You can audit SharePoint Online site collection administrators with PowerShell, but there is an important catch: listing tenant sites and reading each site's administrators are separate permission checks. A SharePoint Administrator can enumerate sites, while Get-SPOUser also requires the caller to be a site collection administrator for the site being queried.
That boundary is why scripts copied from old blog posts often return incomplete results or temporarily add the operator to every site. Decide whether that access change is acceptable before running a tenant-wide audit.
Fact-checked against Microsoft Learn and the PnP PowerShell command documentation on 24 August 2026. PnP PowerShell is a community-supported project, not a Microsoft support-contract replacement.
Choose the audit route first
| Route | Best for | Important limit |
|---|---|---|
| SharePoint Online Management Shell | A Microsoft-documented, interactive administrative audit | Get-SPOUser requires access to each target site |
| PnP PowerShell | Richer reporting and scripting patterns | Community supported; authentication and permissions still need deliberate setup |
| Microsoft Graph | Applications already designed around Graph | Do not assume Graph provides a drop-in tenant-wide SCA report |
Start with a small, read-only sample. Do not grant yourself access to hundreds of sites merely because a downloaded script does so.
Method 1: Microsoft SharePoint Online module
Install or update the module in a controlled PowerShell environment:
Install-Module Microsoft.Online.SharePoint.PowerShell -Scope CurrentUser
Import-Module Microsoft.Online.SharePoint.PowerShell
Connect to your tenant's SharePoint admin URL:
$adminUrl = "https://contoso-admin.sharepoint.com"
Connect-SPOService -Url $adminUrl
Test one site before expanding the scope:
$siteUrl = "https://contoso.sharepoint.com/sites/Finance"
Get-SPOUser -Site $siteUrl -Limit All |
Where-Object { $_.IsSiteAdmin -eq $true } |
Select-Object @{Name="SiteUrl";Expression={$siteUrl}}, LoginName, DisplayName
If this returns access denied, do not hide the error. Confirm the operator's SharePoint role and site-level access. Microsoft documents both as prerequisites for Get-SPOUser.
Once the single-site test is correct, a tenant loop can produce a reviewable CSV:
$output = foreach ($site in Get-SPOSite -Limit All) {
try {
Get-SPOUser -Site $site.Url -Limit All -ErrorAction Stop |
Where-Object { $_.IsSiteAdmin -eq $true } |
Select-Object @{Name="SiteUrl";Expression={$site.Url}}, LoginName, DisplayName
}
catch {
[pscustomobject]@{
SiteUrl = $site.Url
LoginName = $null
DisplayName = "ERROR: $($_.Exception.Message)"
}
}
}
$output | Export-Csv -Path "./sharepoint-site-admins.csv" -NoTypeInformation -Encoding UTF8
The error rows matter. An audit that silently drops inaccessible sites is not a complete audit.
Method 2: PnP PowerShell
PnP PowerShell exposes Get-PnPTenantSite and Get-PnPSiteCollectionAdmin. A typical interactive pattern is:
Connect-PnPOnline -Url "https://contoso-admin.sharepoint.com" -Interactive -ClientId "YOUR-APP-ID"
$sites = Get-PnPTenantSite
foreach ($site in $sites) {
Connect-PnPOnline -Url $site.Url -Interactive -ClientId "YOUR-APP-ID"
Get-PnPSiteCollectionAdmin |
Select-Object @{Name="SiteUrl";Expression={$site.Url}}, LoginName, Title
}
This is an outline, not a universal unattended script. Your Entra app registration, delegated or application permissions, tenant consent and PnP authentication method determine whether it works. For automation, design the app permission model explicitly and test it on a non-production site first.
Operational checks that prevent a bad audit
- Decide whether to include OneDrive sites, archived sites and redirect sites.
- Record failures instead of treating an empty result as “no administrators”.
- Expect throttling and use a bounded retry strategy for large tenants.
- Protect the CSV. It is a map of privileged access.
- Record the audit time, operator, module versions and included scope.
- Review owners and Microsoft 365 group-connected site behaviour separately from SCA membership.
- Remove any temporary site access after validation and prove it was removed.
What the report does not prove
An SCA export does not show every route by which a person can reach content. Group membership, sharing links, Teams membership, sensitivity labels, external sharing policies and application permissions are separate controls.
Treat this report as one input to an access review, not a certificate that the tenant is secure or compliant.
Keep the audit repeatable
Join the SharePoint & Teams Admins Space for practical SharePoint administration patterns and peer review.
