是否有人能够告诉我为什么以下代码块运行速度如此之慢?当我为具有少数成员的组运行它时,它运行正常,但是当我为一个拥有640个成员的组运行时,有时它会成功运行,有时它会超时。域控制器是“本地的”(即不是通过WAN链路)。我从多台机器上尝试过这种方法并得到一些一致的(不合需要的)结果。 Get-ADGroupMember应该为具有<的组快速返回结果1000名会员?我认为它会,但我在这个问题上摸不着头脑。
Import-Module ActiveDirectory
$sw = [Diagnostics.Stopwatch]::StartNew()
Get-ADGroupMember -Identity cri-all_users | measure
$sw.Stop()
$sw.Elapsed
以下是我的输出示例:
Count : 641
Average :
Sum :
Maximum :
Minimum :
Property :
Ticks : 2268358861
Days : 0
Hours : 0
Milliseconds : 835
Minutes : 3
Seconds : 46
TotalDays : 0.00262541534837963
TotalHours : 0.0630099683611111
TotalMilliseconds : 226835.8861
TotalMinutes : 3.78059810166667
TotalSeconds : 226.8358861
这是我的$ PSVERSIONTABLE
PS C:\Windows\System32\WindowsPowerShell\v1.0> echo $PSVERSIONTABLE
Name Value
---- -----
PSVersion 3.0
WSManStackVersion 3.0
SerializationVersion 1.1.0.1
CLRVersion 4.0.30319.18051
BuildVersion 6.2.9200.16628
PSCompatibleVersions {1.0, 2.0, 3.0}
PSRemotingProtocolVersion 2.2
我很感激任何人都能提供的任何见解。我已经开始尝试使用Process Explorer / Process Monitor在系统调用级别调试它并且(未成功)连接调试器,但是还没有走得太远。非常感谢你的帮助和时间。
答案 0 :(得分:2)
当运行640个成员需要3分钟时,问题可能不在于域控制器或cmdlet本身。根据您的测量结果,我们以每秒约2.8个用户的速度运行,即使是最慢的DC也可以处理。您可以通过在中等大小的组上运行来证明这不是问题,如果您击败2.8个用户/秒,那么问题不在于DC。如果你的CPU没有固定在100%......你也可以证明它。
由于您可以查看的几个原因,我已经看到这个问题突然出现了:
当您通过大型组(如域用户)进行迭代时,通常会发生这些问题,因为它们更可能导致可能导致问题的SID损坏。每个损坏的SID都会导致Get-ADGroupMember cmdlet在尝试解析SID时暂停,在超时之前等待10-30秒,然后继续。
修复是找到那些不好的SID。解决方法是获取信息的不同方法,例如使用目录搜索器:
$searchRoot = New-Object System.DirectoryServices.DirectoryEntry
$adSearcher = New-Object System.DirectoryServices.DirectorySearcher
$adSearcher.SearchRoot = $searchRoot
$adSearcher.Filter = "(cn=groupName)"
$adSearcher.PropertiesToLoad.Add("member")
$samResult = $adSearcher.FindOne()
if($samResult)
{
$adAccount = $samResult.GetDirectoryEntry()
$groupMembership = $adAccount.Properties["member"]
$groupMembership | foreach { Write-Host $_ }
}
答案 1 :(得分:1)
我只使用标准的命令行开关,在函数中打包以使其递归。比get-adgroupmember快得多,但不适用于"域用户"或其他主要群体成员。
function getmember($dn){
$obj=get-adobject $dn
if ($obj.objectclass -eq "group"){
$grp=$obj|get-adgroup -property member
$grp.member| foreach{ getmember $_ }
}else{
$dn
}
}
$dn=(get-adgroup "Participants").distinguishedname
measure-command {
$m= getmember $dn
}
measure-command {
get-adgroupmember $dn -recursive|foreach{$_.distinguishedname}
}