问题描述
我正在开发一种工具,该工具可以快速运行 csv 并在 AD 中搜索提供的相关信息 我制作了一个 gui,可以让用户将 CSV 的标题与 AD 搜索方法对齐
我目前的主要问题是在 AD 中搜索 EmailAddress 变量时经常遇到错误 “与处理请求的目录的连接不可用。这可能是暂时的情况。”
及其在选择条目上的错误 限制在任一时间运行的 powershell 作业的数量似乎有助于解决此问题 但并没有完全消除它
这是我目前正在使用的
$maxConcurrentJobs=15
$CheckBlock = {
param ($User)
Try { Get-ADUser -Filter { EmailAddress -eq $User } -Properties SamAccountName,EmployeeID,EmailAddress }
Catch { Return "$User - $_" }
}
$Array.($listBox_Columns.SelectedItem) | ForEach-Object{
$Check = $false
while ($Check -eq $false)
{
if ((Get-Job -State 'Running').Count -lt $maxConcurrentJobs)
{
Write-Host "Processing EmailAddress $_"
Start-Job -ScriptBlock $CheckBlock -ArgumentList $_
$Check = $true
}
}
}
解决方法
我建议移动到 -LDAPFilter
,如下所示:
Get-ADUser -LDAPFilter "(mail=$User)" -Properties SamAccountName,EmployeeID,EmailAddress
并以此为基础构建,最佳选择是一次搜索,一次性获得所有用户。这也可以通过 -LDAPFilter
完成,但需要做更多的工作。
$mails = $listbox_Columns.SelectedItem # this should be an array of email addresses
$filter = $mails -join ')(mail='
Get-ADUser -LDAPFilter "(|(mail=$filter))" -Properties SamAccountName,EmailAddress
此时您很有可能不再需要将其分配到许多作业中,这已经非常有效了。
第二个代码示例中发生了什么:
$mails -join ')(mail='
与 (|(mail=$filter))
一起以 (|(mail=A)(mail=B)(mail=C))
等形式创建 LDAP 搜索表达式,这将在一轮服务器中为您提供所有匹配的对象(但没有其他对象) -旅行。
当然,您需要熟悉 LDAP 搜索过滤器语法并查看 AD 中的原始 LDAP 属性值才能有效地使用它,但对于它提供的性能提升而言,这是一个很小的代价。
,很抱歉,这不适合发表评论,但我一直在观看此讨论,目的是要插话。
虽然我很难引用参考文献,但我知道 -Filter
参数在客户端上由 AD cmdlet 解释/转换为 LDAP 查询-side,然后作为 LDAP 查询字符串转发到服务器。
这可以通过在执行 -Filter
查询的 DC 上增加 NTDS 日志记录以查看记录的内容来证明,我敢打赌这将是翻译后的 LDAP 查询。此外,这是有道理的,因为 AFAIK AD LDAP(非接口)无法回答任何其他类型的查询。我打算使用这种方法仔细检查是我延迟参与的原因。
多年来,我反复测试了 -Filter
和 -LDAPFilter
之间的性能,并反复发现在任一方向摆动的极其微小的差异。鉴于一般性能可变性,我的结论是几乎没有区别!虽然我们可以假设在解释 -Filter
参数时涉及一些开销,但它可能最小到无法检测到的程度。包括在该开销中,可以查询“已启用”等计算属性。 Get-ADUser
返回的该属性可能是 UserAccountControl 的按位解释,但仍可以使用 -Filter
进行查询。关于它和其他属性/属性存在一些争论,但我个人可以证明它的可靠性,并在其他 SO 讨论中提到过。
注意:对于更复杂的查询,这些结果可能会有所不同。但是,随着复杂性的增加,人们可能会出于其他更直接的原因使用 -LDAPQuery
。
我目前找不到这些讨论,但我会尝试更新此笔记。我知道我得出了类似的结论,并对 @mklement0 的一个答案发表了评论,他将我引向了 @tomolak 的其中一个,我在那里记录了类似的评论。
我也早就认识到,针对广泛需求的广泛单一查询比多次重新运行 Get-*
快得多。在合理范围内,这似乎是普遍的,而不是特定于 AD cmdlet。如果我需要检查用户是否存在数千次,首先加载所有用户的列表要快得多,然后检查列表比运行 Get-ADUser
多次。当然,如果我只需要检查几个用户,公式可能会向另一个方向摆动。这种坚定的观察可能是代码加速的原因,而不是 -Filter
和 -LDAPFilter
之间的任何区别。
根据我的经验,-LDAPFilter
的真正用例是某些属性无法通过 -Filter
查询。这可能是由于缺少给定属性的 Filter > LDAPFilter 转换。所以,我能给出和我采用的最好的建议是使用 -Filter
直到你不能,并在你需要时切换到 -LDAPFilter
。我不能排除其他用例,也许是不同 AD cmdlet 之间查询字符串的可移植性?尽管如此,如果您一般或特别熟悉 LDAP 查询,那么使用它们肯定不会造成功能上的损害。