External Sharingintermediate

How to Review External User and Guest Access in SharePoint Online

Find every external identity with access to your SharePoint sites, the group or link that admits each one, and the tenant settings that decide what they can do, using Graph, SharePoint Online PowerShell and PnP.

PTAccess Witness Product TeamProduct and engineeringPublished 11 min read

External access in SharePoint Online arrives through more doors than most reviews check. Guests in the directory, guests in Microsoft 365 groups, guests inside nested security groups, "Specific people" links to addresses that were never invited as guests, and "Anyone" links with no identity at all. A review that only lists guest users in Entra ID sees one door.

This guide enumerates the doors, shows how to inspect each one, and ends with a review procedure you can repeat.

The ways an external person gets in

  1. B2B guest in Entra ID. A user object with userType of Guest, typically created by an invitation. SharePoint and OneDrive use Entra B2B integration, so most modern external sharing creates a guest.
  2. Guest membership in a Microsoft 365 group. A guest added to a group gets the group's connected site permissions (usually Members, so Edit) and Teams access.
  3. Guest membership in an Entra ID security group, including nested groups, that is itself in a SharePoint group. The site owner may never have seen the guest.
  4. Direct role assignment of a guest on a site, library, folder or item.
  5. "Specific people" sharing links on an item. These admit named addresses and, depending on settings, can work with a one-time passcode without creating a durable guest account.
  6. "Anyone" links. No identity. Anyone holding the URL has the link's permission (View or Edit) until it expires or is removed.
  7. Site collection administrator set to a guest, which is rare but catastrophic.

Each door has its own inventory method.

Inventory 1: Guest users in the directory

