Search code examples
asp.netactive-directoryldapdirectoryservicesdirectorysearcher

Find members and members of sub-group


How do I get a list of all the members AND (members of the) subgroups within a specific group/department using DirectorySearcher and Filter/PropertiesToLoad?

At the moment, I can get the group to return all its members. However, there are sub-groups within the group and I cannot get to the members within those sub-groups too.

This is what I have so far:

        DirectoryEntry entry = null;
    entry = new DirectoryEntry("LDAP://DC=au,DC=company,DC=com", null, null, AuthenticationTypes.Secure);

    try
    {
        DirectorySearcher ouSearch = new DirectorySearcher(entry);
        ouSearch.Filter = "(&(objectClass=user)(objectCategory=person)(displayName=*" + username + "*)" +
        "(|" +
            "(memberOf=CN=my department,OU=ADC-Distribution Groups,DC=au,DC=company,DC=com)" +

        ")" +

        ")";

        ouSearch.PropertiesToLoad.Add("samAccountName");
        ouSearch.PropertiesToLoad.Add("displayName");
        ouSearch.PropertiesToLoad.Add("memberOf");
        ouSearch.SearchScope = SearchScope.Subtree;

        SearchResultCollection allOUS = ouSearch.FindAll();

Any assistance appreciated!


Solution

  • You would have to do the search recursively expanding every subgroup that is a member of another group.

    However, there is a lot easier method using the GroupPrincipal class of the System.DirectoryServices.AccountManagement namespace.

    GroupPrincipal has a method GetMembers which allows you to retrieve all members of a group recursively. All you have to do is specify true as the only parameter to GetMembers.

    The following example is copied from MSDN:

    PrincipalContext ctx = new PrincipalContext(ContextType.Domain,                                                                    
                                            "fabrikam.com", 
                                            "DC=fabrikam,DC=com", 
                                            "administrator", 
                                            "SecretPwd123");
    
    GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, 
                                                   IdentityType.Name, 
                                                   "Domain Admins");
    
    if (grp != null)
    {
        foreach (Principal p in grp.GetMembers(recursive: true))
        {
            Console.WriteLine(p.Name);
        }
        grp.Dispose();
    }
    
    ctx.Dispose();