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 }
Share:
6,261

Related videos on Youtube

ErocM
Author by

ErocM

Updated on September 18, 2022

Comments

  • ErocM
    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
      rugk about 5 years
      Actually, you don't need to do anything. Start-VM and Stop-VM do already wait (unless you pass -asjob).
  • ErocM
    ErocM almost 8 years
    I thought it was working. Check out my notes above.
  • longneck
    longneck almost 8 years
    You used the wrong line. Change 'Running' to 'Off'
  • ErocM
    ErocM almost 8 years
    Duh. I wasn't thinking that one through. My bad. Great job! :D
  • Andrew Roberts
    Andrew Roberts over 2 years
    There'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://…