An auditor, a security review, an offboarding, or simply a director asking "who can see this?" — and the honest answer from the site's Permissions page is "some of them". This post is the complete answer and how to produce it.
The four ways in
- Direct permission on the site — a user or group given Read/Edit/Full Control on the site itself. Shown in Site permissions.
- Membership of a SharePoint group — Owners, Members, Visitors, or a custom group. Site permissions shows the group; you must open it to see who is in it.
- Membership of a Microsoft 365 group or Entra security group that is inside one of the above. For a Teams-connected site, Members is the M365 group, and its membership is managed in Teams or Entra, not SharePoint. Site permissions cannot expand it.
- Item-level access — a file, folder or library with broken inheritance and its own permissions, or a sharing link ("People in your organisation with the link"). None of this appears on the site's Permissions page at all.
Two of those four are invisible from the page everyone checks. That is why the audit answer is wrong.
The browser route, and where it stops
Settings gear → Site permissions → Advanced permissions settings gives you the classic view: every principal with a direct role on the site, and the SharePoint groups. Click each group to see members. For an M365 group, you get the group's name and a link out to Entra.
To see item-level exceptions, you go library by library: Library settings → Permissions for this document library → Show items with unique permissions. Then folder by folder. On a real site this is hours, and it still does not list sharing links.
The PowerShell route
PnP PowerShell, connected as a site collection admin:
Connect-PnPOnline -Url https://contoso.sharepoint.com/sites/Finance -Interactive
$rows = New-Object System.Collections.Generic.List[object]
function Add-Rows($scope, $ras) {
foreach ($ra in $ras) {
$m = Get-PnPProperty -ClientObject $ra -Property Member, RoleDefinitionBindings
$roles = ($m.RoleDefinitionBindings | ForEach-Object Name) -join ', '
if ($m.Member.PrincipalType -eq 'SharePointGroup') {
foreach ($u in Get-PnPGroupMember -Group $m.Member.LoginName) {
$rows.Add([pscustomobject]@{ Scope=$scope; Principal=$u.Email; Type=$u.PrincipalType; Access=$roles; How="via SP group $($m.Member.Title)" })
}
} else {
$rows.Add([pscustomobject]@{ Scope=$scope; Principal=$m.Member.LoginName; Type=$m.Member.PrincipalType; Access=$roles; How='Direct' })
}
}
}
$web = Get-PnPWeb -Includes RoleAssignments
Add-Rows 'Site' $web.RoleAssignments
$rows | Format-Table -AutoSize
That gives you the site level: every direct grant and every SharePoint group, expanded to people. It is the first of the four ways in, and the second.
What it does not do: expand Entra / M365 groups to people (that needs Graph), walk every library and item with broken inheritance (one call per item, hours on a real site), or list sharing links (system groups named SharingLinks.<guid>, resolved per file). Those are the third and fourth ways in — the ones the Permissions page also misses — and doing them reliably across a site is why the tool exists.
Microsoft's built-in answer
Data Access Governance reports in the SharePoint admin centre — sites with the most sharing links, sites shared with Everyone except external users, and a per-user "which sites can this person reach" report. They are good, and they require the SharePoint Advanced Management add-on for every user. They are also tenant-level snapshots, not the per-site access chain an auditor asks for.
What to hand the auditor
One table, one row per person, with: Principal · Access level · How (direct / via SP group X / via M365 group Y inside SP group X / item-level on path / sharing link). Flag external users (#ext# in the login) and broad grants (Everyone, Everyone except external users) separately. Date it. That table is what "who has access and how" means.
Producing it for one site by hand is an afternoon; for the site portfolio it is a project. WhoHasAccess365's site-level report is that table, free, run from a SharePoint page under the signed-in admin's own permissions, with groups expanded and broad grants flagged. Pro adds the item-level sweep, sharing links and CSV export.