SYNOPSIS
Builds an inventory report of every SharePoint Online site of the tenant using PnP.PowerShell app-only.SYNTAX
DESCRIPTION
Get-SPOSiteReport collects the configuration of the SharePoint Online sites: storage quota and usage, site collection administrators, site Owners/Members/Visitors, external sharing settings, sensitivity label, default sharing links, conditional access policy and hub site membership. The function connects with PnP.PowerShell in app-only mode (Entra app registration plus a certificate). This is the only reliable way to read site-level data (site collection administrators, site groups, regional settings) across every site of the tenant: the SharePoint Administrator role alone grants access to the admin center, not to the content of each site, so a delegated connection returns Access Denied on Get-PnPSiteCollectionAdmin. An app registration holding the SharePoint Sites.FullControl.All application permission bypasses the site collection admin requirement. That permission covers the personal OneDrive sites as well: they are ordinary site collections of the -my.sharepoint.com host, so they are enumerated and read exactly like any other site (use ExcludeOneDrive or OnlyOneDrive to filter them). The one documented exception is the list of site collection administrators of a OneDrive site, which stays invisible even under this permission: see SECONDARY ADMINISTRATORS ON ONEDRIVE SITES ARE NOT CAPTURED under the IncludeSiteAdmins parameter. Client secrets are not supported by SharePoint for app-only: a certificate is mandatory. Provide it through CertificateThumbprint (Windows certificate store), CertificatePath (.pfx file) or CertificateBase64Encoded (base64 string, handy for Azure Automation or a pipeline variable). The site-level collection runs in parallel (ForEach-Object -Parallel) with one PnP connection per site. Tune the concurrency with ThrottleLimit. PowerShell 7 is required. UNIFORM MEMBERS/OWNERS MODEL On a site connected to a Microsoft 365 group, the SharePoint site collection administrators and the Owners/Members/Visitors groups do not list individual users: they list a single claim placeholder that represents the whole group, of the form ‘federateddirectoryclaimprovider|<groupId>_o’ (group Owners) or ‘federateddirectoryclaimprovider|<groupId>’ (group Members). Get-SPOSiteReport resolves these claims in a second pass, so the *Resolved columns list actual users regardless of the site type (classic site, group-connected site, with or without a Microsoft Teams team). Two well-known non-user claims are also labelled for readability: the ‘Everyone’ claim and the ‘Everyone except external users’ claim. Any claim that cannot be resolved (deleted group, insufficient Graph permission) is reported as ‘<unresolved:guid>’ and counted in the ClaimResolutionErrorCount summary at the end of the run. PROVENANCE OF EACH RESOLVED IDENTITY Every identity in a *Resolved column is annotated so you can tell how it got its rights:- No annotation: the user is directly assigned to that SharePoint group/role (individual claim).
- “<user> (via M365 group ‘<name>’ Owners)” or ”… Members)”: the user only has rights because they belong to that Microsoft 365 group, which itself was added to the SharePoint group/role as a whole. The same user can legitimately appear twice for the same site - once without annotation (direct) and once with it (also a member of a group that was added) - that is not a duplicate, it reflects two distinct sources of access. The group’s display name is resolved once per distinct group for the whole run and falls back to its GUID if that lookup fails (deleted group, insufficient Graph permission).
- IncludeSiteAdmins adds the full list of site collection administrators of each site (raw and resolved).
- IncludeSiteMembers adds the site Owners and Members, resolved through the model described above.
- IncludeSiteVisitors adds the site Visitors on top of IncludeSiteMembers. Kept separate because the Visitors group is often large (for example ‘Everyone except external users’) and less relevant to a rights audit than Owners/Members.
- IncludeSharingLinks adds a per-site count of the existing sharing links, broken down by link type.
- IncludeSharingLinksDetails drills into those links file by file, through Get-SPOSharingLinkReport.
- RegionalSettingsDetails adds the time zone, hour format and locale of each site.
- M365GroupsDetails adds the Microsoft 365 group and Microsoft Teams layer of the group-connected sites.