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)进行分组:Replacereturn 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;
});
}