Tag Archives: Get-MsolGroupMember Nested

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:
2016-01-07_23-46-04

Get-JDMsolGroupMember

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

    param(
        [CmdletBinding(SupportsShouldProcess=$true)]
        [Parameter(Mandatory=$true, ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Position=0)]
        [ValidateScript({Get-MsolGroup -ObjectId $_})]
        $ObjectId,
        [switch]$Recursive
    )
    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.

Enjoy!

/Johan

Advertisements