UserPrincipal.FindByIdentity()
не может осуществлять поиск по адресу электронной почты. Поиск возможен только по одному из типов идентификаторов в IdentityType
. В вашем случае это, вероятно, совпадение по UserPrincipalName
, поэтому иногда вы найдете результаты, но не все.
Для этого я бы использовал DirectorySearcher
напрямую, то есть то, что UserPrincipal.FindByIdentity()
использует за в любом случае, но у вас больше контроля над поиском.
Вам придется искать по атрибуту proxyAddresses
. Там будут все адреса электронной почты пользователя с префиксом smtp:
(основной адрес - прописные буквы SMTP:
). Это будет выглядеть примерно так:
string[] emails = new string[]{"alias1@org.com", "fname.lname@org.com"};
string[] DOMAINS = new string[] { "DOMAIN1", "DOMAIN2"};
foreach (string email in emails)
{
string myDomain = "Not found";
for(int i=0; i<DOMAINS.Length; i++)
{
var searcher = new DirectorySearcher {
SearchRoot = new DirectoryEntry($"LDAP://{DOMAINS[i]}"),
Filter = $"(&(objectClass=user)(objectCategory=person)(proxyAddresses=smtp:{email}))",
PropertiesToLoad = { "cn" } //just put something so it doesn't return everything
};
if (searcher.FindOne() != null)
{
myDomain = DOMAINS[i];
break;
}
}
Console.WriteLine(email + " " + myDomain);
}
Если все домены, которые вы ищете, находятся в одном лесу AD, вы можете сэкономить время, выполнив один раз запрос к Глобальному каталогу, а не разделять запросы на каждый домен. Глобальный каталог хранит данные для всех доменов в лесу. Вы выбираете Глобальный каталог, используя GC://
вместо LDAP://
.
Затем вы можете запросить атрибут пользователя msDS-PrincipalName
, который будет именем пользователя в формате DOMAIN\username
, так что вы можете извлечь доменное имя из этого. Например:
string[] emails = new string[]{"alias1@org.com", "fname.lname@org.com"};
foreach (string email in emails)
{
string myDomain = "Not found";
var searcher = new DirectorySearcher {
SearchRoot = new DirectoryEntry("GC://example.com"),
Filter = $"(&(objectClass=user)(objectCategory=person)(proxyAddresses=smtp:{email}))",
PropertiesToLoad = { "msDS-PrincipalName" }
};
var found = searcher.FindOne();
if (found != null)
{
var mdDsPrincipalName = (string) found.Properties["msDS-PrincipalName"][0];
myDomain = mdDsPrincipalName.Substring(0, mdDsPrincipalName.IndexOf("\\"));
}
Console.WriteLine(email + " " + myDomain);
}
Просто замените example.com
именем любого из ваших доменов (неважно, какой).