LDAP does not return all Active Directory group members if there are more than 1500 members in the group. It will return the first 1500, but none thereafter.
LDAP Does Not Return All Active Directory Group Members
Luckily when a group has more than 1500 users, LDAP returns a ‘member range’ property that looks like this: member;range=0-1499
. This property doesn’t exist when groups have 1500 or less members,
We can use this to iterate through each range until there are no more members left.
function Get-ADGroupMembers {
param ([string]$adgroup)
$searcher=[adsisearcher]""
$searcher.Filter="(&(objectClass=group)(cn=$adgroup))"
$searcher.PageSize=200
#find group
$result=$searcher.FindOne()
#if group found
if ($result) {
#if range exists because group is large
$moreThan1500Members = [bool]($result.Properties.PropertyNames | where { $_ -like "member;range=*" })
#if group has more than 1500 members
if($moreThan1500Members) {
#we need to recurse through ranges
$iteratedAllRanges=$false
$rangeBottom =0
$rangeTop= 0
while (!($iteratedAllRanges)) {
$rangeTop=$rangeBottom + 1499
#set new range
$memberRange="member;range=$rangeBottom-$rangeTop"
$searcher.PropertiesToLoad.Clear()
[void]$searcher.PropertiesToLoad.Add("$memberRange")
try {
#if range invalid, throw exception
$result = $searcher.FindOne()
$rangedProperty = $result.Properties.PropertyNames -like "member;range=*"
$members +=$result.Properties.item($rangedProperty)
if ($members.count -eq 0) { $iteratedAllRanges=$true }
} catch {
$iteratedAllRanges=$true
}
#increment bottom of range for next iteration
$rangeBottom+=1500
}
} else {
#group member count is less than 1500
$members += $result.properties.item("member")
}
$searcher.Dispose()
return $members
}
return $false
}
#return all members
$members = Get-ADGroupMembers "Your AD group name"
#iterate through ALL members
foreach ($mem in $members) {
write-host $mem
}
#get member count
write-host $members.count