Search code examples
c#active-directorydirectoryservices

Active Directory - get all users in multiple Ad Groups


Is there a way to get all active users in multiple groups?

For example:

Get all active users in "AdGroupA" OR "AdGroupB" OR "AdGroupC"

I have see post about single group but not multiple groups.

Thanks.


Solution

  • If I understand you correctly, you just want to return the entire list of users in multiple groups? That should be as easy as getting the users from the single group multiple times.

    public IEnumerable<UserPrincipal> GetUsersFromGroups(string[] groupNames)
    {
        using (var ctx = new PrincipalContext(ContextType.Domain))
        {
            foreach (var groupName in groupNames)
            {
                foreach (var userPrincipal in GroupPrincipal.FindByIdentity(ctx, groupName)
                                                   .GetMembers())
                {
                    yield return userPrincipal;
                }
            }       
        }
    }    
    

    Here is a method not using AccountManagement:

    using System.DirectoryServices;
    
    public static IEnumerable<DirectoryEntry> GetUsersFromGroups(string[] groupNames)
    {
        if (groupNames.Length > 0)
        {
            var searcher = new DirectorySearcher();
            string searchFilter = "(&(objectClass=Group)"; //filter for groups
            searchFilter += "(|"; //start a group of or parameters
    
            foreach (var group in groupNames)  // loop through the group names
            {
                searchFilter += string.Format("(SAMAccountName={0})",group); //add a parameter for each group in the list
            }
    
            searchFilter += "))"; //close off the filter string
            searcher.Filter = searchFilter; //add the filter to the searcher
    
            searcher.PropertiesToLoad.Add("member"); // load the members property for the group
    
            var searchResults = searcher.FindAll(); // perform the search
    
            foreach (SearchResult result in searchResults)
            {
                var directoryEntry = (DirectoryEntry)result.GetDirectoryEntry(); // get the directory entry for the group
                PropertyValueCollection members = directoryEntry.Properties["member"]; // get the members collection
    
                foreach (string name in members)   // iterate over the members. This string will be the distinguished name
                {
                    yield return new DirectoryEntry(string.Format("LDAP://{0}",name)); //return the directory entry. You may get the entry and return the display name or just return distinguished name.
                }
            }
        }        
    }
    

    In my environment I found this to be about 25% faster on average than using DirectoryServices.AccountManagement for 1 group, but as the count of groups and users increased the AccountManagement method actually became faster. This only queries AD once while the first method queries once per group.