Enumerating AD Nested User Groups Using C #

I wrote code in which all users of groups and nested groups. I also wanted to make sure that the cycle did not happen if the group membership caused the cycle when the first group was a member of the last group.

The code I wrote works fine, but a little slower.

This is the first time I have tried searching in AD.

Can someone take a look and tell me if the code looks OK or bad coding (or worse), or was I wrong?

using System; using System.Collections.Generic; using System.Text; using System.DirectoryServices; using System.IO; namespace Tester3 { class Program3 { public static List<string> appGroupList = new List<string>(); public static List<string> userList = new List<string>(); public static List<string> groupList = new List<string>(); public static List<string> groupChecked = new List<string>(); static void Main(string[] args) { // Create Output File StreamWriter outputfile = new StreamWriter("output.txt", false); appGroupList.Add("GLB-SBCCitrixHelpdesk-DL"); appGroupList.Add("SBC_UKBSAVIA001_PROD_ROL_Siebel"); foreach (string appGroup in appGroupList) { string appGroupCN = GetCN(appGroup); GetMembers(appGroupCN); groupChecked.Clear(); } foreach (string item in userList) { Console.WriteLine(item); outputfile.WriteLine(item); } outputfile.Flush(); outputfile.Close(); Console.ReadLine(); } private static string GetCN(string group) { string groupCN = string.Empty; try { using (DirectorySearcher search = new DirectorySearcher()) { search.Filter = "(&(cn=" + group + ")(objectClass=group))"; search.PropertiesToLoad.Add("CN"); SearchResult result = search.FindOne(); if (result != null) { groupCN = result.Properties["adsPath"][0].ToString(); groupCN = groupCN.Replace("LDAP://", ""); } return groupCN; } } catch (Exception) { return groupCN; } } public static void GetMembers(string group) // get members using the groups full cn { // Check if group has already been checked if (groupChecked.Contains(group)) { return; } // Add group to groupChecked list groupChecked.Add(group); try { // Connect to group object using (DirectoryEntry groupObject = new DirectoryEntry("LDAP://" + group)) { // Get member of group object PropertyValueCollection col = groupObject.Properties["member"] as PropertyValueCollection; // Loop through each member foreach (object member in col) { // Connect to member object using (DirectoryEntry memberObject = new DirectoryEntry("LDAP://" + member)) { // Get class of member object string memberClass = memberObject.Properties["objectClass"][1].ToString(); string memberCN = memberObject.Properties["Name"][0].ToString(); if (!groupChecked.Contains(member.ToString())) { if (memberClass.ToLower() == "group") { GetMembers(member.ToString()); } else { userList.Add(memberCN); } } else { if (memberClass.ToLower() != "group") { userList.Add(memberCN); } } } } } } catch (Exception) { } } } } 
+4
source share
1 answer

If you are using .NET 3.5 and above, you should check the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read more here:

Basically, you can define the context of a domain and easily find users and / or groups in AD:

 // set up domain context PrincipalContext ctx = new PrincipalContext(ContextType.Domain); // find a user UserPrincipal user = UserPrincipal.FindByIdentity(ctx, "SomeUserName"); if(user != null) { // get a user group memberships foreach(Principal principal in me.GetGroups()) { GroupPrincipal gp = (principal as GroupPrincipal); if(gp != null) { // do something with the group } } } 

The new S.DS.AM makes it very easy to play with users and groups in AD. The call to .GetGroups() also handles all the problems of nested group memberships, etc. For you - no more worries about this problem!

+1
source

All Articles