如何在 powershell 中等待虚拟机的启动/停止

如何在 powershell 中等待虚拟机的启动/停止

我有这个 powershell 脚本,我正在调用它来备份我们客户的虚拟机:

# 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)
}

问题出在 start-vm 和 stop-vm 上。脚本没有等到 vm 停止或启动后才继续执行下一行。

我该如何让它做到这一点以便我的脚本不会再中断?

谢谢!

长颈

我把代码改成这样:

  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 
  }

我得到了这个:

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

无限循环。

有什么建议么?

答案1

这将等待虚拟机运行:

while ((get-vm -name $vmnames).state -ne 'Running') { start-sleep -s 5 }

这将等到虚拟机关闭:

while ((get-vm -name $vmnames).state -ne 'Off') { start-sleep -s 5 }

答案2

正如 @rugk 所说,如果您通过 powershell 关闭虚拟机,而不是通过虚拟机内部的命令,那么至少目前不需要规定等待条件。您可以简单地写

Stop-VM -Name my_vm 
my other code

并且直到虚拟机关闭之前,所有进一步的代码都只能在虚拟机停止后执行。

相关内容