2011-08-22 73 views
4

我已經寫了一些代碼來獲取組和嵌套組的所有用戶。我還想確保,如果組成員身份通過讓第一組成爲最後一組的成員而導致循環,則循環不會發生。使用C#枚舉嵌套的AD用戶組

我寫的代碼工作正常,但有點慢。

這是我第一次嘗試做AD查找。

有人可以看一看,並告訴我,如果代碼看起來好還是壞 - 編碼(或更糟糕的),或者我已經走了錯路?

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

你可以看看[這個答案] [1]? [1]:http://stackoverflow.com/questions/6252819/find-recursive-group-membership-active-directory-using-c/6289205#6289205 – JPBlanc

回答

1

如果你在.NET 3.5及以上,你應該看看System.DirectoryServices.AccountManagement(S.DS.AM)命名空間。在這裏閱讀全部內容:

基本上,你可以定義域範圍內,並可以輕鬆地查找用戶和/或組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 
     } 
    } 
} 

的新的S.DS.AM使得與AD中的用戶和羣組玩轉非常容易。致電.GetGroups()也會處理所有嵌套組員問題等問題 - 無需再處理這種麻煩!

+0

我沒有看新的.Net 3.5代碼,但我的最終應用程序將不得不在僅安裝.net 2.0的服務器上工作。 – RickBowden

+0

@RickBowden:但.NET 3.5只是.NET 2.0的一個小「服務包」 - 沒有什麼全新的...... –

+0

的確如此,但我在如此緊密(過度)管理的變更控制環境中工作升級這些東西是一場噩夢。 – RickBowden