Fast Get-ADGroupMember

The Problem

Microsoft provides a native function to pull members out of a group in AD, but it's pretty slow. When you have really large groups, it can be very slow. I knew of a faster way but I recently had a request which I tried my 1 liner and it broke because the group in question contained nested groups. While I'm not normally a fan of recursion, I knew it was the answer for this problem. So I created a little recursive function to overcome this issue with flying success. I hope it will be helpful for you as well!

The Function


function Get-CustomADGroupMember {
    param (
        [Parameter(Mandatory = $true, Position = 0)]
        [String]
        $Identity,
        [Parameter(Mandatory = $false)]
        [switch]
        $Recursive,
        [Parameter(DontShow)]
        $CurrentUsers
    )
    $Results = Get-ADGroup -Identity $Identity -Properties Members | Select-Object Members -ExpandProperty Members

    $Users = @()
    foreach ($Result in $Results) {
        try {
            $Users += Get-ADUser -Identity $Result -Properties *
        } catch {
            if ($Recursive) {
                Get-CustomADGroupMember $Result -Recursive -CurrentUsers $Users
            }
        }
    }

    return $Users
}

I was using the default `Get-ADGroupMember -Recursive` command but it timed out in my environment. Using the above method, I was able to pull 417 users out of the group in 22.4132531 seconds when combined with the Measure-Command function which including piping the results to the Export-Csv command. To make some comparasions, I used a different group that had no tested groups with only 11 users in the group. The standard Get-ADGroupMember command took 15.5130935 seconds to complete. Using my custom function, it took only 0.6410776.

Examples

No Recursion

This will pull the users of the provided group, ignoring any nested groups.

Get-CustomADGroupMember "MyAdGroup" | Select-Object SamAccountName, DisplayName, EmailAddress | Export-Csv -Path "MyAdGroupMembers.csv" -NoTypeInformation

With Recursion

This will pull the users of the provided group, including all nested groups.

Get-CustomADGroupMember "MyAdGroup" -Recursive | Select-Object SamAccountName, DisplayName, EmailAddress | Export-Csv -Path "MyAdGroupMembers.csv" -NoTypeInformation

Recursion with Unique Results

This can contain duplicates when a user exists in either multiple child groups or within the parent and a child group. Handling possible duplicates is very simple; we'll just need to add the Unique switch parameter in the Select-Object.

Get-CustomADGroupMember "MyAdGroup" -Recursive | Select-Object -Unique SamAccountName, DisplayName, EmailAddress | Export-Csv -Path "MyAdGroupMembers.csv" -NoTypeInformation