Я пытаюсь получить все прямые отчеты пользователя через Active Directory, рекурсивно. Таким образом, для пользователя я получаю список всех пользователей, у которых есть это лицо в качестве менеджера, или у кого есть лицо в качестве менеджера, у которого есть лицо в качестве менеджера ... у которого в конечном итоге есть пользователь ввода в качестве менеджера.Получение всех прямых отчетов из Active Directory
Моя текущая попытка довольно медленно:
private static Collection<string> GetDirectReportsInternal(string userDN, out long elapsedTime)
{
Collection<string> result = new Collection<string>();
Collection<string> reports = new Collection<string>();
Stopwatch sw = new Stopwatch();
sw.Start();
long allSubElapsed = 0;
string principalname = string.Empty;
using (DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}",userDN)))
{
using (DirectorySearcher ds = new DirectorySearcher(directoryEntry))
{
ds.SearchScope = SearchScope.Subtree;
ds.PropertiesToLoad.Clear();
ds.PropertiesToLoad.Add("directReports");
ds.PropertiesToLoad.Add("userPrincipalName");
ds.PageSize = 10;
ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
SearchResult sr = ds.FindOne();
if (sr != null)
{
principalname = (string)sr.Properties["userPrincipalName"][0];
foreach (string s in sr.Properties["directReports"])
{
reports.Add(s);
}
}
}
}
if (!string.IsNullOrEmpty(principalname))
{
result.Add(principalname);
}
foreach (string s in reports)
{
long subElapsed = 0;
Collection<string> subResult = GetDirectReportsInternal(s, out subElapsed);
allSubElapsed += subElapsed;
foreach (string s2 in subResult)
{
result.Add(s2);
}
}
sw.Stop();
elapsedTime = sw.ElapsedMilliseconds + allSubElapsed;
return result;
}
По существу, эта функция принимает различающееся имя в качестве входных данных (CN = Michael Штум, OU = тест, DC = юг, DC = домен, DC = COM) , и при этом вызов ds.FindOne() выполняется медленно.
Я обнаружил, что поиск слова userPrincipalName намного быстрее. Моя проблема: sr.Properties ["directReports"] - это всего лишь список строк, и это выдающееся имя, которое кажется медленным для поиска.
Интересно, есть ли быстрый способ конвертировать между выдающимся именем и userPrincipalName? Или существует более быстрый способ поиска пользователя, если у меня есть только имя выдающегося?
Редактировать: Спасибо! Поиск в поле «Менеджер» улучшил функцию с 90 секунд до 4 секунд. Вот новый и улучшенный код, который быстрее и более удобным для чтения (обратите внимание, что, скорее всего, ошибка в функциональности ElapsedTime, но фактическое ядро функции работы):
private static Collection<string> GetDirectReportsInternal(string ldapBase, string userDN, out long elapsedTime)
{
Collection<string> result = new Collection<string>();
Stopwatch sw = new Stopwatch();
sw.Start();
string principalname = string.Empty;
using (DirectoryEntry directoryEntry = new DirectoryEntry(ldapBase))
{
using (DirectorySearcher ds = new DirectorySearcher(directoryEntry))
{
ds.SearchScope = SearchScope.Subtree;
ds.PropertiesToLoad.Clear();
ds.PropertiesToLoad.Add("userPrincipalName");
ds.PropertiesToLoad.Add("distinguishedName");
ds.PageSize = 10;
ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
ds.Filter = string.Format("(&(objectCategory=user)(manager={0}))",userDN);
using (SearchResultCollection src = ds.FindAll())
{
Collection<string> tmp = null;
long subElapsed = 0;
foreach (SearchResult sr in src)
{
result.Add((string)sr.Properties["userPrincipalName"][0]);
tmp = GetDirectReportsInternal(ldapBase, (string)sr.Properties["distinguishedName"][0], out subElapsed);
foreach (string s in tmp)
{
result.Add(s);
}
}
}
}
}
sw.Stop();
elapsedTime = sw.ElapsedMilliseconds;
return result;
}
Вы можете получить дополнительную скорость, выбирая DirectoryEntry и DirectorySearcher из рекурсии. Они не меняются между ними, не так ли? – Tomalak 2008-10-10 09:35:19
Больше нет. То, что я не сказал: я использую это в среде Sharepoint, где вызов завернут в вызов SPSecurity.RunWithElevatedPrivileges, что означает, что ref Параметры невозможны, и я не уверен, что передача его как нормального параметра работает (странно Sharepoint Security) – 2008-10-10 09:59:31