Reporting on SharePoint-Only Guest Users before Enabling the Azure AD B2B Integration
Overview
External collaboration and the sharing of files and folders is one of the core feature of SharePoint Online, OneDrive for Business and Microsoft Teams. Nevertheless, did you know that many external identities in your tenant may only be visible in SharePoint – but not in Azure AD? And did you know that these SharePoint-only guest users are bypassing your Conditional Access policies and MFA?
In this blog post, I will show you:
- the differences between the SharePoint B2B and the Azure AD B2B system for managing guest users,
- how to use my PowerShell script for reporting on external users that currently only exist in SharePoint/OneDrive, and
- how to merge the B2B systems to smooth the way for a more secure external access and an optimized guest user lifecycle management.
Difference between SharePoint-Only and Azure AD B2B Guest Users
SharePoint-Only Guest Users
Historically, Microsoft started their external collaboration features in SharePoint Online and OneDrive for Business by focusing on the sharing of files and folders. For this reason, Microsoft had to store external users along with internal users in the so called “User Information List” in the respective site-collection. This list is hidden from the UI and only accessible via one of the following URLs:
https://tenant.sharepoint.com/sites/SiteName/_layouts/people.aspx?MembershipGroupId=0
https://tenant.sharepoint.com/sites/SiteName/_catalogs/users/simple.aspx
When you share single SharePoint/OneDrive files or folders with an external person and as soon as the external user accesses the data for the first time, a new entry is created in this User Information List of the particular site to hold basic metadata for the external identity. An external user can only access a certain SharePoint or OneDrive site after being added to the User Information List. Otherwise, you may have already seen error messages like “We’re sorry, but lorem.ipsum@external-domain.com can’t be found in the tenant.sharepoint.com directory”.
You can clearly identify those kind of external users – I call them “SharePoint-only guest users” – through their user principal name (UPN) shown in the hidden SharePoint list. The UPN contains the urn:spo:guest
identifier (may encoded as urn%3aspo%3aguest
) as shown in the following example:
From an administrative perspective, the governance of those SharePoint-only guest users is difficult since you do not have a transparent, global overview of all external users across the SharePoint and OneDrive sites in your tenant. Each site has its own hidden User Information List and its own collection of guest users. Below in this blog post, I will provide a PowerShell script to create a tenant-wide report on SharePoint-only guest users.
More importantly, when these kind of external users access files and folders in SharePoint and OneDrive, they are not in scope of your Conditional Access policies including MFA requirements, and you do not even see their sign-ins in the Azure AD logs.
Azure AD B2B Guest Users
In contrast to that, when you invite an external person into Microsoft Teams workspaces or into Microsoft 365 Groups, a guest user object is created in your Azure Active Directory. This experience is part of the Microsoft’s modern B2B Collaboration feature.
If an internal user shares a single SharePoint/OneDrive file or folder with an external person, who is already listed as a guest user in your Azure AD, you will recognize a different UPN format in SharePoint’s User Information List as stated above. Azure AD B2B guests will be displayed with an #ext#
identifier:
In comparison to SharePoint-only guests, the huge benefits of Azure AD B2B guests are better transparency and governance options. As an IT admin, you can query the list of all guests directly in the Azure portal. Furthermore, each sign-in is recorded and goes through your prescribed Conditional Access rules. Thus, you can actually require multi-factor authentication for external users.
For this reason, I will show you below in this post how to migrate the legacy guest identities to the modern Azure AD B2B approach.
Summary of Differences
SharePoint-Only Guests | Azure AD B2B Guests | |
UPN format in SharePoint’s User Information List | urn:spo:guest | #ext# |
Subject to Conditional Access (including MFA) | ✖ | ✔ |
Logging of sign-ins | ✖ | ✔ |
Global overview of guests | ✖ | ✔ |
Creating a Tenant-Wide Report on SharePoint-Only Guest Users
I developed the following PowerShell script allowing you to get a full report on the different kind of guest users across all SharePoint and/or OneDrive sites in your Microsoft 365 tenant:
Export-SharePointOnlyGuestUsers.ps1
The core ingredients of the scripts are outlined in the following abbreviated code snippet:
# Get both SharePoint and OneDrive sites
$PnPTenantConnection = Connect-ToPnPSharePoint -TenantAdministration
$sites = Get-PnPTenantSite -IncludeOneDriveSites -Connection $PnPTenantConnection
foreach ($site in $sites) {
# Process current site
$siteUrl = $site.Url
# Open connection to current SharePoint site
$PnPSiteConnection = Connect-ToPnPSharePoint -SiteUrl $siteUrl
# Get external users based on the "urn:spo:guest" or "#EXT#" identifier
$externalUsers = Get-PnPUser -Connection $PnPSiteConnection | Where-Object {
$_.LoginName -like "*urn%3aspo%3aguest*" -or $_.LoginName -like "*urn:spo:guest*" -or $_.LoginName -like "*#EXT#*"
}
foreach ($user in $externalUsers) {
# Differentiate between SPO-only guest vs. Azure AD B2B guest
$externalUserType = "SPO"
if ($user.LoginName -like "*#EXT#*") {
$externalUserType = "B2B"
}
# Specify the properties of the external user to be exported
$props = [ordered]@{
SiteUrl = $siteUrl
SiteTitle = $site.Title
ExternalUserType = $externalUserType
Email = $user.Email
EmailWithFallback = $user.EmailWithFallback
LoginName = $user.LoginName
Title = $user.Title
Id = $user.Id
UserId = $user.UserId
UserPrincipalName = $user.UserPrincipalName
AadObjectId = $user.AadObjectId
IsShareByEmailGuestUser = $user.IsShareByEmailGuestUser
IsEmailAuthenticationGuestUser = $user.IsEmailAuthenticationGuestUser
IsHiddenInUI = $user.IsHiddenInUI
IsSiteAdmin = $user.IsSiteAdmin
Groups = ($user.Groups.Id -join ", ")
Expiration = $user.Expiration
}
# Append to CSV
$row = New-Object -TypeName PSObject -Property $props
$row | Export-Csv -LiteralPath ".\GuestUsers.csv" -Delimiter ";" -Encoding UTF8 -NoTypeInformation -Append
}
}
The script leverages the PnP.PowerShell module and encapsulates certificate-based app-only authentication to SharePoint Online in a helper function Connect-ToPnPSharePoint
. Depending on a script parameter, you can either iterate all SharePoint sites, all OneDrive sites or both. Alternatively, you can provide a list of specific site URLs to be iterated. For each site-collection, the properties of the external users are exported by using the Get-PnPUser
cmdlet and by distinguishing between the urn:spo:guest
vs. #ext#
user types as stated above in this blog post.
The CSV output file serves as a good foundation to create an Excel report. For example, you can create basic pivot tables identifying the sites with the most guest users or the guest users with the most extensive permissions across your tenant:
Enabling the Azure AD B2B Integration for SharePoint and OneDrive
To move from the SharePoint-only guest user experience to the modern Azure AD B2B approach, you need to activate the EnableAzureADB2BIntegration
flag via SharePoint Online Management Shell:
Set-SPOTenant -EnableAzureADB2BIntegration $true
Beforehand, please consult Microsoft’s official documentation on the B2B integration for SharePoint and OneDrive. Furthermore, I like to recommend the blog posts by Pim Jacobs and AdminDroid, which provide more details on the impact of the change.
According to my experience in performing the change in several customer tenants, some external users may loose access to shared files and folders. In general, I can confirm that Microsoft provides a good migration experience according to what you can read in their docs, i.e. as soon as an external person accesses the previously shared OneDrive/SharePoint data again, the SPO-only guest identity is automatically transformed into an AAD B2B guest user object. Nevertheless, we experienced that external persons need to open the original sharing link to the particular file or folder, which has been received via e-mail / Teams chat / etc. probably some weeks or months ago. But the external people may rely on their browser history or browser favorites instead when opening a shared item. Unfortunately, the suggested URLs from the browser may not contain the proper token that allows Microsoft to migrate the user to the Azure AD B2B guest experience. In this case, an internal user needs to re-create sharing links to the respective data again.
Consequently, before performing the change, you should execute my PowerShell script to get a better estimate on the impact in your environment, and you should also inform your employees upfront because external partners may come back to them and may request the re-sharing of SharePoint/OneDrive data.
Sources and Further Readings
- Microsoft: Azure AD B2B integration for SharePoint & OneDrive – SharePoint in Microsoft 365 | Microsoft Learn
- Microsoft: External Identities in Azure Active Directory – Microsoft Entra | Microsoft Learn
- GitHub repository: MicrosoftCloudSecurity/Export-SharePointOnlyGuestUsers.ps1 at main · CloudProtectNinja/MicrosoftCloudSecurity (github.com)
- Pim Jacobs: Securing SharePoint Online guest users with the Azure AD B2B experience – Identity Man (identity-man.eu)
- AdminDroid: SharePoint and OneDrive Integration with Azure AD B2B (admindroid.com)
This was a valiant attempt, but so far I can’t get it ever run successfully. It requires a certificate thumbprint for the App that has the SP site full access. I found that app for us, but the PS code I have been able to find that returns the cert thumbprint, does not match the thumbprint that is partly shown in the App Certificates page. I’ve found 3 separate ‘get the cert thumbprint’ code, they all use CustomKeyIdentifier and none of them convert the thumbprint shown in the GUI.
Hi Brian,
as far as I understand you are trying to reuse an already existing app registration in Entra ID (Azure AD), but since you are not the creator of this app you do not have access to the certificate file (.pfx) and thus the certificate is not available in the certificate store on your Windows machine. Consequently, you cannot authenticate against SharePoint Online in the app-only context und thus you cannot use my script Export-SharePointOnlyGuestUsers.ps1.
I recommend to create a brand new app registration in Entra ID, with ”Sites.FullControl“ application permissions and with a brand new certificate, which is also saved to your local certificate store.
For this purpose, you could use the Register-PnPAzureADApp cmdlet, which will roughly look like this:
Register-PnPAzureADApp -ApplicationName "SharePointGuestExport" -Tenant "yourtenant.onmicrosoft.com" -Store CurrentUser -SharePointApplicationPermissions "Sites.FullControl.All" -Username "yourname@domain.com" -Password (Read-Host -AsSecureString -Prompt "Enter Password")
Please read the documentation of the PnP cmdlet and try to adjust it to your needs.
Afterwards, you should be able to run my script according to my README page on GitHub.
Please feel free to get back to me if more help is needed.