foreach - 与 powershell 7 并行
foreach -parallel with powershell 7
我正在努力解决以下问题。我正在尝试从我们的 2016 年终端服务器接收当前安装的边缘版本。
但是当我 运行 时,powershell 下面的代码显示我安装了版本 95.0.1020.30。
$Servers = get-content C:\users\xxx\Documents\Servers.txt
$servers|foreach-object -parallel {
Get-Ciminstance -ComputerName $Servers -Class Win32_Product | where {$_.Name -Like "*Edge*"} | foreach {$_.Version}
}
现在到了有趣的部分:当我使用通常的 foreach 循环时,它会返回正确的版本。
$Servers = get-content C:\users\cma-admin\Documents\Servers.txt
foreach($server in $servers){
Get-Ciminstance -ComputerName $Server -Class Win32_Product | where {$_.Name -Like "*Edge*"} |
foreach {$_.Version}
}
我很乐意将它与“-parallel”一起使用,因为它可以更快地获取这些信息。
我确实在强大的互联网上爬了很多,但我没有发现任何特定于这个“错误”的东西。
我不太确定我是否正确使用了 foreach -parallel。
此致,
黏土
使用$servers | foreach-object -parallel { ... }
需要在脚本块内使用automatic $_
variable引用当前服务器(管道输入对象):
$servers|foreach-object -parallel {
# Note the use of $_
Get-Ciminstance -ComputerName $_ -Class Win32_Product |
where {$_.Name -Like "*Edge*"} |
foreach {$_.Version}
}
但是,不需要循环(具有并行性),因为 CIM cmdlets,例如 Get-CimInstance
, 具有并行性内置,您可以简单地通过传递一个数组[=服务器名称的 37=] 到 -ComputerName
:
Get-Ciminstance -ComputerName $servers -Class Win32_Product |
where Name -Like "*Edge*" |
foreach Version
注:上面使用了simplified syntax.
结果将不分先后出现。
您可以使用 PowerShell 装饰所有输出对象的 .PSComputerName
属性 来标识特定结果对象的来源服务器。
win32_product class 是出了名的慢,因为它会验证每个 msi。像 get-package 这样的东西会快得多,但是你需要远程 powershell。这也将 运行 并行。除非 Edge 是通过 msi 安装的,否则无论如何它都不会显示 win32_product。
invoke-command $servers { get-package *edge* | ft -a }
Name Version Source ProviderName
---- ------- ------ ------------
Microsoft Edge 96.0.1054.62 Programs
Microsoft Edge Update 1.3.153.55 Programs
Microsoft Edge WebView2 Runtime 96.0.1054.62 Programs
感谢 mklement0 发布正确答案!
我发现当我使用
$servers|foreach-object -parallel {
Get-Ciminstance -ComputerName $Servers -Class Win32_Product | where {$_.Name -Like "*Edge*"} | foreach {$_.Version}
}
它返回本地安装的 Edge 版本。
多亏了 js2010,我会用 get-package 试试看
我正在努力解决以下问题。我正在尝试从我们的 2016 年终端服务器接收当前安装的边缘版本。 但是当我 运行 时,powershell 下面的代码显示我安装了版本 95.0.1020.30。
$Servers = get-content C:\users\xxx\Documents\Servers.txt
$servers|foreach-object -parallel {
Get-Ciminstance -ComputerName $Servers -Class Win32_Product | where {$_.Name -Like "*Edge*"} | foreach {$_.Version}
}
现在到了有趣的部分:当我使用通常的 foreach 循环时,它会返回正确的版本。
$Servers = get-content C:\users\cma-admin\Documents\Servers.txt
foreach($server in $servers){
Get-Ciminstance -ComputerName $Server -Class Win32_Product | where {$_.Name -Like "*Edge*"} |
foreach {$_.Version}
}
我很乐意将它与“-parallel”一起使用,因为它可以更快地获取这些信息。 我确实在强大的互联网上爬了很多,但我没有发现任何特定于这个“错误”的东西。 我不太确定我是否正确使用了 foreach -parallel。
此致,
黏土
使用$servers | foreach-object -parallel { ... }
需要在脚本块内使用automatic $_
variable引用当前服务器(管道输入对象):
$servers|foreach-object -parallel {
# Note the use of $_
Get-Ciminstance -ComputerName $_ -Class Win32_Product |
where {$_.Name -Like "*Edge*"} |
foreach {$_.Version}
}
但是,不需要循环(具有并行性),因为 CIM cmdlets,例如 Get-CimInstance
, 具有并行性内置,您可以简单地通过传递一个数组[=服务器名称的 37=] 到 -ComputerName
:
Get-Ciminstance -ComputerName $servers -Class Win32_Product |
where Name -Like "*Edge*" |
foreach Version
注:上面使用了simplified syntax.
结果将不分先后出现。
您可以使用 PowerShell 装饰所有输出对象的 .PSComputerName
属性 来标识特定结果对象的来源服务器。
win32_product class 是出了名的慢,因为它会验证每个 msi。像 get-package 这样的东西会快得多,但是你需要远程 powershell。这也将 运行 并行。除非 Edge 是通过 msi 安装的,否则无论如何它都不会显示 win32_product。
invoke-command $servers { get-package *edge* | ft -a }
Name Version Source ProviderName
---- ------- ------ ------------
Microsoft Edge 96.0.1054.62 Programs
Microsoft Edge Update 1.3.153.55 Programs
Microsoft Edge WebView2 Runtime 96.0.1054.62 Programs
感谢 mklement0 发布正确答案! 我发现当我使用
$servers|foreach-object -parallel {
Get-Ciminstance -ComputerName $Servers -Class Win32_Product | where {$_.Name -Like "*Edge*"} | foreach {$_.Version}
}
它返回本地安装的 Edge 版本。
多亏了 js2010,我会用 get-package 试试看