c# .net active-directory group-membership

Enumeración de grupos de usuarios anidados usando C#



.net active-directory (1)

He escrito un código que obtiene todos los usuarios de grupos y grupos anidados. También quería asegurarme de que el bucle no ocurriera si la pertenencia al grupo causaba un bucle al tener al primer grupo como miembro del último grupo.

El código que escribí funciona bien pero es un poco lento.

Esta es la primera vez que intento hacer búsquedas AD.

¿Podría alguien echar un vistazo y decirme si el código se ve bien o mal codificado (o peor), o lo he hecho de la manera incorrecta?

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) { } } } }


Si tiene .NET 3.5 y superior, debe consultar el espacio de nombres System.DirectoryServices.AccountManagement (S.DS.AM). Lea todo al respecto aquí:

Básicamente, puede definir un contexto de dominio y encontrar fácilmente usuarios y / o grupos en 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''s group memberships foreach(Principal principal in me.GetGroups()) { GroupPrincipal gp = (principal as GroupPrincipal); if(gp != null) { // do something with the group } } }

El nuevo S.DS.AM hace que sea realmente fácil jugar con usuarios y grupos en AD. La llamada a .GetGroups() también maneja todos los problemas de membresías grupales anidadas, etc., para usted, ¡sin necesidad de lidiar con esa molestia más!