I recently wrote about searching Active Directory users with C#, and mentioned that the next part of the equation was searching Active Directory groups, and returning all the users in the group. Since groups can contain other groups, we must perform this search recursively. In order to avoid the infinite recursion possibility, I added a search depth parameter, and set the maximum search depth to 5. The code I used is below, and you’ll probably notice that it’s pretty similar to my code for searching Active Directory users.
private string[] GetActiveDirectoryGroupUsers(string groupName, int searchDepth)
{
if (searchDepth > Configuration.Instance.ADMaxGroupDepth)
return (new List()).ToArray();
List userNames = new List();
using (DirectoryEntry entry = new DirectoryEntry(Configuration.Instance.LdapPath,
Configuration.Instance.LdapUsername,
Configuration.Instance.LdapPassword,
AuthenticationTypes.Secure))
{
using (DirectorySearcher adSearcher = new DirectorySearcher(entry))
{
// build search filter
string filter = String.Format("(&(objectClass=group)(cn={0}))", groupName);
adSearcher.Filter = filter;
adSearcher.PropertiesToLoad.Add("member");
SearchResult adResult = adSearcher.FindOne();
if (adResult != null && adResult.Properties["member"] != null)
{
for (int i = 0; i < adResult.Properties["member"].Count; i++)
{
string adMember = adResult.Properties["member"][i].ToString();
int userIndex1 = adMember.IndexOf("=", 0);
int userIndex2 = adMember.IndexOf(",", 0);
string username = adMember.Substring(userIndex1 + 1, (userIndex2 - userIndex1) - 1);
if (adMember.Contains("OU=Groups")) // search group recursively
userNames.AddRange(GetActiveDirectoryGroupUsers(username, searchDepth + 1));
else
userNames.Add(username);
}
}
}
}
// sort the array before returning result
userNames.Sort();
return userNames.ToArray();
}