Backup Hyper-V with Powershell

A few days ago, Ben Armstrong, the Virtual PC Guy posted on his blog the following:

Why would you backup VMs / When / What’s the best practice
Why? Just in case of a disaster, you should be able to recover your VMs.
When? The best practive analyzer has the answer:

Get-BpaModel  -ModelId Microsoft/Windows/Hyper-V | Invoke-BpaModel

Get-BpaModel | ? Name -match "Hyper-V" |            
Get-BpaResult | ?{($_.Resolution) -and ($_.Severity -eq "Error")}|            
fl -p ResultNumber,Severity,Category,Title,Problem,Resolution

How do I perform the backup with PowerShell

  • Prerequisite #1: Install the backup features
  • Get-WindowsFeature | ? { $_.DisplayName -match "Backup" }

    Add-WindowsFeature -Name Windows-Server-Backup -IncludeAllSubFeature:$true -Restart:$false

  • Prerequisite #2: Make sure the integration services have been installed
  • Get-VM | ? State -eq "Running" |            
    Select Name,State,Integrationservicesversion |            
    ft -AutoSize

    Query the VM integration services version of running VMs to prevent them going into a saved state if they don’t have the latest VM integration services installed.
    Ben Armstrong, the Virtual PC Guy in his posts also said:

    The virtual machine will only be put into a saved state if it is not running the latest virtual machine additions (or is not a Windows virtual machine).

    More info about VM integration services, see my post: https://p0w3rsh3ll.wordpress.com/2012/11/15/follow-up-about-hyper-v-vm-integration-services/

  • Check what VM can be backed up and how
  • Get-WBVirtualMachine  | ft VMName,Caption -AutoSize


    If the VM is off, the backup is performed from the saved state.
    If the VM is running, the backup is performed using a snapshot.

  • Backup a single VM manually and synchronously
  • # Create an empty policy object                        
    $pol = New-WBPolicy            
    

    # Add a single VM to the backup            
    Get-WBVirtualMachine | ? VMName -eq myVMName | Add-WBVirtualMachine -Policy $pol

    # Define a target folder for the backup            
    $targetvol = New-WBBackupTarget -NetworkPath \\mytargetserver.fqdn\HVBackup$ -Credential (Get-Credential) -NonInheritAcl:$false -Verbose            
    Add-WBBackupTarget -Policy $pol -Target $targetvol

    # Define a schedule            
    Set-WBSchedule -Policy $pol -Schedule ([datetime]::Now.AddMinutes(10))            
                
    # Start the backup synchronously            
    Start-WBBackup -Policy $pol


    Note that you cannot start a saved VM (off) when there’s a backup in progress:

    # Review the result            
    Get-WBSummary            
    Get-WBBackupSet -BackupTarget (Get-WBBackupTarget $pol)            
    Get-WBJob -Previous 1


We have the ability to add multiple VMs to a single backup job. However VMs will be backed up sequentially.
You may have also seen how tedious it can be to perform the recovery in Ben Armstrong’s blog post, so I propose the following code snippet that may help:

$BackupShare = "\\mytargetserver.fqdn\HVBackup$"
$cred = (Get-Credential)
Get-VM | ForEach-Object -Process {
    $targetfolder = Join-Path -Path $BackupShare -ChildPath "$($env:COMPUTERNAME)\$($_.Name)"
    If (Test-Path $targetfolder) {
        Write-Verbose -Message "Previous backup for VM $($_.Name) found" -Verbose
        # Delete it first
        try {
            Remove-Item -Path $targetfolder -Force -ErrorAction Stop
        } catch {
            Write-Warning -Message "Failed to remove target folder $targetfolder"
            return
        }
        # Create directory
        try {
            New-Item -Path $targetfolder -ItemType Directory -ErrorAction Stop
        } catch {
            Write-Warning -Message "Failed to create target folder $targetfolder"
            return
        }
    } else {
        # Create directory
        try {
            New-Item -Path $targetfolder -ItemType Directory -ErrorAction Stop
        } catch {
            Write-Warning -Message "Failed to create target folder $targetfolder"
            return
        }
    }

    # Create an empty policy object            
    $pol = New-WBPolicy

    # Add the VM
    Get-WBVirtualMachine | ? VMName -eq $_.Name | Add-WBVirtualMachine -Policy $pol
    
    # Define a target folder
    $targetvol = New-WBBackupTarget -NetworkPath $targetfolder -Credential $cred -NonInheritAcl:$false -Verbose
    Add-WBBackupTarget -Policy $pol -Target $targetvol

    # Set a schedule
    Set-WBSchedule -Policy $pol -Schedule ([datetime]::Now.AddMinutes(10))

    # Start the backup
    Start-WBBackup -Policy $pol -Async 

    # Let us know the status of the running job
    While((Get-WBJob).JobState -eq "Running") { 
        $percent = ([int](@(([regex]'.*\((?<percent>\d{2})\%\).*').Matches((Get-WBJob).CurrentOperation).Groups)[-1].Value))
        if ($percent) {
            Write-Progress -Activity "Backup of VM $($_.Name) in progress" -Status "Percent completed: " -PercentComplete $percent
        } else {
            Write-Progress -Activity "Backup of VM $($_.Name) in progress" -Status (Get-WBJob).CurrentOperation
        }
    }
}
Advertisements

3 thoughts on “Backup Hyper-V with Powershell

  1. Brilliant!

    Practically everything one needs to know on how to backup a Hyper-V VM (and a windows computer), using PowerShell.

    Great Work.

  2. Everyone be aware though that a snapshot/checkpoint is not good enough in many if not most situations, since many applications do not support snapshots. Hence you would actually need to do a full VSS backup and hence you would either have to shutdown the VM to do this (otherwise the above method generate a checkpoint), or you would have to do a VSS backup from within the VM; this is actually what I do since I am paranoid about not being able to restore to a fully-working state.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s