关于多个集合的 Powershell foreach

Powershell foreach regarding multiple collections

所以我有一个正在使用的 Powershell 脚本,我想寻求社区的帮助。我必须预先说明,我并不总是最擅长传达我正在尝试做的事情,部分原因是我没有编程经验,所以请耐心等待,如果我用不正确的词来解释我的意思,请问 questions/correct 我均值。

话虽如此,这就是我想要做的事情:

同时递增服务和启动类型:

所以假设 $services 有:
bits appmgmt

$startuptypes 有:

Automatic Manual

我希望分别应用它们(位 > 自动 appmgmt > 手动)

这是我目前所拥有的:

$services = Get-Content "C:\TEMP\services.txt"
$Startuptypes = Get-Content "C:\TEMP\StartupTypes.txt"
$RebootingServer = Read-Host 'Name of the server that you are bringing down'
$FailoverServer = Read-Host 'Name of the server it is failing over to'


#foreach ($service in $services && $Startuptype in $Startuptypes) {

Invoke-Command -ComputerName $RebootingServer -ArgumentList $service - ScriptBlock {param($service) Stop-Service $service}
Start-Sleep -s 3
Invoke-Command -ComputerName $RebootingServer -ArgumentList $service - ScriptBlock {param($service) set-service $service -StartupType Disabled}
Start-Sleep -s 10
Invoke-Command -ComputerName $FailoverServer -ArgumentList $service $StartupType -ScriptBlock {param($service,$startuptype) Set-Service $service -StartupType $startuptype}
Start-Sleep -s 3
Invoke-Command -ComputerName $FailoverServer -ArgumentList $service - ScriptBlock {param($service) Start-Service $service}
Start-sleep -s 10
}

'for each' 语句是我希望它执行的操作的伪代码,但不确定它是否存在或如何相应地编写它。我什至不知道应该怎么称呼它。多个条件?除此之外,我将如何正确地写下我想要完成的事情?感谢您提供任何帮助。

听起来你想枚举对应对中2个集合的元素:在迭代1中,处理集合中的元素1 A 以及集合 B 中的元素 1,...

PowerShell 6- 解决方案:

# Sample collections.
# Note that their counts must match.
$services     = 'serviceA', 'serviceB', 'serviceC'
$startupTypes = 'automatic', 'manual', 'disabled '


$i = 0 # helper index var.
foreach ($service in $services) { # enumerate $services directly

   # Using the index variable, find the corresponding element from 
   # the 2nd collection, $startupTypes, then increment the index.
   $startupType = $startupTypes[$i++]

   # Now process $service and $startupType as needed.
}

PowerShell 7+ 解决方案:

PowerShell 7 基于 .NET Core 3.1 构建,其中 System.Linq.Enumerable.Zip 具有 returns(2 元素) 元组 的重载,这简化了解决方案:

  • 警告:对于不同大小的输入集合,一旦较小的集合有 运行 个项目,枚举就会停止。
# Sample collections.
# Note: Due to use of [Linq.Enumerable]::Zip() below:
#  * The element counts need *not* match, because pairing stops 
#    once the shorter collection has run out of elements.
#  * However, note that strongly typed type constraint ([string[]]),
#    which is required for PowerShell to find the right [Linq.Enumerable]::Zip()
#    method overload. You can also *cast* on demand. 
[string[]] $services     = 'serviceA', 'serviceB', 'serviceC'
[string[]] $startupTypes = 'automatic', 'manual', 'disabled '

# Enumerate the collection in pairs (2-element tuples).
# Note that the tuple elements are always named .Item1 and .Item2.
[Linq.Enumerable]::Zip($services, $startupTypes) | ForEach-Object {
  "service: {0}; startup type: {1}" -f $_.Item1, $_.Item2 
}

一般来说,请注意,从 7.0 开始,PowerShell 不支持 .NET 扩展方法(这就是为什么此处需要显式使用 [System.Linq.Enumerable])以及缺少对调用 通用方法 的全面支持,尽管 GitHub 上有功能请求 - 请参阅 here and here

以上结果:

service: serviceA; startup type: automatic
service: serviceB; startup type: manual
service: serviceC; startup type: disabled