Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用PrincipalSearcher查找带有;或;参数_C#_.net_Active Directory - Fatal编程技术网

C# 使用PrincipalSearcher查找带有;或;参数

C# 使用PrincipalSearcher查找带有;或;参数,c#,.net,active-directory,C#,.net,Active Directory,是否可以使用System.DirectoryServices.AccountManagement.PrincipalSearcher基于多个参数使用“或”(非“和”)进行搜索 i、 e 我希望使用PrincipalSearcher(而不是DirectorySearcher)进行类似的搜索(在LDAP中) FindAll方法搜索主体中指定的域 上下文,用于具有与上设置的属性相同的属性的对象 查询筛选器。FindAll方法返回与 提供的对象,而FindOne方法只返回一个 匹配主对象。 我不知道您

是否可以使用
System.DirectoryServices.AccountManagement.PrincipalSearcher
基于多个参数使用“或”(非“和”)进行搜索

i、 e

我希望使用
PrincipalSearcher
(而不是
DirectorySearcher
)进行类似的搜索(在LDAP中)

FindAll方法搜索主体中指定的域 上下文,用于具有与上设置的属性相同的属性的对象 查询筛选器。FindAll方法返回与 提供的对象,而FindOne方法只返回一个 匹配主对象。


我不知道您需要什么,但您可以按1 proprety和1 by other进行搜索,然后使用列表上的LINQ进行合并、筛选等。

这显然是不可能的,这里有一个解决方法:

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());
}
List searchPrinciples=newlist();
添加(新用户主体(上下文){DisplayName=“tom*”});
添加(新用户主体(上下文){SamAccountName=“tom*”});
添加(新用户主体(上下文){MiddleName=“tom*”});
添加(新用户主体(上下文){GivenName=“tom*”});
列表结果=新列表();
var searcher=new PrincipalSearcher();
foreach(搜索原则中的var项目)
{
搜索者=新的首席搜索者(项目);
results.AddRange(searcher.FindAll());
}

不一定像其他答案那样清晰,但下面是我在一个项目中如何实现这一点的。我希望两个搜索都异步运行,以尽量减少由于运行两个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();
}
公共异步静态任务查找器(字符串搜索字符串)
{
searchString=String.Format(“*{0}*”,searchString);
列表用户=新列表();
使用(UserPrincipal searchMaskDisplayname=newuserprincipal(domainContext){DisplayName=searchString})
使用(UserPrincipal searchMaskUsername=newuserprincipal(domainContext){SamAccountName=searchString})
使用(PrincipalSearcherDisplayName=新PrincipalSearcher(searchMaskDisplayname))
使用(PrincipalSearcherUserName=新PrincipalSearcher(searchMaskUsername))
使用(Task taskDisplayname=Task.Run(()=>searcherDisplayname.FindAll())
使用(Task taskUsername=Task.Run(()=>searcherUsername.FindAll())
{
foreach(UserPrincipal UserPrincipal in(wait taskDisplayname).Union(wait taskUsername))
使用(用户主体)
{
添加(新的成人身份(userPrincipal));
}
}
返回users.Distinct().ToList();
}
我的成人类有一个基于SID的平等性检查。我试图将
Distinct()
添加到两个搜索结果的
Union()
,但没有成功


我欢迎对我的答案提出任何建设性的批评,因为我想知道是否有任何方法可以改进它。

我知道这有点晚了,但这是我在搜索广告时使用的结构:

PrincipalContext pContext = new PrincipalContext(ContextType.Machine, Environment.MachineName);
GroupPrincipal gp = GroupPrincipal.FindByIdentity(pContext, "Administrators");
bool isMember = UserPrincipal.Current.IsMemberOf(gp);
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;
    });
}
publicstatictask GetUsers(//任何您想要的过滤器)
{
返回任务。运行(()=>
{
PrincipalContext context=新PrincipalContext(ContextType.Domain);
UserPrincipal=新的UserPrincipal(上下文);
principal.Enabled=true;
PrincipalSearcher=新PrincipalSearcher(委托人);
var users=searcher.FindAll().Cast()
.Where(x=>x.SomeProperty…//执行查询)
.Select(x=>newsomeUserModelClass
{
userName=x.SamAccountName,
email=x.UserPrincipalName,
guid=x.guid.Value
}).OrderBy(x=>x.userName).AsEnumerable();
返回用户;
});
}

是的,这是我目前使用的解决方法,我希望有一种方法可以在一次搜索中更干净地完成这项工作。谢谢。你必须用这个来处理副本。如果显示名称、给定名称和帐户名称都包含名称“tom”,那么您将有重复的名称。我也希望这样,但在多次查询时,它的性能是否会明显降低?我想知道为什么我不应该求助于DirectorySearcher如果不能使用PrincipalSearcher只返回不同的用户,那么可以使用LINQ根据标识符(例如SID)进行分组:Replace
return users.distinct().ToList()返回users.GroupBy(user=>user.Sid)。选择(group=>group.First()).ToList()在将ADUserEntity对象添加到集合之前使用简单的if语句怎么样?如果(!users.Contains(userPrincipal)users.Add(new ADUserEntity(userPrincipal));您基本上是在读取整个目录,并在客户端执行筛选。这不会扩展到任何中等大小或更大的目录。此后,在执行搜索之前,我添加了筛选到UserPrincipal对象,并将搜索范围缩小到特定的起始位置。
PrincipalContext pContext = new PrincipalContext(ContextType.Machine, Environment.MachineName);
GroupPrincipal gp = GroupPrincipal.FindByIdentity(pContext, "Administrators");
bool isMember = UserPrincipal.Current.IsMemberOf(gp);
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;
    });
}