Created
November 24, 2025 17:59
-
-
Save griffeth-barker/d423a8d4494df4013f52cc3e26347e3b to your computer and use it in GitHub Desktop.
Identify Entra groups where all specified users are a member
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Get-MgCommonGroups { | |
| <# | |
| .SYNOPSIS | |
| Identifies groups of which all the provided users are members (intersections). | |
| .DESCRIPTION | |
| This function consumes an array of Entra ID user identities via ObjectId or UserPrincipalName and checks for | |
| intersections in group membership (groups where all of the provided users are members), and returns a list of | |
| those groups. | |
| .PARAMETER UserIdentities | |
| The ObjectId or UserPrincipalName of the users to check. | |
| .INPUTS | |
| System.String[] | |
| .OUTPUTS | |
| System.Management.Automation.PSObject | |
| .EXAMPLE | |
| Get-MgCommonGroups -UserIdentities 'alex@contoso.com','pat@contoso.com' | |
| .EXAMPLE | |
| $users = @( | |
| 'alex@contoso.com', | |
| 'pat@contoso.com' | |
| ) | |
| Get-MgCommonGroups -UserIdentities $users | |
| #> | |
| [CmdletBinding()] | |
| param( | |
| [Parameter(Mandatory)] | |
| [string[]]$UserIdentities | |
| ) | |
| #region Dependency handling ----------------------------------------------------------------------------------- | |
| if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) { | |
| throw "Microsoft.Graph module not found. Install: Install-Module Microsoft.Graph" | |
| } | |
| if (-not (Get-MgContext)) { | |
| Connect-MgGraph -Scopes 'User.Read.All','Group.Read.All','GroupMember.Read.All' | |
| Select-MgProfile -Name beta # beta profile needed for Get-MgGroupMemberCount | |
| } | |
| #endregion ---------------------------------------------------------------------------------------------------- | |
| function Get-UserGroupIds { | |
| param([string]$Identity) | |
| $user = Get-MgUser -UserId $Identity -ErrorAction Stop | |
| $groups = Get-MgUserMemberOf -UserId $user.Id -All | Where-Object { | |
| $_.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.group' | |
| } | |
| $groups.Id | |
| } | |
| #region Identify group intersections -------------------------------------------------------------------------- | |
| $allSets = @() | |
| foreach ($id in $UserIdentities) { | |
| try { | |
| $ids = Get-UserGroupIds -Identity $id | |
| $allSets += ,$ids | |
| } catch { | |
| Write-Warning "Skipping $($id): $($_.Exception.Message)" | |
| } | |
| } | |
| if (-not $allSets) { return @() } | |
| $common = $null | |
| foreach ($set in $allSets) { | |
| if ($null -eq $common) { | |
| $common = [System.Collections.Generic.HashSet[string]]::new() | |
| foreach ($gid in $set) { $common.Add($gid) | Out-Null } | |
| } else { | |
| $temp = [System.Collections.Generic.HashSet[string]]::new() | |
| foreach ($gid in $set) { $temp.Add($gid) | Out-Null } | |
| $common.IntersectWith($temp) | |
| } | |
| if ($common.Count -eq 0) { break } | |
| } | |
| if ($common.Count -eq 0) { return @() } | |
| #endregion ---------------------------------------------------------------------------------------------------- | |
| #region Output ------------------------------------------------------------------------------------------------ | |
| $results = foreach ($gid in $common) { | |
| $g = Get-MgGroup -GroupId $gid -Property 'id,displayName,description' | |
| [PSCustomObject]@{ | |
| GroupId = $g.Id | |
| DisplayName = $g.DisplayName | |
| Description = $g.Description | |
| MemberCount = Get-MgGroupMemberCount -GroupId $gid -ConsistencyLevel eventual | |
| } | |
| } | |
| $results | Sort-Object DisplayName | |
| #endregion ---------------------------------------------------------------------------------------------------- | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment