Using PrincipalSearcher to find users with “or” parameters

前端 未结 5 1848
情歌与酒
情歌与酒 2020-12-30 20:07

Is it possible to use System.DirectoryServices.AccountManagement.PrincipalSearcher to search based on multiple parameters using \"or\" (not \"and\").

i.

相关标签:
5条回答
  • 2020-12-30 20:47

    The FindAll method searches the domain specified in the principal context for objects that have identical properties to those set on the query filter. The FindAll method returns all objects that match the supplied object whereas the FindOne method returns only a single matching principal object. http://msdn.microsoft.com/en-us/library/bb384378(v=vs.90).aspx

    I don't know what you need, but you could do a search by 1 proprety and 1 by other and then use LINQ on the lists to merge,filter and etc...

    0 讨论(0)
  • 2020-12-30 21:03

    Not necessarily as clean as some of the other answers but here is how I've implemented this in a project I'm working on. I wanted both searches to be run async to try and reduce any slow down due to running two AD queries.

    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();
    }
    

    My ADUserEntity class has an equality check based on the SID. I tried to add the Distinct() on to the Union() of the two searcher results but that didn't work.

    I welcome any constructive criticism on my answer as I'd like to know if there is any way I can improve it.

    0 讨论(0)
  • 2020-12-30 21:04

    It's obviously not possible, here is a workaround:

    List<UserPrincipal> searchPrinciples = new List<UserPrincipal>();
    searchPrinciples.Add(new UserPrincipal(context) { DisplayName="tom*"});
    searchPrinciples.Add(new UserPrincipal(context) { SamAccountName = "tom*" });
    searchPrinciples.Add(new UserPrincipal(context) { MiddleName = "tom*" });
    searchPrinciples.Add(new UserPrincipal(context) { GivenName = "tom*" });
    
    List<Principal> results = new List<Principal>();
    var searcher = new PrincipalSearcher();
    foreach (var item in searchPrinciples)
    {
        searcher = new PrincipalSearcher(item);
        results.AddRange(searcher.FindAll());
    }
    
    0 讨论(0)
  • 2020-12-30 21:04
    PrincipalContext pContext = new PrincipalContext(ContextType.Machine, Environment.MachineName);
    GroupPrincipal gp = GroupPrincipal.FindByIdentity(pContext, "Administrators");
    bool isMember = UserPrincipal.Current.IsMemberOf(gp);
    
    0 讨论(0)
  • 2020-12-30 21:05

    I know this is kind of late, but this is the construct I use when searching 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;
        });
    }
    
    0 讨论(0)
提交回复
热议问题