1

I'm working in .net 2.0 and need to retrieve all the users of a given AD group. I have the following method that does return all the members of the group, but it does not return users that have the passed group as their primary group. What do I need to do to get those users included as well?

/// <summary>
/// Gets the group child users.
/// </summary>
/// <param name="parentGroup">The parent group.</param>
/// <returns></returns>
public List<ADUser> GetGroupChildUsers(ADGroup parentGroup)
{
    List<ADUser> list = new List<ADUser>();

    DirectoryEntry entry = GetDirectoryEntry(LdapBaseString);

    DirectorySearcher searcher = new DirectorySearcher(entry);
    searcher.Filter = string.Format("(&(objectCategory=person)(memberOf={0}))", parentGroup.DN);

    searcher.PropertiesToLoad.Add("objectGUID");
    searcher.SizeLimit = MaxReturnCount;

    SearchResultCollection results = searcher.FindAll();

    foreach (SearchResult result in results) {
        Guid guid = new Guid((byte[])result.Properties["objectGUID"][0]);
        list.Add(GetUserByGuid(guid));
    }

    if (list.Count <= 0) {
        return null;
    } else {
        return list;
    }
}
Matthew Vines
  • 27,253
  • 7
  • 76
  • 97
  • I had a similar question a while ago, this may help. I needed to extract only machines or only user names instead of everything. http://stackoverflow.com/questions/6252785/winnt-giving-to-much-information-i-need-to-narrow-down-to-just-machine-names – sealz Jun 20 '11 at 17:46

1 Answers1

4

The primary group of a user is given by primaryGroupID attribute of a user. In fact primaryGroupID contains the RID of the primary group in a string format. That's why, I first get the SID of the group you are looking for users, then I compute (badly) the RID, and I search for users with a primaryGroupID containing the RID.

/* Connection to Active Directory
 */
DirectoryEntry deBase = new DirectoryEntry("LDAP://WM2008R2ENT:389/dc=dom,dc=fr");

/* Directory Search for agroup
 */
string givenGrpName = "MonGrpSec"; 
DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
dsLookFor.Filter = string.Format ("(sAMAccountName={0})", givenGrpName);
dsLookFor.SearchScope = SearchScope.Subtree;
dsLookFor.PropertiesToLoad.Add("cn");
dsLookFor.PropertiesToLoad.Add("objectSid");

SearchResult srcGrp = dsLookFor.FindOne();

/* Get the SID
 */
SecurityIdentifier secId = new SecurityIdentifier(srcGrp.Properties["objectSid"][0] as byte[], 0);

/* Find The RID (sure exists a best method)
 */
Regex regRID = new Regex(@"^S.*-(\d+)$");
Match matchRID =  regRID.Match(secId.Value);
string sRID = matchRID.Groups[1].Value;

/* Directory Search for users that has a particular primary group
 */
DirectorySearcher dsLookForUsers = new DirectorySearcher(deBase);
dsLookForUsers.Filter = string.Format("(primaryGroupID={0})", sRID);
dsLookForUsers.SearchScope = SearchScope.Subtree;
dsLookForUsers.PropertiesToLoad.Add("cn");

SearchResultCollection srcUsers = dsLookForUsers.FindAll();

foreach (SearchResult user in srcUsers)
{
  Console.WriteLine("{0} is the primary group of {1}", givenGrpName, user.Properties["cn"][0]);
}
JPBlanc
  • 70,406
  • 17
  • 130
  • 175
  • Impressive. Do you know how to get all members of nested security and distribution group types? – J Weezy Mar 16 '18 at 17:45
  • Yes, you've got the answer in [this](https://stackoverflow.com/a/8055996/608772) other post or [here](https://stackoverflow.com/a/6289205/608772). . – JPBlanc Mar 17 '18 at 17:50
  • 1
    Based on the solution you provide, from what I can tell, the method for getting all group members is to find what groups a user is a member of. Am I correct? The method I am attempting to implement goes the other way: it gets all members contained within the group itself. The reason for doing it this way is that there are far fewer groups then there are users. So, getting the group that each user is in would result in the same group being hit multiple times. Is it possible to only inspect a group and get all members regardless of groupType? – J Weezy Mar 19 '18 at 15:54