![](/img/trans.png)
[英]How to find a UserPrincipal where a property is not set using a PrincipalSearcher?
[英]Using PrincipalSearcher to find users with “or” parameters
是否可以使用System.DirectoryServices.AccountManagement.PrincipalSearcher
使用“或”(不是“和”)基於多個參數進行搜索。
即
// 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
(而不是DirectorySearcher
)進行類似的搜索(在LDAP中)
// (&(objectCategory=person)(!UserAccountControl:1.2.840.113556.1.4.803:=2)(|(SAMAccountName=tom*)(DisplayName=tom*)))
這顯然是不可能的,這是一個解決方法:
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());
}
不一定像其他一些答案一樣干凈,但這里是我在我正在研究的項目中實現這一點的方法。 我希望兩個搜索都運行異步,以嘗試減少由於運行兩個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()
添加到兩個搜索器結果的Union()
上但是沒有用。
我歡迎對我的答案提出任何建設性的批評,因為我想知道是否有任何方法可以改進它。
我知道這有點晚了,但這是我在搜索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;
});
}
FindAll方法在主體上下文中指定的域中搜索具有與查詢過濾器上設置的屬性相同的屬性的對象 。 FindAll方法返回與提供的對象匹配的所有對象,而FindOne方法僅返回單個匹配的主體對象。 http://msdn.microsoft.com/en-us/library/bb384378(v=vs.90).aspx
我不知道你需要什么,但你可以通過1 proprety和1 by other進行搜索,然后使用列表上的LINQ進行合並,過濾等...
PrincipalContext pContext = new PrincipalContext(ContextType.Machine, Environment.MachineName);
GroupPrincipal gp = GroupPrincipal.FindByIdentity(pContext, "Administrators");
bool isMember = UserPrincipal.Current.IsMemberOf(gp);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.