How can I get a list of users within an LDAP group, even if that group happens to be the primary group for some users?
For example, suppose "Domain Users" is "Domain Leute" in German. I want all members of "CN=Domain Leute,DC=mycompany,DC=com". How would I know that is the well-known "Domain Users" group?
Or what if some users' primary group was changed to "CN=rebels,DC=mycompany,DC=com", and I wanted to get members of THAT group? Users don't have a memberOf property for their primary group, and the primary group won't have a member property listing them.
This is what I see when viewed via LDAP (ie, no MS extensions):
You need to find out primaryGroupToken from the Group object first. If you are using ADSIEdit, you need to make sure you have "Constructed" filter on to see this calculated attribute. For Domain Users, the primaryGroupToken should be 513.
Then, you neeed to find all the users with primaryGroupID set to this value. Here is the ldap query you should write to find out all users with Domain Users set as the primary group.
(&(objectCategory=person)(objectClass=user)(primaryGroupID=513))
EDIT
Here is the steps to show primaryGroupToken in LDAP Browser. I am using LDAP browser 2.6 build 650. Right click your profile and click properties
Go to LDAP Settings tab and click Advanced button.
Add an extra operational attribute primaryGroupToken
Click Apply button and close the properties page. Now, you should see the primaryGroupToken in your group object.
To get the the primaryGroupToken from any given group extract it from the objectSid so for example Domain Users objectSid = S-1-5-21-704657944-2065781323-617630493-513
then the primaryGroupToken is the last digits after the "-" so in the case of the "Domain Users" its 513
This is a PS script that I made to do exactly that:
[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices");
$groupName = "Grupo Domain";
$directoryEntry = New-Object System.DirectoryServices.DirectoryEntry;
$directorySearcher = New-Object System.DirectoryServices.DirectorySearcher($directoryEntry, "(&(objectClass=group)(CN=$groupName))");
[void]$directorySearcher.PropertiesToLoad.Add("objectSid");
[void]$directorySearcher.PropertiesToLoad.Add("member");
$result = $directorySearcher.FindOne();
if ($result -eq $null) { return; }
# Try get the group members through the "member" property.
if ($result.Properties["member"].Count -gt 0) {
foreach ($member in $result.Properties["member"]) {
$memberSearcher = New-Object System.DirectoryServices.DirectorySearcher($directoryEntry, "(&(objectClass=*)(distinguishedName=$member))");
[void]$memberSearcher.PropertiesToLoad.Add("msDS-PrincipalName");
$memberResult = $memberSearcher.FindOne();
if ($memberResult -eq $null) { continue; }
Write-Output $memberResult.Properties["msDS-PrincipalName"];
}
return;
}
if ($result.Properties["objectSid"].Count -gt 0) {
# The group might be an AD primary group. Try get the members by the PrimaryGroupID.
$groupSid = New-Object System.Security.Principal.SecurityIdentifier($result.Properties["objectSid"][0], 0);
# Hacky way to get only the last RID.
$primaryGroupSid = $groupSid.Value.Replace($groupSid.AccountDomainSid.ToString(), [String]::Empty).TrimStart('-');
$memberSearcher = New-Object System.DirectoryServices.DirectorySearcher($directoryEntry, "(&(objectClass=*)(primaryGroupId=$primaryGroupSid))");
[void]$memberSearcher.PropertiesToLoad.Add("msDS-PrincipalName");
$memberResult = $memberSearcher.FindAll();
if ($memberResult -eq $null) { continue; }
foreach ($member in $memberResult) {
Write-Output $member.Properties["msDS-PrincipalName"];
}
}