我試圖通過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 =邁克爾葡萄汁,OU =測試,DC =子,DC =域,DC = COM) ,並且對此,對ds.FindOne()的調用很慢。
我發現搜索userPrincipalName的速度要快很多。我的問題:sr.Properties [「directReports」]只是一個字符串列表,這是distinguishedName,它似乎很慢搜索。
我想知道,是否有一種快速的方法來轉換distinguishedName和userPrincipalName?還是有更快的方式來搜索用戶,如果我只有distinguishedName工作?
編輯:感謝您的答案!搜索管理器字段將功能從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安全) – 2008-10-10 09:59:31