Getting Accurate Membership counts for AD Groups?

I have tried the following:
(Get-ADGroupMember <group_dn> -server <domain or specific DC>).Count
Get-ADGroupMember <group_dn> -server <domain or specific DC> | Measure-Object
(Get-ADGroup <group_dn> -server <domain or specific DC> -Properties members).members.count
dsget group <group_dn> [-s <domain> or -d <domain>] -members -expand

I get different counts for each one. I took one group, Active Directory Users and Computers show 2 members.
dsget returns 3
Get-ADGroupMember returns 1
Get-ADGroup return 2

I have learned through trying to investigate this that Get-ADGroupMember only returns ‘user’ or ‘computer’ objects and this particular group, one of the two users is indeed a ‘contact’ object.

I have also learned that using recursive methods because groups may have nested groups within that it may cause issues because a user could be a member of the group queried, but also a member of the nested group, which means that is counted at least twice.

I know that for nested groups, I will have to just feed the nested group through another Get-ADGroup command.

I know that Get-ADGroupMember has the 5000 limit and I know that I have groups with more than 5000 members.

Any pointers for helping to get the most accurate group member count would greatly appreciated.

TIA

It looks like Get-AdGroupMember supports recursion? Will that help?

Get-ADGroupMember [-Identity] <ADGroup> [-AuthType {Negotiate | Basic}] [-Credential <pscredential>] [-Partition <string>] [-Recursive] [-Server <string>]  [<CommonParameters>]

It does, but if the group has more than 5000 members, the command fails.

By default, the Get-ADGroupMember cmdlet has a limit of 5,000 members, If the group has over 5,000 members you will get the error below.

“Get-ADGroupMember: The size limit for this request was exceeded”.

The Get-ADGroupMember limit is restricted by the Active Directory Web Services which has a default limit of 5,000 objects. You can modify a config file to change the 5,000 limits but it does require restarting the Active Directory Web Services. Getting the config file changed is not an option.

AI says at the point, use ADSI. This is what it came up with. Be interested to see how it works for you. Ran fine on my DC test VM, but then again, not anywhere near 5k+ objects.

Import-Module ActiveDirectory

$outputPath = "C:\Temp\ADGroupMembers_LargeRecursive.csv"
$results = [System.Collections.Generic.List[PSCustomObject]]::new()

# Get all group objects
$allGroups = Get-ADGroup -Filter *

foreach ($group in $allGroups) {
    # LDAP filter using the "In Chain" OID for deep recursion
    # (memberOf:1.2.840.113556.1.4.1941:=<DistinguishedName>)
    $filter = "(&(objectCategory=person)(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=$($group.DistinguishedName)))"
    
    try {
        # Find all users within the group's hierarchy
        $members = Get-ADObject -LDAPFilter $filter -Properties SamAccountName
        
        foreach ($member in $members) {
            $results.Add([PSCustomObject]@{
                GroupName         = $group.Name
                MemberName        = $member.Name
                MemberSamAccount  = $member.SamAccountName
                DistinguishedName = $member.DistinguishedName
            })
        }
    }
    catch {
        Write-Warning "Failed to query group: $($group.Name). Error: $($_.Exception.Message)"
    }
}

# Export to CSV
$results | Export-Csv -Path $outputPath -NoTypeInformation
Write-Host "Export completed to $outputPath"


I am also just looking for member count, not exporting a list of all the members. Maybe later

You can certainly edit the code and remove what you dont need.

$results.Count