Powershell/PowerCLI Loop, timeouts and exits

生来就可爱ヽ(ⅴ<●) 提交于 2021-01-27 19:01:29

问题


Here is the scenario - I'm remotely starting a VM via Powershell/PowerCLI (VMwares Powershell module) and once the VM is started I will be running a series of cmdlets against the VM.

Currently I have this bit of code:

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')

Which works - the VM starts and the loop will check until VMware Tools is reporting in to VMware (which means the VM has fully booted into the OS).

However this will run indefinitely and so in a scenario where the VM fails to boot successfully - the script hangs. So I've tried to add in a timer to exit the script if it runs passed by 5 Minutes:

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

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

Which successfully exits the script after 5 minutes. The issue is whilst I'm testing this - the VM has booted and I'm getting a response indicating that VMtools has responded, but the loop isn't stopping. It's continuing till it has timed-out then exiting as opposed to proceeding to the next step.

I've not worked with this type of loop before so would appreciate some input as I'm sure I'm close - but I've missed something.


回答1:


You're not updating $toolsStatus in your loop, hence it never exits even though the VM has booted. Just move the check inside your loop.

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



回答2:


Should be just a simple logical fix. In your final while loop, add both expressions with an -and and negate the $toolStatus

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

When one becomes false, the loop will end.




回答3:


VMWare already has a command for wait.

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

I've read about VMTools running and the OS not being started problems. As soon as the Windows logo appears VMTools seems to report as running, this can cause issues. I prefer to use a Powershell command to ping the machine until I get a response.

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


来源:https://stackoverflow.com/questions/42640113/powershell-powercli-loop-timeouts-and-exits

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!