3

以下のコードには2つの目標があります

1) 特定の AD グループに属しているユーザーのリストを取得する
2) そのグループに属するすべてのユーザーの電子メール/姓/名を取得する

両方を達成するためのより良い方法があれば、私に知らせてください。

完全な DN を取得できましたが、完全な DN から残りのデータを取得する方法がわかりません。または、この情報を取得するためのより良い方法がある場合はお知らせください。以下は私が使用しているコードですが、エラーが発生します:

The value provided for adsObject does not implement IADs.

完全な DN を使用して DirectorySearcher を実行しようとしたとき。

HashSet<string> User_Collection = new HashSet<string>();

SearchResultCollection sResults = null;
DirectoryEntry dEntryhighlevel = new DirectoryEntry("LDAP://CN=Global_Users,OU=Astrix,OU=Clients,OU=Channel,DC=astro,DC=net");
foreach (object dn in dEntryhighlevel.Properties["member"])
{
    DirectoryEntry dEntry = new DirectoryEntry(dn);
    Console.WriteLine(dn);
    DirectorySearcher dSearcher = new DirectorySearcher(dEntry);
    //filter just user objects
    dSearcher.SearchScope = SearchScope.Base;
    //dSearcher.Filter = "(&(objectClass=user)(dn="+dn+")";
    dSearcher.PageSize = 1000;
    sResults = dSearcher.FindAll();
    foreach (SearchResult sResult in sResults)
    {
        string Last_Name = sResult.Properties["sn"][0].ToString();
        string First_Name = sResult.Properties["givenname"][0].ToString();
        string Email_Address = sResult.Properties["mail"][0].ToString();
        User_Collection.Add(Last_Name + "|" + First_Name + "|" + Email_Address);
    }

速度は重要です。はい、設計どおりに HashSet を使用していないことを理解しています。

4

2 に答える 2

1

をいつも使っていSystem.DirectoryServices.AccountManagementます。

最初に目にすることの 1 つは、「利用可能な場合、Fast Concurrent Bind (FSB) 機能を使用することで、接続速度が向上します。接続キャッシュにより、使用されるポートの数が減少します。」そうは言っても、速度のためにこれに対してコードをテストしていませんが、これは自分で行う必要がありますが、これは Microsoft の新しいライブラリです。

これが私のコード例です:

// Create the context for the principal object. 
PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
                                            "fabrikam",
                                            "DC=fabrikam,DC=com");

// Create an in-memory user object to use as the query example.
GroupPrincipal u = new GroupPrincipal(ctx) {DisplayName = "Your Group Name Here"};

// Set properties on the user principal object.

// Create a PrincipalSearcher object to perform the search.
PrincipalSearcher ps = new PrincipalSearcher {QueryFilter = u};

// Tell the PrincipalSearcher what to search for.

// Run the query. The query locates users 
// that match the supplied user principal object. 
PrincipalSearchResult<Principal> results = ps.FindAll();

foreach (UserPrincipal principal in ((GroupPrincipal)results.FirstOrDefault()).Members)
{
    string email = principal.EmailAddress;
    string name = principal.Name;
    string surname = principal.Surname;
}
于 2012-06-15T18:52:30.007 に答える
0

AD でいくつかのグループのグループ メンバーシップを歩いているようです...(上記のメンバー参照からこれを推測します)

とにかく、探している API の種類を決める必要があります。あなたが今使っているものは少し低いレベルです (ただし、必要に応じてもっと低くすることもできます :))。前の答えがうまくいかないので、より高いレベルに行くことはオプションです。

コードをもう少しシェイクするには(そして、それがあなたにとって重要であると述べたようにパフォーマンスを支援します):

  • グループ メンバーシップの検索自体に使用したのと同じ接続を使用します (つまり、追加の接続/バインドはありません)。
  • ベース DN がユーザー DN、検索フィルターが (objectclass=*) で、属性が関心のある属性のみ (no *) であるベース検索を実行します。
  • ページサイズを削除できます。ページングは​​、グループ (別名ページ) で多くのオブジェクトを要求する方法ですが、ベース検索では 1 つのオブジェクトしか返されないため、実際には何もしません。
  • ベース検索結果のカウントは常に 1 である必要があります。

クロスドメインの問題にも注意してください。ドメイン 1 のドメイン ローカル タイプのグループにドメイン 2 のメンバーが含まれる 2 ドメイン フォレストでコードをテストしてください。ドメイン (または、関心のあるいくつかのプロパティがすべて GC 部分属性セットにある場合は GC...)

また、セキュリティにも留意してください。ドメイン内の一部のユーザーがこれらのプロパティにアクセスできない場合、コードは何をしますか? 上記のコードは厄介な方法で失敗します。:) これをもっと優雅に処理したいかもしれません...

お役に立てれば。〜エリック

于 2012-06-15T19:42:52.297 に答える