2012-11-21 18 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을 얻고있다. 나는 한 번에 점진적으로 몇 개를로드하고 나머지는로드하는 동안 사용자에게 표시하도록 시도 할 수 있었지만 한 번 그 내부 루프를 쳤을 때 몇 분 정도 멈춰 버렸습니다.

domain \ username 형식의 사용자 이름을 얻으려고 시도하고 있는데 그 중 하나를 수행하는 방법을 찾지 못했습니다.

답변

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

귀하의 방법을 사용하고 또한 비동기 속성을 true로 설정하면 더 빨리로드됩니다. 고맙습니다. – twreid

+0

당신을 진심으로 환영합니다. – Daro

+0

@twreid 비동기 = true로 설정했으나 비동기 또는 작업 을 사용하지 않았습니까? –

0

매우 빠릅니다. 나는 2 초 만에 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

내가 사용할 수있는 I 돈으로 전에 그룹 또는 사용자 이름을 알지 못합니다. 사용자가 원하는 디렉토리를 선택할 수 있도록 활성 디렉토리에서 사용자 목록을 얻으려고합니다. – twreid

+0

나는 왜 아직도 네가 할 수 없는지 모르겠다. 아마도 그룹에 합격했을 것이다. 사용자가 해당 사용자를 얻을 수있는 사용자 이름을 선택하면 모든 사용자 이름이 반환됩니다. 그건, 내가 전문가가 아니야 ... 그냥 일을 동일한 유형의 일을 한 번 만든 –

+0

나는 그것을 시도하고 그것이 작동하지 않았다. 나는 그것이 당신의 해결책에 결함이 있다고 생각하지 않지만 오히려 우리의 광고는 너무 큽니다. – twreid

0

직류이 endfront 예 "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; 
     } 

을 위해 당신이 할 수있는 방법을 cntroller 도메인입니다 :

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

       foreach (string x in list) 
       { 
        Console.WriteLine(x); 
       } 
관련 문제