电源壳 |在 Powershell 作业中加速 运行 Get-ADUser
Powershell | Speed up Running Get-ADUser in Powershell jobs
我正在开发一种工具,可以通过 csv 快速 运行 并在 AD 中搜索所提供的相关信息
我制作了一个图形用户界面,可以让用户将 CSV 的 header 与 AD 搜索方法
对齐
我目前的主要问题是在 AD 中搜索 EmailAddress 变量时,我经常遇到错误
“与用于处理请求的目录的连接不可用。这可能是暂时的情况。”
及其在 select 条目上的错误
在任何时候限制 powershell 作业的数量 运行ning 似乎有助于解决这个问题
但并没有完全消除它
这是我目前正在使用的东西
$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, EmployeeID, EmailAddress
此时您很有可能不再需要将其分配给许多作业,这已经非常高效了。
第二个代码示例中发生了什么:
$mails -join ')(mail='
与 (|(mail=$filter))
一起以 (|(mail=A)(mail=B)(mail=C))
等形式创建一个 LDAP 搜索表达式,这将为您提供所有匹配的对象(但没有别的)服务器往返。
当然,您需要熟悉 LDAP 搜索过滤器语法并查看 AD 中的原始 LDAP 属性 值才能有效地使用它,但这是为它提供的性能提升。
很抱歉,这不适合发表评论,但我一直在观看这个讨论,目的是插话。
虽然我很难引用参考文献,但我知道 -Filter
参数是 interpreted/translated 通过 AD[=43 进入 LDAP 查询=] cmdlet,在客户端,然后作为 LDAP 查询字符串转发到服务器。
这可以通过在 DC 上执行 -Filter
查询以查看记录的内容来提高 NTDS 日志记录来证明,我敢打赌它将是转换后的 LDAP 查询。此外,这是有道理的,因为 AFAIK AD LDAP(非接口)无法回答任何其他类型的查询。我打算使用这种方法仔细检查是我延迟参与的原因。
多年来,我反复测试了 -Filter
和 -LDAPFilter
之间的性能,并反复得出在任一方向摆动的极小差异。鉴于一般的性能可变性,我的结论是几乎没有区别!虽然我们可以假设 -Filter
参数的解释涉及一些开销,但它可能最小到无法检测到的程度。包括在该开销中的是查询计算属性(如“已启用”)的能力。 Get-ADUser
返回的 属性 可能是 UserAccountControl 的按位解释,但是可以使用 -Filter
查询它。关于那个和其他 properties/attributes 存在一些争论,但我可以亲自证明它的可靠性并在其他 SO 讨论中提到过它。
注意:对于更复杂的查询,这些结果可能会有所不同。但是,增加的复杂性可能会导致人们出于其他更直接的原因使用 -LDAPQuery
。
我目前找不到这些讨论,但我会尝试更新此注释。我知道我得出了类似的结论并评论了@mklement0 的一个答案,他将我带到了@tomolak 的一个答案,我在其中记录了类似的评论。
我也早就认识到,针对广泛需求的广泛单一查询比重新运行多次 Get-*
快得多。在某种程度上,这似乎是普遍的,而不是特定于 AD cmdlet。如果我需要检查用户是否存在数千次,首先加载所有用户的列表,然后检查列表比 运行 Get-ADUser
快得多。当然,如果我只需要检查几个用户,公式可能会转向另一个方向。这种坚定的观察可能是代码加速的原因,-Filter
和 -LDAPFilter
.
之间没有任何区别
根据我的经验,-LDAPFilter
的真正用例是当某些属性无法使用 -Filter
查询时。这可能是由于给定 属性 缺少 Filter > LDAPFilter 转换。所以,我能给出的最好的建议是使用 -Filter
直到你不能,然后在需要时切换到 -LDAPFilter
。我不能排除其他用例,也许是不同 AD cmdlet 之间查询字符串的可移植性?尽管如此,如果您对 LDAP 查询一般或具体感到满意,那么使用它们肯定不会造成功能上的损害。
我正在开发一种工具,可以通过 csv 快速 运行 并在 AD 中搜索所提供的相关信息 我制作了一个图形用户界面,可以让用户将 CSV 的 header 与 AD 搜索方法
对齐我目前的主要问题是在 AD 中搜索 EmailAddress 变量时,我经常遇到错误 “与用于处理请求的目录的连接不可用。这可能是暂时的情况。”
及其在 select 条目上的错误 在任何时候限制 powershell 作业的数量 运行ning 似乎有助于解决这个问题 但并没有完全消除它
这是我目前正在使用的东西
$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, EmployeeID, EmailAddress
此时您很有可能不再需要将其分配给许多作业,这已经非常高效了。
第二个代码示例中发生了什么:
$mails -join ')(mail='
与 (|(mail=$filter))
一起以 (|(mail=A)(mail=B)(mail=C))
等形式创建一个 LDAP 搜索表达式,这将为您提供所有匹配的对象(但没有别的)服务器往返。
当然,您需要熟悉 LDAP 搜索过滤器语法并查看 AD 中的原始 LDAP 属性 值才能有效地使用它,但这是为它提供的性能提升。
很抱歉,这不适合发表评论,但我一直在观看这个讨论,目的是插话。
虽然我很难引用参考文献,但我知道 -Filter
参数是 interpreted/translated 通过 AD[=43 进入 LDAP 查询=] cmdlet,在客户端,然后作为 LDAP 查询字符串转发到服务器。
这可以通过在 DC 上执行 -Filter
查询以查看记录的内容来提高 NTDS 日志记录来证明,我敢打赌它将是转换后的 LDAP 查询。此外,这是有道理的,因为 AFAIK AD LDAP(非接口)无法回答任何其他类型的查询。我打算使用这种方法仔细检查是我延迟参与的原因。
多年来,我反复测试了 -Filter
和 -LDAPFilter
之间的性能,并反复得出在任一方向摆动的极小差异。鉴于一般的性能可变性,我的结论是几乎没有区别!虽然我们可以假设 -Filter
参数的解释涉及一些开销,但它可能最小到无法检测到的程度。包括在该开销中的是查询计算属性(如“已启用”)的能力。 Get-ADUser
返回的 属性 可能是 UserAccountControl 的按位解释,但是可以使用 -Filter
查询它。关于那个和其他 properties/attributes 存在一些争论,但我可以亲自证明它的可靠性并在其他 SO 讨论中提到过它。
注意:对于更复杂的查询,这些结果可能会有所不同。但是,增加的复杂性可能会导致人们出于其他更直接的原因使用 -LDAPQuery
。
我目前找不到这些讨论,但我会尝试更新此注释。我知道我得出了类似的结论并评论了@mklement0 的一个答案,他将我带到了@tomolak 的一个答案,我在其中记录了类似的评论。
我也早就认识到,针对广泛需求的广泛单一查询比重新运行多次 Get-*
快得多。在某种程度上,这似乎是普遍的,而不是特定于 AD cmdlet。如果我需要检查用户是否存在数千次,首先加载所有用户的列表,然后检查列表比 运行 Get-ADUser
快得多。当然,如果我只需要检查几个用户,公式可能会转向另一个方向。这种坚定的观察可能是代码加速的原因,-Filter
和 -LDAPFilter
.
根据我的经验,-LDAPFilter
的真正用例是当某些属性无法使用 -Filter
查询时。这可能是由于给定 属性 缺少 Filter > LDAPFilter 转换。所以,我能给出的最好的建议是使用 -Filter
直到你不能,然后在需要时切换到 -LDAPFilter
。我不能排除其他用例,也许是不同 AD cmdlet 之间查询字符串的可移植性?尽管如此,如果您对 LDAP 查询一般或具体感到满意,那么使用它们肯定不会造成功能上的损害。