Powershell 7 ForEach-Object Parallel 在传递给 invoke-command 时中断自动变量
Powershell 7 ForEach-Object Parallel breaks automatic variable when passed to invoke-command
请告知,任何关于我需要做什么才能成功传递变量的见解都将不胜感激。
此操作成功,但一次对管道列表中的每个 FQDN 都起作用。我有 100 多台服务器,所以这可能比人们想象的要花更长的时间。每台服务器 1-6 秒
Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black
$FQDNs | ForEach-Object {
Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock {
$OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
Write-Output "$Using:_`: $OS"
}
}
}
如果我添加 -Parallel 参数,它会立即失败并显示以下错误。如果自动变量是我看到的 foreach-object 管道它们的唯一方式,我还应该如何给变量? (我希望这是错误的)
ForEach-Object: C:\Scripts\Checklist.ps1:53
Line |
53 | $FQDNs | ForEach-Object -Parallel {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
| The value of the using variable '$using:_' cannot be retrieved because
| it has not been set in the local session.
这是插入了 Parallel 参数的脚本,以准确显示我正在执行的操作
Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black
$FQDNs | ForEach-Object -Parallel {
Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock {
$OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
Write-Output "$Using:_`: $OS"
}
}
}
问题显然是 PowerShell 并不总是正确处理 嵌套上下文 ,在这种情况下,因为添加 -Parallel
参数会创建一个独立的 运行space 每个脚本块实例 运行 并行,$Using:
现在评估那个 运行space 上下文而不是以前执行它的远程会话上下文 没有参数。
如果交替使用 Invoke-Command
和 -ThrottleLimit
以及传入 -ComputerName
的计算机名称数组以利用并行性而不是 ForEach-Object
与 -Parallel
.
要解决此问题,请尝试使用 [scriptblock]::Create()
构建您的脚本块,以便遵循正确的上下文,如 中所述。
Invoke-command computername comp1,comp2,comp3 已经并行运行。
# elevated prompt
start-service winrm
invoke-command localhost,localhost,localhost { sleep 10 }
(get-history)[-1] | fl
Id : 3
CommandLine : invoke-command localhost,localhost,localhost { sleep 10 }
ExecutionStatus : Completed
StartExecutionTime : 6/19/2020 10:05:02 AM
EndExecutionTime : 6/19/2020 10:05:13 AM # 11 seconds for all three
请告知,任何关于我需要做什么才能成功传递变量的见解都将不胜感激。
此操作成功,但一次对管道列表中的每个 FQDN 都起作用。我有 100 多台服务器,所以这可能比人们想象的要花更长的时间。每台服务器 1-6 秒
Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black
$FQDNs | ForEach-Object {
Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock {
$OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
Write-Output "$Using:_`: $OS"
}
}
}
如果我添加 -Parallel 参数,它会立即失败并显示以下错误。如果自动变量是我看到的 foreach-object 管道它们的唯一方式,我还应该如何给变量? (我希望这是错误的)
ForEach-Object: C:\Scripts\Checklist.ps1:53
Line |
53 | $FQDNs | ForEach-Object -Parallel {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
| The value of the using variable '$using:_' cannot be retrieved because
| it has not been set in the local session.
这是插入了 Parallel 参数的脚本,以准确显示我正在执行的操作
Write-Host "Confirm correct OS is installed" -ForegroundColor Yellow -BackgroundColor Black
$FQDNs | ForEach-Object -Parallel {
Invoke-Command -ComputerName $_ -Credential $Credentials -ScriptBlock {
$OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
Write-Host "$Using:_`: $OS" -ForegroundColor Green -BackgroundColor Black
Write-Output "$Using:_`: $OS"
}
}
}
问题显然是 PowerShell 并不总是正确处理 嵌套上下文 ,在这种情况下,因为添加 -Parallel
参数会创建一个独立的 运行space 每个脚本块实例 运行 并行,$Using:
现在评估那个 运行space 上下文而不是以前执行它的远程会话上下文 没有参数。
如果交替使用 Invoke-Command
和 -ThrottleLimit
以及传入 -ComputerName
的计算机名称数组以利用并行性而不是 ForEach-Object
与 -Parallel
.
要解决此问题,请尝试使用 [scriptblock]::Create()
构建您的脚本块,以便遵循正确的上下文,如
Invoke-command computername comp1,comp2,comp3 已经并行运行。
# elevated prompt
start-service winrm
invoke-command localhost,localhost,localhost { sleep 10 }
(get-history)[-1] | fl
Id : 3
CommandLine : invoke-command localhost,localhost,localhost { sleep 10 }
ExecutionStatus : Completed
StartExecutionTime : 6/19/2020 10:05:02 AM
EndExecutionTime : 6/19/2020 10:05:13 AM # 11 seconds for all three