Active Directory에서 사용자 목록을 얻으려면 어떻게해야합니까?


109

Active Directory에서 사용자 목록을 얻으려면 어떻게해야합니까? 사용자 이름, 이름, 성을 가져 오는 방법이 있습니까? 이것이 사용 된 유사한 게시물을 보았습니다.

 PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN");

나는 Active Directory로 아무것도하지 않았으므로 완전히 길을 잃었습니다. 어떤 도움이라도 대단히 감사하겠습니다!


3
.NET 3.5에서 AD를 사용하는 방법에 대한 훌륭한 소개를 보려면 우수한 MSDN 문서 .NET Framework 3.5에서 디렉터리 보안 주체 관리를 읽어보십시오.
marc_s 2011 년

@의 marc_s의 기사처럼 보이는이 여기 있어요, 보관있어 업데이트 링크
JB합니다.

@marc_s 선생님을 읽고 싶지만 링크는 죽은 것입니다. 나는이 시도 blogs.msdn.microsoft.com/msdnmagazine/2008/01/16/... 마이크로 소프트 잡지 유전 페이지에 그 기사의 리드에 있지만, 심지어 링크
말콤 살바도르에게

1
@ Malky.Kid 나는 기사로가는 길을 찾았다. 이 질문 에 대한 첫 번째 의견링크를 사용하여 2008 년 1 월호를 다운로드하십시오 . 읽기 전에 탐색기 속성 페이지에서 chm 파일의 차단을 해제하는 것을 잊지 마십시오.
OneWorld

답변:


229

Active Directory를 처음 사용하는 경우 먼저 Active Directory가 데이터를 저장하는 방법을 이해해야합니다.

Active Directory는 실제로 LDAP 서버입니다. LDAP 서버에 저장된 개체는 계층 적으로 저장됩니다. 파일 시스템에 파일을 저장하는 것과 매우 유사합니다. 이것이 바로 Directory Server와 Active Directory 라는 이름을 갖게 된 이유입니다.

Active Directory의 컨테이너 및 개체는 distinguished name. 고유 이름은 다음과 같습니다 CN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=com. 기존 관계형 데이터베이스와 마찬가지로 LDAP 서버에 대해 쿼리를 실행할 수 있습니다. 이를 LDAP 쿼리라고합니다.

.NET에서 LDAP 쿼리를 실행하는 방법에는 여러 가지가 있습니다. DirectorySearcher from System.DirectoryServices또는 SearchRequest 를 사용할 수 있습니다 System.DirectoryServices.Protocol.

귀하의 질문에 대해서는 사용자 주체 개체를 구체적으로 찾으려고하기 때문에 가장 직관적 인 방법은에서 PrincipalSearcher 를 사용하는 것 System.DirectoryServices.AccountManagement입니다. Google에서 다양한 예를 쉽게 찾을 수 있습니다. 다음은 귀하가 요구하는 것을 정확히 수행하는 샘플입니다.

using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (var result in searcher.FindAll())
        {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
            Console.WriteLine("Last Name : " + de.Properties["sn"].Value);
            Console.WriteLine("SAM account name   : " + de.Properties["samAccountName"].Value);
            Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value);
            Console.WriteLine();
        }
    }
}
Console.ReadLine();

AD 사용자 개체에는 여러 특성이 있습니다. 특히, givenName당신을 줄 것이다 First Name그리고 sn당신에게 줄 것이다 Last Name. 사용자 이름에 대해. 사용자 로그온 이름을 의미하는 것 같습니다. AD 사용자 개체에는 두 개의 로그온 이름이 있습니다. 하나는 samAccountNameWindows 2000 이전 사용자 로그온 이름이라고도하는입니다. userPrincipalName일반적으로 Windows 2000 이후에 사용됩니다.


2
서버에 도메인이없는 경우

동일한 코드를 사용하여 AD 그룹의 사용자를 나열하는 방법은 무엇입니까?
nJoshi

이 방법을 사용하여 이메일 주소가 할당 된 디렉토리의 검색 범위 만 좁힐 수 있습니까?
ARidder101 2017-04-04

신경 쓰지 마, 알아 냈어. if (((UserPrincipal)result).EmailAddress != null)결과를 내 목록 에 추가 하기 전에 추가 해야했습니다 .
ARidder101 2017

2
현재 컴퓨터가 도메인에 속하지 않으면 어떻게됩니까?
Marcus

23

y 활성 계정을 필터링하려면 Harvey의 코드에 다음을 추가하십시오.

 UserPrincipal userPrin = new UserPrincipal(context);
 userPrin.Enabled = true;

처음 사용 후. 그런 다음 추가

  searcher.QueryFilter = userPrin;

모두 찾기 전에. 그리고 그것은 당신에게 활성을 가져다 줄 것입니다.


searcher.QueryFilter = userPrin;초기화시 사용자 주체를 주체 검색 자에게 이미 전달했기 때문에 필요하지 않다고 생각 하지만 그렇지 않은 경우 활성 사용자 만 필터링하는 팁에 감사드립니다!
Andrey

1
그래, 안드레이는 문을 사용하여 두 번째에서이 속성을 추가하는 바로 그래서 기본적으로이 대체 될 수있다 :using (var searcher = new PrincipalSearcher(new UserPrincipal(context){ Enabled = true }))
마르코 Jovanov

하지만 Enabled값이 있는지 먼저 테스트해야한다고 생각했습니다 .if (userPrincipal.Enabled.HasValue)
JohnB

4

확실히 여기에서 @Harvey Kwok에게 크레딧이 전달되지만, 제 경우에는 실제 UserPrincipals 목록을 얻고 싶었 기 때문에이 예제를 추가하고 싶었습니다. 이 쿼리를 미리 필터링하는 것이 더 효율적일 수 있지만 소규모 환경에서는 모든 항목을 가져온 다음 나중에 목록에서 필요에 따라 필터링하는 것이 더 쉽습니다.

필요한 항목에 따라 DirectoryEntry로 캐스트 할 필요가 없지만 일부 속성은 UserPrincipal에서 사용할 수 없습니다.

using (var searcher = new PrincipalSearcher(new UserPrincipal(new PrincipalContext(ContextType.Domain, Environment.UserDomainName))))
{
    List<UserPrincipal> users = searcher.FindAll().Select(u => (UserPrincipal)u).ToList();
    foreach(var u in users)
        {
            DirectoryEntry d = (DirectoryEntry)u.GetUnderlyingObject();
            Console.WriteLine(d.Properties["GivenName"]?.Value?.ToString() + d.Properties["sn"]?.Value?.ToString());
        }
}

'e'는 무엇입니까?
Fandango68

1
감사합니다. 나는 그것을 바꿨고, "u"로되어 있었다. 속성이 누락 된 경우 null 값을 처리하기 위해? s도 추가했습니다.
Jordan

1

System.DirectoryServices.dll을 포함시킨 다음 아래 코드를 사용하십시오.

DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + Environment.MachineName);
string userNames="Users: ";

foreach (DirectoryEntry child in directoryEntry.Children)
{
    if (child.SchemaClassName == "User")
    {
        userNames += child.Name + Environment.NewLine   ;         
    }

}
MessageBox.Show(userNames);

1
@ Fandango68 : LOL, 맞아요 !!! System.Windows.Forms.MessageBox.Show (ex.Message + ex.StackTrace);
Jhollman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.