2012-11-21 193 views
1

我正在編寫一個應用程序,需要從指定的域中獲取用戶列表。我現在可以獲得用戶,但是這是一種減慢速度的方法,尤其是在較大的域名上,我該如何更快地做到這一點?獲取Active Directory中的用戶列表

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, domain)) 
     { 
      UserPrincipal userPrincipal = new UserPrincipal(pc); 

      PrincipalSearcher search = new PrincipalSearcher(userPrincipal); 

      PrincipalSearchResult<Principal> results = search.FindAll(); 

      foreach (var principals in results.Partition(20)) 
      { 
       IDictionary<string, string> users = new Dictionary<string, string>(20); 
       foreach (UserPrincipal principal in principals.Cast<UserPrincipal>()) 
       { 
        users.Add(principal.SamAccountName, principal.DisplayName); 
       } 

       yield return users; 
      } 
     } 

基本上在外foreach循環我得到的IEnumerable的IEnumerable>。我這樣做,所以我可以嘗試逐漸加載一些,並將其顯示給用戶,而其餘的仍在加載,但是一旦我打到內部循環,我會有幾分鐘的掛起。

我想獲得域\用戶名格式的用戶名,以及我還沒有想出如何做。

回答

2

試試這個。它應該工作得更快。

using System.DirectoryServices; 

string[] RetProps = new string[] { "SamAccountName", "DisplayName" }; 
       //IDictionary<string, string> users = new Dictionary<string, string>(); 
List<string[]> users = new List<string[]>(); 

      foreach (SearchResult User in GetAllUsers("YourDomain", RetProps)) 
      { 
      DirectoryEntry DE = User.GetDirectoryEntry(); 
      try 
       { 
       users.Add(new string[]{DE.Properties["SamAccountName"][0].ToString(), DE.Properties["DisplayName"][0].ToString()}); 
       } 
       catch 
       { 
       } 
      } 


    internal static SearchResultCollection GetAllUsers(string DomainName, string[] Properties) 
    { 
     DirectoryEntry DE = new DirectoryEntry("LDAP://" + DomainName); 
     string Filter = "(&(objectCategory=organizationalPerson)(objectClass=User))"; 
     DirectorySearcher DS = new DirectorySearcher(DE); 
     DS.PageSize = 10000; 
     DS.SizeLimit = 10000; 
     DS.SearchScope = SearchScope.Subtree; 
     DS.PropertiesToLoad.AddRange(Properties); DS.Filter = Filter; 
     SearchResultCollection RetObjects = DS.FindAll(); 
     return RetObjects; 
    } 
    } 
} 
+0

我用你的方法,並將Asynchronous屬性設置爲true,現在加載速度更快。謝謝。 – twreid

+0

不客氣。 – Daro

+0

@twreid你只是設置Asynchronous = true,但沒有使用異步或任務? –

0

這非常快。幾秒鐘後我就得到了14k結果。如果你需要更新UI,你可以使用一個事件處理器和一個不同的線程。

string groupName = "Domain Users"; 
      string domainName = "domain"; 
      var results = new List<string>(); 
      using (var pc = new PrincipalContext(ContextType.Domain, domainName)) 
      { 
       using (var grp = GroupPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, groupName)) 
       { 
        if (grp != null) 
         foreach (var p in grp.GetMembers(false)) 
         { 
          results.Add(p.DisplayName); 
         } 
       } 
       Assert.IsTrue(results.Count > 0); 
      } 
+0

我不能使用,因爲我不要在手之前不知道組或用戶名。我正在嘗試獲取活動目錄中的用戶列表,以便用戶可以選擇他們想要的。 – twreid

+0

我想我不確定你爲什麼仍然不能,也許只是通過組。這將返回所有的用戶名,一旦用戶選擇一個你可以得到該用戶。這就是說,我不是專家......只是把相同類型的東西工作了一次 –

+0

我試過了,它沒有奏效。我認爲這不是解決方案的缺陷,而是我們的廣告太大。 – twreid

0

dc是cntroller例如如何 「company.com」

public static ArrayList GetAllActiveDirectoryUsersByDisplayName(string dc) 
      { 
       ArrayList list = new ArrayList(); 

       PrincipalContext ctx = new PrincipalContext(ContextType.Domain, dc); 
       UserPrincipal u = new UserPrincipal(ctx); 

       PrincipalSearcher ps = new PrincipalSearcher(u); 
       PrincipalSearchResult<Principal> results = ps.FindAll(); 

       foreach (UserPrincipal usr in results) 
       { 
        list.Add(usr.Name); 
       } 

      list.Sort(); 

      return list; 
     } 

在endfront你可以這樣做域名:

ArrayList list = GetAllActiveDirectoryUsersByDisplayName("company.com"); 

       foreach (string x in list) 
       { 
        Console.WriteLine(x); 
       } 
相關問題