Powershell |加速在Powershell作业中运行Get-ADUser



我正在开发一个工具,该工具可以快速运行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
}
}
}

很抱歉,这不适合发表评论,但我一直在关注这场讨论,目的是插话。

虽然我很难引用引用,但众所周知,-Filter参数由客户端的ADcmdlet解释/转换为LDAP查询,然后作为LDAP查询字符串转发到服务器。

这可以通过在执行-Filter查询的DC上增加NTDS日志来证明,我敢打赌这将是转换后的LDAP查询。此外,这是理所当然的,因为AFAIK AD LDAP(无接口(无法回答任何其他类型的查询。我打算使用这种方法进行双重检查,这是我延迟参与的原因。

多年来,我反复测试了-Filter&CCD_ 4,并反复出现在任一方向上摆动的极窄差异。考虑到总体性能的可变性,我的结论是几乎没有区别!虽然我们可以假设在解释-Filter自变量时会涉及一些开销,但它可能是最小的,以至于无法检测到。包括在该开销中的是查询计算的属性的能力;启用";。Get-ADUser返回的属性很可能是UserAccountControl的逐位解释,但它可以用-Filter查询。关于这一点和其他属性/属性,有一些争论,但我可以亲自证明它的可靠性,并在其他SO讨论中提到过它。

注意:对于更复杂的查询,这些结果可能会有所不同。然而,复杂性的增加可能会导致人们出于其他更直接的原因使用-LDAPQuery

我目前找不到这些讨论,但我会在找到时尝试更新这篇笔记。我知道我得出了类似的结论,并对@mkulement0的一个答案发表了评论,他将我引导到了@tomolak的一个回答,我在那里记录了类似的评论。

我早就认识到,针对广泛需求的广义奇异查询比多次重新运行Get-*要快得多。在合理的范围内,这似乎是通用的,而不是特定于AD cmdlet。如果我需要检查一个用户是否存在数千次,那么首先加载所有用户的列表,然后检查列表比多次运行Get-ADUser要快得多。当然,如果我只需要检查少数用户,公式可能会朝着另一个方向发展。这种坚定的观察可能是代码加速的原因,而不是-Filter-LDAPFilter之间的任何差异。

根据我的经验,-LDAPFilter的真实用例是当某些属性不能用-Filter查询时。这可能是由于缺少Filter>给定属性的LDAFilter转换。因此,我能给出的最好的建议和我所采用的建议是使用-Filter,直到你做不到为止,并在你需要时切换到-LDAPFilter。我不能排除其他用例,也许是不同AD cmdlet之间查询字符串的可移植性?尽管如此,如果您对LDAP查询总体上或具体来说都很满意,那么使用它们肯定不会对功能造成损害。

我建议移动到-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属性值才能有效地使用它,但这对于它提供的性能提升来说是一个很小的代价。

最新更新