Nested Groups: Why Your SharePoint Permissions Report Is Wrong, and How to Expand Entra ID and AD Groups
Last updated: 2026-10-21
A SharePoint permissions report that lists "Marketing" as one row may be hiding hundreds of people. SharePoint stores the grant against the group, and Entra ID or Active Directory groups can contain other groups. To see the real list of people, the report has to read the directory and follow nested groups down to each user. SharePoint Essentials Toolkit does this, free on up to 20 sites.
A SharePoint permissions report that lists "Marketing" as one row may be hiding hundreds of people. SharePoint stores the grant against the group, and Entra ID or Active Directory groups can contain other groups. To see the real list of people, the report has to read the directory and follow nested groups down to each user. SharePoint Essentials Toolkit does this, free on up to 20 sites.
Why do nested groups matter?
An auditor asks who can open the Finance library. Your report says "Finance Readers" and "Everyone except external users". Both answers are technically correct and practically useless. The auditor wants names.
The risk is real too. A security group added to a site years ago may now contain contractors, a whole department, or another group someone added for convenience. Nobody looks inside, so nobody notices. Before a Microsoft 365 Copilot rollout this matters more, because every person in that chain can ask Copilot about the content.
What are the four kinds of group in SharePoint?
| Group | Where it lives | Can it nest? |
|---|---|---|
| SharePoint group (Owners, Members, Visitors, custom) | One site collection | Cannot contain another SharePoint group, but can contain the three groups below |
| Microsoft 365 group | Entra ID; connected to a team site or Team | Members are users (owners and members) |
| Entra ID security group (or AD group on-premises) | Directory | Yes, can contain other security groups, many levels deep |
| Everyone / Everyone except external users / All authenticated users | Built-in claims | Means "everyone" of that type; not a list you expand |
Microsoft explains how sharing and group access fit together in Sharing and permissions in the SharePoint modern experience.
A worked example: one row, 400 people
Here is a typical chain (illustrative, but we see this shape in real tenants):
- The Marketing site's Members SharePoint group has Edit.
- Inside Members is the Entra ID security group SG-Marketing.
- SG-Marketing contains 60 people and two more groups: SG-Marketing-Agency (outside contractors) and SG-Sales-All.
- SG-Sales-All contains 340 people.
A report that stops at the SharePoint group shows "Members: Edit". A report that stops at the first directory group shows "SG-Marketing". Only a fully expanded report shows that 400 people, including agency contractors and the whole sales team, can edit marketing files.
Option 1: SharePoint and the Microsoft 365 admin centers
You can follow a chain by hand. It takes three places:
- The site. Select Settings > Site permissions > Advanced permissions settings. Note each SharePoint group and any directory group granted access directly. Select a SharePoint group to see its members; directory groups inside it appear as single entries.
- Microsoft Entra admin center. In the Entra admin center, go to Groups > All groups, open each directory group from step 1 and select Members. Nested groups appear as entries you open in turn, one level at a time.
- Microsoft 365 admin center. For a group-connected team site, open Teams & groups > Active teams & groups, select the group and view Membership for its owners and members.
To test one person instead, use Check Permissions on the site's Advanced permissions page. It reports whether they have access and through which group.
All of this is accurate and included in your license. It works forward from a group or backward from a person, one level and one site at a time, and nothing joins the pieces into a single list of names.
Option 2: PowerShell with PnP and Microsoft Graph
Microsoft Graph's Get-MgGroupTransitiveMember follows nesting for you. The work is connecting it to SharePoint. SharePoint stores directory groups as claim login names that contain the Entra object ID:
- Security group:
c:0t.c|tenant|<object-id> - Microsoft 365 group members:
c:0o.c|federateddirectoryclaimprovider|<object-id> - Microsoft 365 group owners: the same, ending in
_o
The script below reads one site's direct grants and SharePoint group members, finds the directory groups among them, and expands each to its people. Install PnP PowerShell 2.x or later and Microsoft Graph PowerShell, and register your own Entra ID app for PnP.
# Expand directory groups on one site to the people inside them
$ClientId = "<your-app-id>"
$SiteUrl = "https://contoso.sharepoint.com/sites/Marketing"
Connect-PnPOnline -Url $SiteUrl -Interactive -ClientId $ClientId
Connect-MgGraph -Scopes "GroupMember.Read.All", "User.Read.All"
function Get-EntraGroupId($login) {
if ($login -match '^c:0t\.c\|tenant\|([0-9a-f-]{36})