How do I wait on a start/stop of a virtual machine in powershell
6,261
This will wait until the VM is running:
while ((get-vm -name $vmnames).state -ne 'Running') { start-sleep -s 5 }
And this will wait until the VM is off:
while ((get-vm -name $vmnames).state -ne 'Off') { start-sleep -s 5 }
Related videos on Youtube
Author by
ErocM
Updated on September 18, 2022Comments
-
ErocM over 1 year
I have this powershell script that I'm calling to backup our customer's virtual machines:
# Author: Vladimir Eremin # Created Date: 3/24/2015 # http://forums.veeam.com/member31097.html # ################################################################## # User Defined Variables ################################################################## # Names of VMs to backup separated by comma (Mandatory). For instance, $VMNames = “VM1”,”VM2” $VMNames = "ZIMBRA" # Name of vCenter or standalone host VMs to backup reside on (Mandatory) $HostName = "TGDALLAS" # Directory that VM backups should go to (Mandatory; for instance, C:\Backup) $Directory = "H:\backups" # Desired compression level (Optional; Possible values: 0 - None, 4 - Dedupe-friendly, 5 - Optimal, 6 - High, 9 - Extreme) $CompressionLevel = "5" # Quiesce VM when taking snapshot (Optional; VMware Tools are required; Possible values: $True/$False) $EnableQuiescence = $True # Protect resulting backup with encryption key (Optional; $True/$False) $EnableEncryption = $False # Encryption Key (Optional; path to a secure string) $EncryptionKey = "" # Retention settings (Optional; By default, VeeamZIP files are not removed and kept in the specified location for an indefinite period of time. # Possible values: Never , Tonight, TomorrowNight, In3days, In1Week, In2Weeks, In1Month) $Retention = "In3Days" ################################################################## # Notification Settings ################################################################## # Enable notification (Optional) $EnableNotification = $True # Email SMTP server $SMTPServer = "localhost" # Email FROM $EmailFrom = "[email protected]" # Email TO $EmailTo = "[email protected]" # Email subject $EmailSubject = "TGDALLAS Backup Status" ################################################################## # Email formatting ################################################################## $style = "<style>BODY{font-family: Arial; font-size: 10pt;}" $style = $style + "TABLE{border: 1px solid black; border-collapse: collapse;}" $style = $style + "TH{border: 1px solid black; background: #dddddd; padding: 5px; }" $style = $style + "TD{border: 1px solid black; padding: 5px; }" $style = $style + "</style>" ################################################################## # End User Defined Variables ################################################################## #################### DO NOT MODIFY PAST THIS LINE ################ Asnp VeeamPSSnapin $Server = Get-VBRServer -name $HostName $MesssagyBody = @() foreach ($VMName in $VMNames) { Stop-VM -Name $VMNames $VM = Find-VBRHvEntity -Name $VMName -Server $Server If ($EnableEncryption) { $EncryptionKey = Add-VBREncryptionKey -Password (cat $EncryptionKey | ConvertTo-SecureString) $ZIPSession = Start-VBRZip -Entity $VM -Folder $Directory -Compression $CompressionLevel -DisableQuiesce:(!$EnableQuiescence) -AutoDelete $Retention -EncryptionKey $EncryptionKey } Else { $ZIPSession = Start-VBRZip -Entity $VM -Folder $Directory -Compression $CompressionLevel -DisableQuiesce:(!$EnableQuiescence) -AutoDelete $Retention } If ($EnableNotification) { $TaskSessions = $ZIPSession.GetTaskSessions().logger.getlog().updatedrecords $FailedSessions = $TaskSessions | where {$_.status -eq "EWarning" -or $_.Status -eq "EFailed"} if ($FailedSessions -ne $Null) { $MesssagyBody = $MesssagyBody + ($ZIPSession | Select-Object @{n="Name";e={($_.name).Substring(0, $_.name.LastIndexOf("("))}} ,@{n="Start Time";e={$_.CreationTime}},@{n="End Time";e={$_.EndTime}},Result,@{n="Details";e={$FailedSessions.Title}}) } Else { $MesssagyBody = $MesssagyBody + ($ZIPSession | Select-Object @{n="Name";e={($_.name).Substring(0, $_.name.LastIndexOf("("))}} ,@{n="Start Time";e={$_.CreationTime}},@{n="End Time";e={$_.EndTime}},Result,@{n="Details";e={($TaskSessions | sort creationtime -Descending | select -first 1).Title}}) } } Start-VM -Name $VMNames } If ($EnableNotification) { $Message = New-Object System.Net.Mail.MailMessage $EmailFrom, $EmailTo $Message.Subject = $EmailSubject $Message.IsBodyHTML = $True $message.Body = $MesssagyBody | ConvertTo-Html -head $style | Out-String $SMTP = New-Object Net.Mail.SmtpClient($SMTPServer) $SMTP.Send($Message) }
The problem is with the start-vm and stop-vm. The script is not waiting until the vm has stopped or started before continuing on to the next line.
How would I get it to do this so my script will stop breaking?
Thanks!
longneck
I changed the code to this:
Stop-VM -Name $VMNames while ((get-vm -name $vmnames).state -ne 'Running') { $a = Get-Date Write-Output "Waiting 5 seconds for $VMName to stop: $a" $state = (get-vm -name $vmnames).state Write-Output "State: $state" start-sleep -s 5 }
and I am getting this:
PS H:\> H:\VeeamBackupZimbra.ps1 Waiting 5 seconds for ZIMBRA to stop: 07/21/2016 14:39:03 State: Off Waiting 5 seconds for ZIMBRA to stop: 07/21/2016 14:39:08 State: Off Waiting 5 seconds for ZIMBRA to stop: 07/21/2016 14:39:13 State: Off Waiting 5 seconds for ZIMBRA to stop: 07/21/2016 14:39:18 State: Off Waiting 5 seconds for ZIMBRA to stop: 07/21/2016 14:39:23 State: Off
An endless loop.
Any suggestions?
-
rugk about 5 yearsActually, you don't need to do anything.
Start-VM
andStop-VM
do already wait (unless you pass-asjob
).
-
-
ErocM almost 8 yearsI thought it was working. Check out my notes above.
-
longneck almost 8 yearsYou used the wrong line. Change
'Running'
to'Off'
-
ErocM almost 8 yearsDuh. I wasn't thinking that one through. My bad. Great job! :D
-
Andrew Roberts over 2 yearsThere's an undocumented Wait-VM cmdlet that ships in the Hyper-V module that encapsulates this behaviour, probably using the code shown in this blog post: web.archive.org/web/20190907044133/https://…