PowerShell/CLI:具有多个数组的“Foreach”循环
Posted
技术标签:
【中文标题】PowerShell/CLI:具有多个数组的“Foreach”循环【英文标题】:PowerShell/CLI: "Foreach" loop with multiple arrays 【发布时间】:2014-10-01 05:50:03 【问题描述】:我有一个 PowerCLI 脚本,它可以关闭 VM、更改其内存和 cpu,然后重新打开它。我已经修改了脚本以利用变量。这一切都很完美。
我现在正在尝试修改脚本以利用数组,以便在众多虚拟机中循环。关闭和打开虚拟机电源的脚本部分完美运行。
我遇到的问题是在 foreach 循环中使用来自两个数组的变量。
对于 $vm_name 中的每个 VM,我需要设置在 $memory_gb 中找到的相应内存量。
这就是我所拥有的(它目前为所有虚拟机设置了相同数量的内存(“1”)....
$vm_name = @("OMAC-SBXWIN7AJM", "OMAC-SBXWIN2012R2AJM", "OMAC-SBXWIN2008R2AJM")
$memory_gb = 2,4,4
# SET THE VM MEMORY
Write-Host 'NOW SETTING THE VM MEMORY'
foreach ($objItem in $vm_name)
Set-VM -VM $vm_name -MemoryGB 1 -confirm:$false
Break
http://i.stack.imgur.com/E9hfY.png
...我尝试在第一个循环中嵌套第二个 foreach 循环,但无济于事。
如何编写脚本让 $vm_name 中的每个 VM 获取在 $memory_gb 中找到的相应内存量?
【问题讨论】:
【参考方案1】:您可以使用 Zip 功能:
function Zip($a1, $a2)
while ($a1)
$x, $a1 = $a1
$y, $a2 = $a2
[tuple]::Create($x, $y)
用法:
zip 'a','b','c' 1,2,3 |% $_.item1 + $_.item2
结果:
a1
b2
c3
【讨论】:
@js2010 为以后的读者清除它:$x, $a1 = $a1
语法是解压数组的下一个成员,而不是保留手动迭代器 $i
或类似的【参考方案2】:
您有 2 个选项。首先(不是我建议的)是一个 For() 循环。它会是这样的:
For($I=0;$I -lt $vm_name.count;$I++)
Set-VM -VM $vm_name[$I] -MemoryGB $memory_gb[$I] -confirm:$false
更好的方法是将其放入带有 VMName, Memory
之类的标头的 CSV 中,然后列出每个 VM 和您想要的内存。然后运行类似:
Import-CSV C:\Path\To\File.CSV | ForEachSet-VM -VM $_.VMName -MemoryGB $_.memory -confirm:$false
【讨论】:
将其放入数据文件中非常聪明,脱帽致敬。 这非常有效。谢谢!我肯定会使用 .CSV,因为我最终会修改许多机器。 这行得通,但我得到了这个错误.... Set-VM:无法将参数“MemoryGB”绑定到目标。异常设置“MemoryGB”:“对象引用未设置为对象的实例。”在 U:\How To\PowerCLI\Test.ps1:8 char:36 + Set-VM -VM $vm_name[$i] -MemoryGB $memory_gb[$i] -confirm:$false + ~~~~~~~ ~~~~~~~ + CategoryInfo : WriteError: (:) [Set-VM], ParameterBindingExcept ion + FullyQualifiedErrorId : ParameterBindingFailed,VMware.VimAutomation.ViCo re.Cmdlets.Commands.SetVM 既然它起作用了,那么错误真的重要吗? 这可能是因为我使用 -le 而不是 -lt 所以它试图迭代第 4 个 VM/内存集。我真的希望您使用第二个选项,所以我没有像第一个选项那样密切关注。我会尽快更新答案以纠正该问题。【参考方案3】:另一个更紧凑的解决方案是使用哈希表:
$vms = @"OMAC-SBXWIN7AJM" = 2; "OMAC-SBXWIN2012R2AJM" = 4; "OMAC-SBXWIN2008R2AJM" = 4
# SET THE VM MEMORY
Write-Host 'NOW SETTING THE VM MEMORY'
foreach ($vm in $vms.getEnumerator())
Set-VM -VM $vm.Name -MemoryGB $vm.Value -confirm:$false
【讨论】:
这也对我有用。谢谢!我没有考虑过使用哈希表。【参考方案4】:$vm_name = @("OMAC-SBXWIN7AJM", "OMAC-SBXWIN2012R2AJM", "OMAC-
SBXWIN2008R2AJM")
$memory_gb = 2,4,4
# SET THE VM MEMORY
Write-Host 'NOW SETTING THE VM MEMORY'
foreach ($objItem in $vm_name)
Set-VM -VM $vm_name -MemoryGB $memory_gb[$vm_name.indexOf($objItem)] -confirm:$false
Break
只要两个数组大小相同,这将起作用。
【讨论】:
你先生是一位绅士和学者,我无法弄清楚如何将两个数组类型变量传递给一个 foreach 循环,而不是每次都在其他数组项上执行每个数组项。所以应该运行 4 次循环的东西正在执行 16 次。但这部分救了我:[$vm_name.indexof($objItem)] Index of 是一个非常聪明的解决方案。【参考方案5】:$vm_name = @("OMAC-SBXWIN7AJM", "OMAC-SBXWIN2012R2AJM", "OMAC-SBXWIN2008R2AJM")
$memory_gb = (2,4,4)
# SET THE VM MEMORY
Write-Host 'NOW SETTING THE VM MEMORY'
for( $i = 0; $i -lt $vm_name.length; $i++)
$vm = $vm_name[$i]
$gb = $memory_gb[$i]
write-host setting $vm to $gb GB ...
Set-VM -VM $vm -MemoryGB $gb -confirm:$false
您只需要确保两个数组的长度相同。
【讨论】:
@JamesMcCallister:我很受宠若惊,但在 SO 上,感谢通常以赞成和/或接受最佳答案的形式表达 :-)以上是关于PowerShell/CLI:具有多个数组的“Foreach”循环的主要内容,如果未能解决你的问题,请参考以下文章
powershell inline 在竹子中失败,但从 windows powershell CLI 传递
知道如何使用 powershell/cli 或任何其他方式获取/查询其中创建了 Queue/table/file/blob 的存储帐户列表吗?