Вы не можете сделать это с UserPrincipal
, а PrincipalSearcher
позволит вам выполнять поиск только по свойствам, указанным UserPrincipal
.Вы должны использовать DirectorySearcher
напрямую (это то, что PrincipalSearcher
использует в любом случае за кадром).
Вот пример того, что вы бы сделали:
public IEnumerable<string> GetUsersWithManager(string managerDn) {
var search = new DirectorySearcher(new DirectoryEntry()) {
Filter = $"(&(objectClass=user)(manager={managerDn}))"
};
search.PropertiesToLoad.Add("distinguishedName");
using (var results = search.FindAll()) {
foreach (SearchResult result in results) {
if (result.Properties.Contains("mail")) {
yield return (string) result.Properties["distinguishedName"][0];
}
}
}
}
Параметром является distinguishedName
менеджера, и он возвращает distinguishedName
всех пользователей, у которых этот человек является их менеджером (атрибут manager
содержит DN учетной записи менеджера).Возможно, вам придется настроить его под свои нужды.
Если вам нужен объект UserPrincipal
для конечных пользователей, вы можете сделать это с помощью этого (где переменная distinguishedName
- это DN пользователя):
UserPrincipal.FindByIdentity(context, IdentityType.DistinguishedName, distinguishedName)
Имейте в виду, что атрибут manager
не проиндексирован.Так что, если это ваш единственный критерий (кроме (objectClass=user)
), тогда AD нужно искать каждого пользователя, чтобы найти совпадения.Это может или не может быть очень медленным в вашей среде.
Лично я в любом случае предпочитаю использовать DirectorySearcher
и DirectoryEntry
напрямую.Я считаю, что все пространство имен System.DirectoryServices.AccountManagement
очень медленное.Я написал статью о том, как повысить производительность, используя пространство имен System.DirectoryServices
: Active Directory: лучшая производительность