2012-05-22 4 views
9

모든 Active Directory 사용자를 찾으려면 System.DirectoryServices.ActiveDirectory 클래스를 사용하고 있습니다. 코드는 매우 간단합니다 :UserPrincipal 개체의 도메인 이름은 어디에 있습니까?

var context = new PrincipalContext(ContextType.Domain); 
var searcher = new PrincipalSearcher(new UserPrincipal(context)); 
var results = searcher.FindAll(); 

내가 예를 들어, "친숙한"(. 일명 "Windows 2000 이전 버전"형식)의 도메인 자격을 갖춘 사용자 이름을 싶어. "CONTOSO \ SmithJ". UserPrincipal.SamAccountName은 나에게 사용자 이름 부분을 제공하지만 어떻게 도메인 부분을 가져 옵니까? 도메인이 컴퓨터 또는 현재 사용자의 도메인과 동일하다고 가정 할 수 없습니다.

+0

가능한 중복 : http://stackoverflow.com/questions/4284641/get-netbiosname-from- a-userprincipal-object – MichelZ

답변

6

AD DS의 경우 msDS-PrincipalName의 값은 NetBIOS 도메인 이름이고 그 뒤에 백 슬래시 ("\")가옵니다.

당신은 사용하여 찾을 수 있습니다

/* Retreiving the root domain attributes 
*/ 
sFromWhere = "LDAP://DC_DNS_NAME:389/dc=dom,dc=fr"; 
DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "AdminLogin", "PWD"); 

DirectorySearcher dsLookForDomain = new DirectorySearcher(deBase); 
dsLookForDomain.Filter = "(objectClass=*)"; 
dsLookForDomain.SearchScope = SearchScope.base; 
dsLookForDomain.PropertiesToLoad.Add("msDS-PrincipalName"); 

SearchResult srcDomains = dsLookForDomain.FindOne(); 
+0

+1 감사합니다. msDS-PrincipalName이 원하는대로 보입니다. – EMP

+0

참고 : MSDN에 따라 Domain \ Username 또는 사용자의 SID 일 수 있습니다. http://msdn.microsoft.com/en-us/library/cc223404.aspx –

0

확인을, 여기에 최종 코드는 내가 JPBlanc의 대답과 answer linked by MichaelZ를 사용하여 함께했다. 각 사용자의 SID, 표시 이름 및 DOMAIN \ 사용자 이름을 표시합니다.

var ldapUrl = "LDAP://" + defaultNamingContext; 

    using (var rootDe = new DirectoryEntry(ldapUrl)) 
    using (var searcher = new DirectorySearcher(rootDe)) 
    { 
     searcher.SearchScope = SearchScope.Subtree; 
     searcher.PropertiesToLoad.Add("objectSid"); 
     searcher.PropertiesToLoad.Add("displayName"); 
     searcher.PropertiesToLoad.Add("msDS-PrincipalName"); 
     searcher.Filter = "(&(objectClass=user)(objectCategory=person))"; 

     var results = searcher.FindAll(); 

     foreach (SearchResult result in results) 
     { 
      var qualifiedUsername = GetSinglePropertyValue(result, "msDS-PrincipalName"); 
      var displayName = GetSinglePropertyValue(result, "displayName"); 
      var sid = new SecurityIdentifier((byte[])GetSinglePropertyValue(result,"objectSid"), 0); 

      Console.WriteLine("User: {0}\r\n\tDisplay name: {1}\r\n\tSID: {2}", 
       qualifiedUsername, displayName, sid); 
     } 
    } 

    private static object GetSinglePropertyValue(SearchResult result, string propertyName) 
    { 
     var value = result.Properties[propertyName]; 
     if (value.Count == 0) 
      return null; 
     if (value.Count == 1) 
      return value[0]; 
     throw new ApplicationException(string.Format("Property '{0}' has {1} values for {2}", 
      propertyName, value.Count, result.Path)); 
    } 

그리고 (answered here 등) 컴퓨터의 도메인에 대한 기본 명명 컨텍스트를 효율적으로 활용하려면 다음

private static string GetDefaultNamingContext() 
{ 
    // This check is fast 
    try 
    { 
     Domain.GetComputerDomain(); 
    } 
    catch (ActiveDirectoryObjectNotFoundException) 
    { 
     return null; 
    } 

    // This takes 5 seconds if the computer is not on a domain 
    using (var rootDe = new DirectoryEntry("LDAP://RootDSE")) 
    { 
     try 
     { 
      return (string)rootDe.Properties["defaultNamingContext"][0]; 
     } 
     catch (COMException ex) 
     { 
      if (ex.ErrorCode == -2147023541) 
       return null; 
      throw; 
     } 
    } 
}