Many of us have had to baby-proof our living quarters at some point. This can be a tedious process, since babies are often able to surprise us by finding ways to get into things we don’t expect. However, just making a flat “no babies allowed” rule is often not an option, so we have to iteratively harden the environment to reduce the chances of damage.
The preceding paragraph is not really about babies, it’s about Microsoft 365 guest accounts in your tenant.
Before You Get Started…
Tony Redmond wrote a column showing how to use Microsoft Graph to perform a quick inventory of guests with permission to access your tenant, with a focus on finding accounts that weren’t being used. It’s worth reading so that you understand the basic tools available for checking which guest accounts exist and whether (and how) they’re being used. In this column, though, I want to focus more on controlling how the guests get into your tenant in the first place; in future columns, we’ll explore more of the management tasks you might want to perform, such as conducting access reviews.
Performing an Initial Guest Audit
Many tenants have inactive guest accounts, and sometimes in large numbers. Microsoft has made it easy to invite guests but harder for guests to voluntarily leave; overall, the lifecycle management process for guest accounts makes it easy to end up with guest ghosts. Finding out whether you’re a guest ghost host is the purpose of this column.
There’s no single consolidated source of data that you can use to see what every guest user has access to and has done in your tenant. The mechanism described in Tony’s article is a good starting point because it will show you what accounts currently exist. While it’s tempting to just do something like the below PowerShell example, which will give you a CSV of all the guest accounts, there are several nuances you need to be aware of (such as the need to use two different techniques to find accounts that have never signed in versus those that have).
# Get all guest users with key information Get-MgUser -Filter "userType eq 'Guest'" -Property ` "displayName,mail,createdDateTime,userPrincipalName,id" | ` Select-Object DisplayName, Mail, CreatedDateTime, UserPrincipalName, Id |` Export-CSV "GuestUsers.csv" -NoTypeInformation
You can also use the Entra admin center to see this data, filtering it as you like.
Your next step should probably be to identify groups that contain guest users, as Microsoft’s long-recommended practice is to assign permissions to groups. The script snippet below will produce a CSV showing which groups contain guest users. You can use this to form the basis of the auditing spreadsheet I’ll discuss in a moment.
# Connect to Graph with necessary scopes if not already connected Connect-MgGraph -Scopes "Group.Read.All", "User.Read.All" $Groups = Get-MgGroup -All $Results = @() ForEach ($Group in $Groups) { $Members = Get-MgGroupMember -GroupId $Group.Id $GuestMembers = @() ForEach ($Member in $Members) { $User = Get-MgUser -UserId $Member.Id -Property "userPrincipalName,userType" If ($User.UserType -eq "Guest") { $GuestMembers += $User } } If ($GuestMembers.Count -gt 0) { $Results += [PSCustomObject]@{ GroupName = $Group.DisplayName GuestCount = $GuestMembers.Count GuestEmails = ($GuestMembers.UserPrincipalName -join "; ") } } }
Guest users often use SharePoint, too. You can use the Active sites view in the SharePoint Admin Center to give you a quick view of which sites are enabled for sharing, but to get a complete view, you need to check which users have access to what, which is held in each site’s sharing settings. It’s easy to build a script that uses Get-MgSite to get the sites and then iteratively call Get-MgSitePermission and Get-MgUser to build a guest access list. (If there’s sufficient interest, that might be a good future column topic!) You can also use the usage reports in the M365 admin center to give you data about guest usage in Teams.
Pulling Your Audit Data Together
Before moving on to hardening your configuration, take the audit data you’ve assembled and use it to build a list or spreadsheet tracking at least the following items:
- The total number of guest accounts your tenant has
- Who owns the guest accounts (and, if you can, related information about which department, site, etc. in your organization “owns” the guest invitations)
- Age distribution (how many are >90 days, >180 days, >365 days old)
- A breakdown of active-looking versus inactive-looking accounts. I phrase it that way because you may want to err on the side of caution by not removing accounts unless you’re sure they’re unused.
- Data about which sites, Teams, etc. have the most guest users with access, and/or the most activity
The idea behind gathering this data is to give you a (hopefully) complete picture of which guests are already in your tenant. In future columns, I’ll talk about how to manage your invitation policies to control how guests are added in the future, as well as strategies for evicting ghost guests once you’re confident they’re no longer needed.