Recursively enumerate Azure AD Group members with PowerShell

Many of the scripts used to assign licenses for Azure AD / Office 365 users are utilizing groups to assign the licenses. On the topic I have received quite a lot requests on nested group support, which is not possible with Get-MsolGroupMember as of now.

To solve this problem, I have built a simple function canned Get-JDMSOLGroupMember. It checks if a group consists of other groups, and loops through them until all group members of all groups have been enumerated. In the end it will sort the members so that no duplicate member records are returned. It will only return users, not groups.

See the screenshot below on how it works:


function Get-JDMsolGroupMember { 
    The function enumerates Azure AD Group members with the support for nested groups.
    Get-JDMsolGroupMember 6d34ab03-301c-4f3a-8436-98f873ec121a
    Get-JDMsolGroupMember -ObjectId  6d34ab03-301c-4f3a-8436-98f873ec121a -Recursive
    Get-MsolGroup -SearchString "Office 365 E5" | Get-JDMsolGroupMember -Recursive
    Author   : Johan Dahlbom, johan[at]
    Blog     : 
    The script are provided “AS IS” with no guarantees, no warranties, and it confer no rights.

        [Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
        [ValidateScript({Get-MsolGroup -ObjectId $_})]
    begin {
        $MSOLAccountSku = Get-MsolAccountSku -ErrorAction Ignore -WarningAction Ignore
        if (-not($MSOLAccountSku)) {
            throw "Not connected to Azure AD, run Connect-MsolService"
    process {
        Write-Verbose -Message "Enumerating group members in group $ObjectId"
        $UserMembers = Get-MsolGroupMember -GroupObjectId $ObjectId -MemberObjectTypes User -All
        if ($PSBoundParameters['Recursive']) {
            $GroupsMembers = Get-MsolGroupMember -GroupObjectId $ObjectId -MemberObjectTypes Group -All
            if ($GroupsMembers) {
                Write-Verbose -Message "$ObjectId have $($GroupsMembers.count) group(s) as members, enumerating..."
                $GroupsMembers | ForEach-Object -Process {
                    Write-Verbose "Enumerating nested group $($_.Displayname) ($($_.ObjectId))"
                    $UserMembers += Get-JDMsolGroupMember -Recursive -ObjectId $_.ObjectId 
        Write-Output ($UserMembers | Sort-Object -Property EmailAddress -Unique) 
    end {

As usual, let me know if you find issues or have any other suggestions.




8 thoughts on “Recursively enumerate Azure AD Group members with PowerShell

  1. James

    I got this on some groups:
    Method invocation failed because [Microsoft.Online.Administration.GroupMember] does not contain a method named ‘op_Addition’.

  2. Havard Overas

    Use should make $UserMembers an array in line 32:
    $UserMembers = @(Get-MsolGroupMember -GroupObjectId $ObjectId -MemberObjectTypes User -All)

  3. Pingback: Azure ARM Group Membership Recursively - Part 1 - SPR

  4. Ben Van Aerde

    As Havard mentioned, $UserMembers needs to be an array.
    Apart from this, the function works perfectly.

  5. Steve Murphy

    For Members of AD Security Groups and Unified Groups, I need to know if the Member is a “member” or and “owner”. If it’s possible, I’m willing to pay for the solution.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s