32

System.DirectoryServices.AccountManagement.PrincipalSearcher「and」ではなく「or」を使用して複数のパラメータに基づいて検索するために使用することは可能ですか。

すなわち

// This uses an and
//(&(objectCategory=person)(!UserAccountControl:1.2.840.113556.1.4.803:=2)(&(SAMAccountName=tom*)(DisplayName=tom*)))
var searchPrinciple = new UserPrincipal(context);
searchPrinciple.DisplayName =  "tom*";
searchPrinciple.SamAccountName = "tom*";

var searcher = new PrincipalSearcher();
searcher.QueryFilter = searchPrinciple;

var results = searcher.FindAll();

PrincipalSearcher(not DirectorySearcher)を使用して (LDAP で) これに似た検索をしたい

// (&(objectCategory=person)(!UserAccountControl:1.2.840.113556.1.4.803:=2)(|(SAMAccountName=tom*)(DisplayName=tom*)))
4

5 に答える 5

8

他のいくつかの回答ほどきれいであるとは限りませんが、私が取り組んでいるプロジェクトでこれをどのように実装したかを次に示します。2 つの AD クエリの実行によるスローダウンを減らすために、両方の検索を非同期で実行したいと考えました。

public async static Task<List<ADUserEntity>> FindUsers(String searchString)
{
    searchString = String.Format("*{0}*", searchString);
    List<ADUserEntity> users = new List<ADUserEntity>();

    using (UserPrincipal searchMaskDisplayname = new UserPrincipal(domainContext) { DisplayName = searchString })
    using (UserPrincipal searchMaskUsername = new UserPrincipal(domainContext) { SamAccountName = searchString })
    using (PrincipalSearcher searcherDisplayname = new PrincipalSearcher(searchMaskDisplayname))
    using (PrincipalSearcher searcherUsername = new PrincipalSearcher(searchMaskUsername))
    using (Task<PrincipalSearchResult<Principal>> taskDisplayname = Task.Run<PrincipalSearchResult<Principal>>(() => searcherDisplayname.FindAll()))
    using (Task<PrincipalSearchResult<Principal>> taskUsername = Task.Run<PrincipalSearchResult<Principal>>(() => searcherUsername.FindAll()))
    {
        foreach (UserPrincipal userPrincipal in (await taskDisplayname).Union(await taskUsername))
            using (userPrincipal)
            {
                users.Add(new ADUserEntity(userPrincipal));
            }
    }

    return users.Distinct().ToList();
}

私の ADUserEntity クラスには、SID に基づく等価性チェックがあります。Distinct()2 つの検索結果のに onを追加しようとしましUnion()たが、うまくいきませんでした。

改善できる方法があるかどうか知りたいので、私の回答に対する建設的な批判を歓迎します。

于 2014-07-22T17:05:01.567 に答える
3

これはちょっと遅いことはわかっていますが、これは AD を検索するときに使用する構成です。

public static Task<IEnumerable<SomeUserModelClass>> GetUsers(//Whatever filters you want)
{
    return Task.Run(() =>
    {
        PrincipalContext context = new PrincipalContext(ContextType.Domain);
        UserPrincipal principal = new UserPrincipal(context);
        principal.Enabled = true;
        PrincipalSearcher searcher = new PrincipalSearcher(principal);

        var users = searcher.FindAll().Cast<UserPrincipal>()
            .Where(x => x.SomeProperty... // Perform queries)
            .Select(x => new SomeUserModelClass
            {
                userName = x.SamAccountName,
                email = x.UserPrincipalName,
                guid = x.Guid.Value
            }).OrderBy(x => x.userName).AsEnumerable();

        return users;
    });
}
于 2016-06-09T11:54:22.440 に答える
-3

FindAll メソッドは、プリンシパル コンテキストで指定されたドメインを検索して、クエリ フィルタで設定されたプロパティと同一のプロパティを持つオブジェクトを探します。FindAll メソッドは、指定されたオブジェクトに一致するすべてのオブジェクトを返しますが、FindOne メソッドは、一致するプリンシパル オブジェクトを 1 つだけ返します。 http://msdn.microsoft.com/en-us/library/bb384378(v=vs.90).aspx

何が必要なのかわかりませんが、1つのプロパティで検索し、1つのプロパティで検索してから、リストでLINQを使用してマージ、フィルタリングなどを行うことができます...

于 2012-05-15T18:12:49.003 に答える