Connect-MgGraph -Scopes "User.Read.All","AuditLog.Read.All"
Get-MgUser -Filter "userType eq 'Guest'" -All `
  -Property id,displayName,mail,userPrincipalName,createdDateTime,externalUserState,signInActivity |
  Select-Object displayName, mail, createdDateTime, externalUserState,
    @{n="LastSignIn"; e={ $_.SignInActivity.LastSignInDateTime }}

externalUserState of PendingAcceptance means the invitation was never redeemed. LastSignIn far in the past is a candidate for removal. This list is the population; it does not tell you what any of them can reach.

Inventory 2: Where each guest has access

Two complementary approaches.

From the site side, the SharePoint Online Management Shell lists external users per site:

Connect-SPOService -Url https://contoso-admin.sharepoint.com
Get-SPOSite -Limit All | ForEach-Object {
  $site = $_
  Get-SPOExternalUser -SiteUrl $site.Url -PageSize 50 -ErrorAction SilentlyContinue |
    Select-Object @{n="Site"; e={ $site.Url }}, DisplayName, Email, AcceptedAs, WhenCreated, InvitedBy
}

This catches guests that SharePoint knows about on each site, but it reports the guest, not the path.

From the identity side, transitiveMemberOf for a guest shows every group they are in, directly or through nesting:

GET https://graph.microsoft.com/v1.0/users/{guest id}/transitiveMemberOf?$select=id,displayName,groupTypes,securityEnabled

Intersect that with the Entra ID and Microsoft 365 groups that hold role assignments on your sensitive sites and you have the group-based paths. Groups with Unified in groupTypes are Microsoft 365 groups; securityEnabled without Unified is a security group.

Sharing links are principals on the item. Each is a hidden SharePoint group named SharingLinks.<item guid>.<kind>.<link guid>, where the kind is OrganizationView, OrganizationEdit, AnonymousView, AnonymousEdit, Flexible (specific people) and similar. To find them, enumerate items with unique permissions and look at their role assignments:

Connect-PnPOnline -Url https://contoso.sharepoint.com/sites/Finance -Interactive -ClientId $ClientId
$items = Get-PnPListItem -List "Documents" -PageSize 2000 -Fields "FileRef","HasUniqueRoleAssignments" |
  Where-Object { $_["HasUniqueRoleAssignments"] }
foreach ($item in $items) {
  $ras = Get-PnPProperty -ClientObject $item -Property RoleAssignments
  foreach ($ra in $ras) {
    $m = Get-PnPProperty -ClientObject $ra -Property Member
    if ($m.Title -like "SharingLinks.*") {
      [pscustomobject]@{ Item = $item["FileRef"]; Link = $m.Title; Users = (Get-PnPGroupMember -Group $m.Title | ForEach-Object Email) -join ";" }
    }
  }
}

Microsoft Graph also exposes links per drive item, which is convenient for a single library:

GET https://graph.microsoft.com/v1.0/sites/{site-id}/drive/items/{item-id}/permissions

Permissions with a link property are sharing links; link.scope of anonymous is an Anyone link, organization is company-wide, users is specific people. grantedToIdentitiesV2 lists the specific-people audience. Note that Graph shows links per item, so a library-wide inventory means walking the drive.

Anyone links deserve their own line in every report: they have no identity, so the audit trail for use is limited to the link event and any file access events attributed to anonymous users.

Inventory 4: The settings that decide what is possible

External access is bounded by tenant and site settings. Record them alongside the inventory; a review is meaningless without the policy it is measured against.

Get-SPOTenant | Select-Object SharingCapability, DefaultSharingLinkType, DefaultLinkPermission,
  RequireAnonymousLinksExpireInDays, FileAnonymousLinkType, FolderAnonymousLinkType,
  ExternalUserExpirationRequired, ExternalUserExpireInDays,
  SharingDomainRestrictionMode, SharingAllowedDomainList, SharingBlockedDomainList

Get-SPOSite -Identity https://contoso.sharepoint.com/sites/Finance |
  Select-Object SharingCapability, DefaultSharingLinkType, DefaultLinkPermission, DisableCompanyWideSharingLinks

SharingCapability values from most to least open: ExternalUserAndGuestSharing (Anyone links allowed), ExternalUserSharingOnly (authenticated guests only), ExistingExternalUserSharingOnly, Disabled. A site cannot be more permissive than the tenant. ExternalUserExpirationRequired with ExternalUserExpireInDays makes guest access on sites and OneDrive expire unless renewed, which is one of the few settings that reduces review work over time.

A repeatable review procedure

  1. Freeze the policy. Export tenant and per-site sharing settings. Note the date.
  2. List the population. Guest users with state, creation date and last sign-in.
  3. Map the paths per sensitive site. On each inheritance boundary, expand every role assignment transitively and flag userType eq 'Guest' identities, recording the full route.
  4. List the links. Every SharingLinks.* group and every Graph permission with a link, with kind, audience and expiry.
  5. Decide. For each guest path and link: keep (with owner and justification), expire, or remove. Anyone links on anything sensitive are almost always "remove."
  6. Act and verify. Remove access, then re-run steps 3 and 4 to confirm. Remember propagation delay before declaring a guest cut off.
  7. Record who admitted each path. Pull the audit events (AddedToGroup, Add member to group., SharingLinkCreated, AddedToSecureLink) so the next review starts with attribution.

For step 7 the retention clock applies: see How Long Does Microsoft 365 Keep SharePoint Audit History?.

Access reviews and expiration

Entra ID Governance access reviews can put Microsoft 365 group guest membership in front of group owners on a schedule, and guest expiration in SharePoint handles the long tail of forgotten invitations. Neither covers guests nested in security groups on sites, direct item grants or links, so they reduce the review, they do not replace it.

FAQ

A specific-people link went to an address that is not a guest in Entra ID. How?
With verification-code (one-time passcode) sharing, recipients can authenticate to a link without a durable guest object, depending on tenant settings. The address appears in the link's audience but not in your guest list.
Does removing a guest from Entra ID remove their SharePoint access?
Deleting the guest user revokes sign-in, and their direct and group-based paths stop working. Their entries may still appear in site user lists until cleaned up, and Anyone links they used remain valid for anyone else.
Can I find Anyone links tenant-wide?
There is no single tenant-wide query. The SharePoint admin center sharing reports and per-library enumeration through REST or Graph are the practical routes, and the AnonymousLinkCreated audit event lists creations within retention.
external-sharingguestsentra-b2bsharing-links
All guides
  • SharePoint Permissions11 min read, intermediate

    How to Find Out Why a User Has Access to a SharePoint Site

    Trace direct, inherited and nested group access in SharePoint Online, from the role assignment on the resource down to the identity, using the admin UI, REST and PowerShell.

  • Entra ID10 min read, intermediate

    SharePoint Groups vs Microsoft 365 Groups vs Entra ID Security Groups

    Three kinds of group grant SharePoint access and they behave differently for scope, nesting, ownership, guests and audit. Here is how each one works and how to tell them apart in a role assignment.

  • Historical Access12 min read, advanced

    How to Audit Historical SharePoint Permissions

    SharePoint keeps no permission history. This guide shows what the audit log can and cannot reconstruct, how to build a baseline plus event approach with PowerShell, and how to state confidence honestly.