web-dev-qa-db-ja.com

Active Directoryからユーザーのリストを取得するにはどうすればよいですか?

Active Directoryからユーザーのリストを取得するにはどうすればよいですか?ユーザー名、名、姓を取得する方法はありますか?私はこれが使用された同様の投稿を見ました:

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

Active Directoryを使用したことがないため、完全に失われました。どんな助けも大歓迎です!

98
Mike

Active Directoryを初めて使用する場合は、Active Directoryが最初にデータを保存する方法を理解することをお勧めします。

Active Directoryは、実際にはLDAPサーバーです。 LDAPサーバーに保存されているオブジェクトは階層的に保存されます。ファイルシステムにファイルを保存するのと非常に似ています。それが名前DirectoryサーバーとアクティブDirectoryを得た理由です

Active Directoryのコンテナとオブジェクトは、distinguished nameで指定できます。識別名はCN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=comのようなものです。従来のリレーショナルデータベースと同様に、LDAPサーバーに対してクエリを実行できます。 LDAPクエリと呼ばれます。

.NETでLDAPクエリを実行する方法はいくつかあります。 DirectorySearcher from System.DirectoryServicesまたは SearchRequest from System.DirectoryServices.Protocolを使用できます。

あなたの質問については、ユーザープリンシパルオブジェクトを具体的に見つけることを求めているので、最も直感的な方法は PrincipalSearcher from 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ユーザーオブジェクトには、多くの属性があります。特に、givenNameFirst Nameを提供し、snLast Nameを提供します。ユーザー名について。ユーザーのログオン名を意味していると思います。 ADユーザーオブジェクトには2つのログオン名があることに注意してください。 1つはsamAccountNameです。これは、Windows 2000以前のユーザーログオン名とも呼ばれます。 userPrincipalNameは通常、Windows 2000以降で使用されます。

211
Harvey Kwok

Y個のアクティブなアカウントをフィルタリングする場合は、これをHarveyのコードに追加します。

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

最初の使用後。それから加えて

  searcher.QueryFilter = userPrin;

すべてを見つける前に。そして、それはあなたにアクティブなものを取得するはずです。

21
apereira

確かにクレジットはここ@Harvey Kwokに送られますが、私の場合は実際のUserPrincipalのリストを取得したかったので、この例を追加したかっただけです。このクエリを事前にフィルター処理する方がおそらく効率的ですが、私の小さな環境では、すべてを引き出して、後でリストから必要に応じてフィルター処理する方が簡単です。

必要に応じて、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());
        }
}
5
Jordan

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
FreeAsInBeer