Fast Get-ADGroupMember
April 04, 2025
~ 2 min read
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