PowerCLI遍历集群和主机

时间:2017-05-03 19:00:00

标签: powershell vmware powercli

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

我正在尝试编写一个脚本,遍历群集并在每个群集内部,将主机置于维护模式,将其移出群集,启动/停止VM,向其添加内存,然后将主机移回它被移出的集群。

这是我到目前为止所拥有的。内部循环起作用,但外部循环只是使所有内容运行两次并在内部循环中将集群名称添加为$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):

我添加了一些代码来启动/停止每个群集上的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

1 个答案:

答案 0 :(得分:1)

此语句为您提供所有群集:

$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
    }
}

旁注:你的循环周围的& { ... }毫无意义。放下它。