HYPER-V Back Script, with optional suspend or stop of the virtual machine

With the help of the powershell applets for HYPER-V it has become quite easy to create a reliable backup of your virtual machines without the need for highly expensive backup tools. The script uses the standard export functionality build into HYPER-V, so you can restore one of these backup’s to the actual virtual machine including the unique identifiers

Adept the configuration section at the top of the script with the network locations of your choosing. If you choose a non local location, you need to make sure the computer account of the hypervisor has access to the share (NOT the logged in user) (see: this document )

  • $export_share – The network share of local location ending in a \
  • $export_prefix – An optional prefix for the export directoryname
  • $email_from – The sender address for alert mails
  • $mail_to – The receiver address for alert mails
  • $mailserver – Your smtp relay

With the configuration set, you can amend the very bottom of the script with the names of the virtual machines you need backed up. The basic choise you have here is wheter you want to stop the virtual machine during the backup (BackupWithSuspend), or create a backup of the running virtual machine including the memory state.BackupWithStop

# configuration
$export_share = "\\server\share\";
$export_prefix = "export_";
$mail_from = "powershell@yourdomain.com";
$mail_to = "sysop@yourdomain.com";
$mailserver = "smtpserver@yourdomain.com";

# backup/export VM, suspending the VM
Function BackupWithSuspend($computer)
{
	echo "Stopping Virtual Machine $computer"
    echo "Clear location"
    Remove-Item "$export_share$export_prefix$computer" -recurse
    Start-Sleep -s 10
	echo 'Creating backup'
    Export-VM -ErrorAction Stop $computer "$export_share$export_prefix$computer"          
    Start-Sleep -s 10
	echo "Completed $computer"
}

Function BackupWithStop($computer)
{
	echo "Stopping Virtual Machine $computer"
	Stop-VM -Name $computer
    Start-Sleep -s 10
    echo "Clear location"
    Remove-Item "$export_share$export_prefix$computer" -recurse
    Start-Sleep -s 10
	echo 'Creating backup'
    Try
    {
        Export-VM -ErrorAction Stop $computer "$export_share$export_prefix$computer"
    }
    Catch
    {
        $msg = "$(Get-Date) - Error during Export-VM $($_.Exception.Message)"
        SendMail $computer $msg    
    }       
    Start-Sleep -s 10
	echo "Starting Virtual machine $computer"
	Start-VM -Name $computer
    Start-Sleep -s 10
	echo "Completed $computer"
}

# Check the heartbeat of the specified VM, and keep attempting to start it if
# it is not present.
Function CheckStart([string]$computer, [int]$sleeptime) 
{
    # Give the VM Some time to do a normal startup after export/backup
    Start-Sleep -s $sleeptime
    $retrycount = 0
    # check heartbeat
    $VM = Get-VMIntegrationService -VMName $computer -Name Heartbeat 
    while ($VM.PrimaryStatusDescription -ne "OK" -and $retrycount -lt 10) 
    { 
        $retrycount = $retrycount + 1
        $VM = Get-VMIntegrationService -VMName $computer -Name Heartbeat 
        Set-Variable -Name msg  "Poging $retrycount Start mislukt."
        Write-Host $msg
        if ($retrycount -eq 5)
        {
                SendMail $computer $msg
        }
        Start-VM -Name $computer
        sleep $sleeptime        
    }
    write-host $computer "Exit"
}

# Send administrative email
Function SendMail([string]$subject,[string]$msg)
{ 
    Send-MailMessage -From $mail_from -SmtpServer $mailserver -To $mail_to -Subject $subject -Body $msg
}

# The actual backup targets
$computer = "G1_SRV_SERVER1"; BackupWithSuspend $computer; CheckStart $computer 60
$computer = "G1_SRV_SERVER2"; BackupWithSuspend $computer; CheckStart $computer 60
$computer = "S1_WORKSTATION1"; BackupWithStop $computer; CheckStart $computer 60
$computer = "S1_WORKSTATION2"; BackupWithStop $computer; CheckStart $computer 60