我正在查询Active Directory以获取计算机列表,并使用Invoke-Command
从每个计算机中检索数据。因为我为每台计算机调用Invoke-Command
两次 - 一次使用-FilePath
参数,一次使用-ScriptBlock
参数 - 我使用New-PSSession
为每台计算机创建一个会话时间由于要处理的计算机列表可能很长,我依赖的事实是,当将-ComputerName
参数的多个值传递给New-PSSession
cmdlet时,它会并行启动连接。
每台计算机的输出为PSObject
,其中包含对Invoke-Command
的调用结果以及有关计算机的信息;我使用-PipelineVariable
通用参数来保存管道中较早的信息。但是,我发现,在我的最后ForEach-Object
块中,$_
变量(PSSession
对象)并不总是与$computerInfo
变量匹配(管道对象存储Active Directory计算机信息);我在具有不同会话的行中$computerInfo
多次迭代获得相同的值。我插入了一些调试代码,用于说明在调用$computerInfo
之前和之后New-PSSession
的值如何不同:
$sessionOption = New-PSSessionOption -NoMachineProfile;
Get-ADComputer -Filter $computerFilter -Properties 'Description', 'OperatingSystem' `
| Where-Object -Property 'DistinguishedName' -Match -Value $DistinguishedNamePattern `
-PipelineVariable 'computerInfo' `
| Select-Object -First 10 `
| ForEach-Object {
Write-Host "Before New-PSSession: $($computerInfo.Name)";
return $_;
} `
| Select-Object -ExpandProperty 'Name' `
| New-PSSession -SessionOption $sessionOption `
| ForEach-Object {
Write-Host " After New-PSSession: $($computerInfo.Name)";
$session = $_;
try
{
New-Object -TypeName 'PSObject' -Property @{
DistinguishedName = $computerInfo.DistinguishedName;
Computer = $computerInfo.Name;
OperatingSystem = $computerInfo.OperatingSystem;
Description = $computerInfo.Description;
InvokeScriptResult1 = Invoke-Command -FilePath $scriptPath -Session $session;
InvokeScriptResult2 = Invoke-Command -ScriptBlock $scriptBlock -Session $session;
};
}
finally
{
Remove-PSSession -Session $session;
}
};
以下是一些示例控制台输出:
Before New-PSSession: COMPUTER1
Before New-PSSession: COMPUTER2
Before New-PSSession: COMPUTER3
After New-PSSession: COMPUTER3
After New-PSSession: COMPUTER3
Before New-PSSession: COMPUTER4
After New-PSSession: COMPUTER4
Before New-PSSession: COMPUTER5
Before New-PSSession: COMPUTER6
Before New-PSSession: COMPUTER7
Before New-PSSession: COMPUTER8
After New-PSSession: COMPUTER8
After New-PSSession: COMPUTER8
Before New-PSSession: COMPUTER9
After New-PSSession: COMPUTER9
Before New-PSSession: COMPUTER10
After New-PSSession: COMPUTER10
After New-PSSession: COMPUTER10
After New-PSSession: COMPUTER10
请注意,在Before New-PSSession
行中,所有十台计算机只出现一次,而在After New-PSSession
行中,计算机3,8和10是重复的,计算机是1,2,5,6和7缺失。我也尝试将-ThrottleLimit 1
传递给New-PSSession
并获得类似的结果。
我怀疑这是同步问题。由于New-PSSession
同时打开多台计算机的会话,因此每当它从管道中的早期提取计算机时,它将覆盖该计算机的$computerInfo
。在我正在进行处理的管道中,它会看到相同的$computerInfo
变量,因此当它处理输入序列中$computerInfo
之前的会话时,包含刚开始连接的任何计算机New-PSSession
至。这是一个错误吗?或者-PipelineVariable
与New-PSSession
这样的cmdlet不兼容?有没有办法可以在$_
之后立即“捕获”$computerInfo
和New-PSSession
,以便它们始终保持同步?这就是我期望-PipelineVariable
工作的方式,但似乎整个管道有一个$computerInfo
实例,而不是每个对象通过管道传递一个。
答案 0 :(得分:0)
在某些情况下,New-PSSession
可能会在其EndProcessing覆盖中输出对象。很难说如果在这种情况下发生这种情况,但要解决这个问题,请更换:
| New-PSSession -SessionOption $sessionOption `
与
| Foreach {New-PSSession -Name $_ -SessionOption $sessionOption} `