PowerCLI 遍历集群和主机

PowerCLI to walk through clusters and hosts

这是我正在尝试做的事情:我有一个包含多个集群的 vSphere 设置,在这些集群下面有一些主机。

我正在尝试编写一个遍历集群和每个集群内部的脚本,将主机置于维护模式,将其移出集群,start/stop 一个虚拟机,为其添加内存,然后移动主机回到它被移出的集群中。

这是我目前所拥有的。内部循环有效,但外部循环只是使所有内容 运行 两次并在内部循环中将集群名称添加为 $cluster

有什么想法吗?我只希望每个集群中的所有主机的内部循环为 运行。

我添加了 -WhatIf 用于测试,您可以忽略这些。

Connect-VIServer vcenter01

$clusters = Get-Cluster
$esxhosts = Get-Cluster $clusters | Get-VMHost
$Datacenter = "Datacenter01"
$sleep = 1

& {
    foreach ($cluster in $clusters) {
        foreach ($esxhost in $esxhosts) {
            Set-VMHost $esxhost -State Maintenance -WhatIf
            Move-VMhost $esxhost -Destination $Datacenter -WhatIf
            Set-VMHost $esxhost -State Connected -WhatIf
            Sleep $sleep
            Stop-VMGuest -Vm Z-VRA-$esxhost -Confirm:$false -WhatIf
            Sleep $sleep
            Set-VM -Vm Z-VRA-$esxhost -MemoryGB 6 -Confirm:$false -WhatIf
            Start-VM -Vm Z-VRA-$esxhost -WhatIf
            Sleep $sleep
            Move-VMhost $esxhost -Destination $cluster -WhatIf
        }
    }
}

Disconnect-VIServer vcenter01

这是工作副本的样子(感谢@Ansgar Wiechers):

我在每个集群上的 start/stop HA 准入控制中添加了一些代码,因为它正在运行。如果资源不足,这将解决 VM 在维护模式期间腾空的问题。

Connect-VIServer vcenter01

$Datacenter = "Datacenter01"
$sleep = 1

Get-Cluster  | ForEach-Object {
$cluster = $_
Set-Cluster -HAAdmissionControlEnabled $false -Cluster $cluster -Confirm:$false -Whatif
$cluster  | Get-VMHost | ForEach-Object {
        Set-VMHost $_ -State Maintenance -WhatIf
        Move-VMhost $_ -Destination $Datacenter -WhatIf
        Set-VMHost $_ -State Connected -WhatIf
        Sleep $sleep
        Stop-VMGuest -Vm Z-VRA-$_ -Confirm:$false -WhatIf
        Sleep $sleep
        Set-VM -Vm Z-VRA-$_ -MemoryGB 6 -Confirm:$false -WhatIf
        Start-VM -Vm Z-VRA-$_ -WhatIf
        Sleep $sleep
        Move-VMhost $_ -Destination $cluster -WhatIf


    }
   Set-Cluster -HAAdmissionControlEnabled $true -Cluster $cluster Confirm:$false -Whatif
}


Disconnect-VIServer vcenter01

这条语句给你所有的簇:

$clusters = Get-Cluster

此语句为您提供所有集群的所有管理程序

$esxhosts = Get-Cluster $clusters | Get-VMHost

因为您的内部循环已经迭代了所有集群的所有管理程序,所以在外部循环中迭代集群会为每个集群重复该操作。对于两个聚类,您会得到两次结果,对于三个聚类,您会得到三次结果,依此类推。

由于内部循环中的最终操作不是集群不可知的,如果您删除小鸡开关,您的代码实际上可能会破坏某些东西。您需要枚举每个集群 的管理程序 。我无权访问 vSphere 系统,但我想像这样的东西应该可以满足您的需求:

Get-Cluster | ForEach-Object {
    $cluster = $_
    $cluster | Get-VMHost | ForEach-Object {
        Set-VMHost $_ -State Maintenance -WhatIf
        ...
        Move-VMhost $_ -Destination $cluster -WhatIf
    }
}

旁注:循环周围的 & { ... } 毫无意义。扔掉它。