Powershell / PowerCLI循环,超时和退出

时间:2017-03-07 04:15:13

标签: loops powershell timeout powercli

以下是方案 - 我通过Powershell / PowerCLI(VMwares Powershell模块)远程启动VM,一旦VM启动,我将运行一系列针对VM的cmdlet。

目前我有这段代码:

SELECT t1.Id,
       t1.Sender,
       t1.Receiver,
       t2.username AS NAME
FROM conversation t1
INNER JOIN users t2
    ON t2.id = CASE WHEN t1.Sender = 1   THEN t1.Receiver
                    WHEN t1.Receiver = 1 THEN t1.Sender END
WHERE t1.Sender = 1 OR
      t1.Receiver = 1

哪个有效 - 虚拟机启动,循环将检查,直到VMware Tools向VMware报告(这意味着虚拟机已完全启动到操作系统)。

然而,这将无限期地运行,因此在VM无法成功启动的情况下 - 脚本挂起。所以我试图添加一个计时器来退出脚本,如果它运行5分钟后通过:

Start-VM "my VM Name" -runAsync
$vm = Get-VM | where { $_.name -eq "my VM Name" }    

start-sleep -seconds 20
do {
    start-sleep -seconds 5
    $toolsStatus = ($VM | Get-View).Guest.ToolsStatus
} until ($toolsStatus -eq 'toolsOK')

5分钟后成功退出脚本。问题是我正在测试这个问题 - 虚拟机启动了,我得到的响应表明VMtools已经响应,但是循环没有停止。它一直持续到超时然后退出而不是继续下一步。

我之前没有使用过这种类型的循环,所以我会很感激一些输入,因为我确定我已经关闭了 - 但是我错过了一些东西。

3 个答案:

答案 0 :(得分:1)

应该只是一个简单的逻辑修复。在最后的while循环中,使用-and添加两个表达式并取消$toolStatus

while ($sw.elapsed -lt $timeout -and $toolsStatus -ne 'toolsOK'){
    start-sleep -seconds 5
}

当一个变为假时,循环将结束。

答案 1 :(得分:1)

VMWare已经有一个等待命令。

Start-VM "My VM Name" -runAsync
$VM = Get-VM | where { $_.name -eq "My VM Name" } | Wait-Tools -TimeoutSeconds 180

https://www.vmware.com/support/developer/PowerCLI/PowerCLI41U1/html/Wait-Tools.html

我已经阅读了有关运行VMTools和操作系统未启动问题的信息。一旦Windows徽标出现,VMTools似乎报告为正在运行,这可能会导致问题。我更喜欢使用Powershell命令来ping机器,直到我收到回复。

$thisisaddress = (Get-NetIPAddress | where {$_.AddressFamily -eq "IPv4" -and $_.InterfaceAlias -eq "Ethernet"}).ipaddress

$pingMachine = New-Object System.Net.NetworkInformation.Ping

$timeout = new-timespan -Minutes 1
$sw = [diagnostics.stopwatch]::StartNew()
while ($sw.elapsed -lt $timeout -and $pingStatus.Status -ne 'Success'){
    $pingStatus = $pingMachine.Send($thisisaddress)
    $pingStatus
}

答案 2 :(得分:0)

您没有在循环中更新$toolsStatus,因此即使VM已启动它也永远不会退出。只需在循环中移动支票即可。

Start-VM "My VM Name" -runAsync
$VM = Get-VM | where { $_.name -eq "My VM Name" }

$timeout = new-timespan -minutes 5
start-sleep -seconds 5
$sw = [diagnostics.stopwatch]::StartNew()
while ($sw.elapsed -lt $timeout) {
    $toolsStatus = ($VM | Get-View).Guest.ToolsStatus
    if ($toolsStatus -eq 'toolsOK') {
        return
    }
    start-sleep -seconds 5
}
Exit