TechEd Europe: Windows vNext Hyper-V Backup and Restore PowerShell Scripts
TechEd Europe - Windows vNext Hyper-V Backup and Restore PowerShell Scripts
We just had a fantastic session at TechEd Europe showcasing the next evolution in Hyper-V backup and restore coming with Windows vNext (currently available as a Technical Preview). Once the session recording is live I will post a link but for those folks in the room here is the PowerShell module I wrote for the demo's. As I mentioned in the session please try give our new backup and restore scenarios a try and submit feedback so that we can make sure the next release of Hyper-V backup has the most reliable, scalable and preformat backup and restore solution possible. Thanks!
The module is also attached to this post at the bottom.
-taylorb
# ProcessWMIJob is a generic function that waits for WMI job's to
# complete and returns appropriate success/failure cases.
# This function was originally written and documented on
# Taylor Brown's blog at:
# https://blogs.msdn.com/b/taylorb/archive/2008/06/18/hyper-v-wmi-rich-error-messages-for-non-zero-returnvalue-no-more-32773-32768-32700.aspx
filter ProcessWMIJob
{
param
(
[WMI]$WmiClass = $null,
[string]$MethodName = $null
)
$errorCode = 0
$returnObject = $_
if ($_.ReturnValue -eq 4096)
{
$Job = [WMI]$_.Job
$returnObject = $Job
while ($Job.JobState -eq 4)
{
Write-Progress -Activity $Job.Caption -Status ($Job.JobStatus + " - " + $Job.PercentComplete + "%") -PercentComplete $Job.PercentComplete
Start-Sleep -seconds 1
$Job.PSBase.Get()
}
if ($Job.JobState -ne 7)
{
if ($Job.ErrorDescription -ne "")
{
Write-Error $Job.ErrorDescription
Throw $Job.ErrorDescription
}
else
{
$errorCode = $Job.ErrorCode
}
}
Write-Progress -Activity $Job.Caption -Status $Job.JobStatus -PercentComplete 100 -Completed:$true
}
elseif($_.ReturnValue -ne 0)
{
$errorCode = $_.ReturnValue
}
if ($errorCode -ne 0)
{
Write-Error "Hyper-V WMI Job Failed!"
if ($WmiClass -and $MethodName)
{
$psWmiClass = [WmiClass]("\\" + $WmiClass.__SERVER + "\" + $WmiClass.__NAMESPACE + ":" + $WmiClass.__CLASS)
$psWmiClass.PSBase.Options.UseAmendedQualifiers = $TRUE
$MethodQualifierValues = ($psWmiClass.PSBase.Methods[$MethodName].Qualifiers)["Values"]
$indexOfError = [System.Array]::IndexOf(($psWmiClass.PSBase.Methods[$MethodName].Qualifiers)["ValueMap"].Value, [string]$errorCode)
if (($indexOfError -ne "-1") -and $MethodQualifierValues)
{
Throw "ReturnCode: ", $errorCode, " ErrorMessage: '", $MethodQualifierValues.Value[$indexOfError], "' - when calling $MethodName"
}
else
{
Throw "ReturnCode: ", $errorCode, " ErrorMessage: 'MessageNotFound' - when calling $MethodName"
}
}
else
{
Throw "ReturnCode: ", $errorCode, "When calling $MethodName - for rich error messages provide classpath and method name."
}
}
return $returnObject
}
function Convert-VmBackupCheckpoint
{
Param(
[Parameter(Mandatory=$True)]
[System.Management.ManagementObject]$BackupCheckpoint = $null
)
# Retrieve an instance of the snapshot management service
$Msvm_VirtualSystemSnapshotService = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemSnapshotService
# Convert the snapshot to a reference point, this function returns a job object.
$job = $Msvm_VirtualSystemSnapshotService.ConvertToReferencePoint($BackupSnapshot)
# Wait for the job to complete.
($job | ProcessWMIJob -WmiClass $Msvm_VirtualSystemSnapshotService -MethodName "ConvertToReferencePoint") | Out-Null
# The new reference point object is related to the job, GetReleated
# always returns an array in this case there is only one member
$refPoint = (([WMI]$job.Job).GetRelated("Msvm_VirtualSystemReferencePoint") | % {$_})
# Return the reference point object
return $refPoint
}
function Export-VMBackupCheckpoint
{
Param(
[Parameter(Mandatory=$True)]
[string]$VmName = [String]::Empty,
[Parameter(Mandatory=$True)]
[string]$DestinationPath = [String]::Empty,
[Parameter(Mandatory=$True)]
[System.Management.ManagementObject]$BackupCheckpoint = $null,
[System.Management.ManagementObject]$ReferencePoint = $null,
[bool]$noWait = $false
)
# Retrieve an instance of the virtual machine management service
$Msvm_VirtualSystemManagementService = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemManagementService
# Retrieve an instance of the virtual machine computer system that will be snapshoted
$Msvm_ComputerSystem = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ComputerSystem -Filter "ElementName='$vmName'"
# Retrieve an instance of the Export Setting Data Class (this is used to inform the export operation)
# GetReleated always returns an array in this case there is only one member
$Msvm_VirtualSystemExportSettingData = ($Msvm_ComputerSystem.GetRelated("Msvm_VirtualSystemExportSettingData","Msvm_SystemExportSettingData",$null,$null, $null, $null, $false, $null) | % {$_})
# Specify the export options
# CopySnapshotConfiguration
# 0: ExportAllSnapshots - All snapshots will be exported with the VM.
# 1: ExportNoSnapshots - No snapshots will be exported with the VM.
# 2: ExportOneSnapshot - The snapshot identified by the SnapshotVirtualSystem property will be exported with the VM.
# 3: ExportOneSnapshotUseVmId - The snapshot identified by the SnapshotVirtualSystem property will be exported with the VM. Using the VMs ID.
$Msvm_VirtualSystemExportSettingData.CopySnapshotConfiguration = 3
# CopyVmRuntimeInformation
# Indicates whether the VM runtime information will be copied when the VM is exported. (i.e. saved state)
$Msvm_VirtualSystemExportSettingData.CopyVmRuntimeInformation = $false
# CopyVmStorage
# Indicates whether the VM storage will be copied when the VM is exported. (i.e. VHDs/VHDx files)
$Msvm_VirtualSystemExportSettingData.CopyVmStorage = $true
# CreateVmExportSubdirectory
# Indicates whether a subdirectory with the name of the VM will be created when the VM is exported.
$Msvm_VirtualSystemExportSettingData.CreateVmExportSubdirectory = $false
# SnapshotVirtualSystem
# Path to a Msvm_VirtualSystemSettingData instance that represents the snapshot to be exported with the VM.
$Msvm_VirtualSystemExportSettingData.SnapshotVirtualSystem = $BackupSnapshot
# DifferentialBase
# Base for differential export. This is either path to a Msvm_VirtualSystemReferencePoint instance that
# represents the reference point or path to a Msvm_VirtualSystemSettingData instance that
# represents the snapshot to be used as a base for differential export. If the CopySnapshotConfiguration
# property is not set to 3(ExportOneSnapshotUseVmId), this property is ignored."
$Msvm_VirtualSystemExportSettingData.DifferentialBase = $ReferenceSnapshot
# StorageConfiguration
# Indicates what should be the VHD path in the exported configuration.
# 0: StorageConfigurationCurrent - The exported configuration would point to the current VHD.
# 1: StorageConfigurationBaseVhd - The exported configuration would point to the base VHD.
$Msvm_VirtualSystemExportSettingData.StorageConfiguration = 1
#Export the virtual machine snapshot, this method returns a job object.
$job = $Msvm_VirtualSystemManagementService.ExportSystemDefinition($Msvm_ComputerSystem, $DestinationPath, $Msvm_VirtualSystemExportSettingData.GetText(1))
if (!$noWait)
{
($job | ProcessWMIJob -WmiClass $Msvm_VirtualSystemManagementService -MethodName "ExportSystemDefinition") | Out-Null
}
}
function Get-VmBackupCheckpoints
{
Param(
[Parameter(Mandatory=$True)]
[string]$VmName = [String]::Empty
)
# Retrieve an instance of the virtual machine computer system that contains recovery checkpoints
$Msvm_ComputerSystem = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ComputerSystem -Filter "ElementName='$VmName'"
# Retrieve all snapshot associations for the virtual machine
$allSnapshotAssociations = $Msvm_ComputerSystem.GetRelationships("Msvm_SnapshotOfVirtualSystem")
# Enumerate across all of the instances and add all recovery snapshots to an array
$virtualSystemSnapshots = @()
$enum = $allSnapshotAssociations.GetEnumerator()
$enum.Reset()
while($enum.MoveNext())
{
if (([WMI] $enum.Current.Dependent).VirtualSystemType -eq "Microsoft:Hyper-V:Snapshot:Recovery")
{
$virtualSystemSnapshots += ([WMI] $enum.Current.Dependent)
}
}
# Return the array of recovery snapshots
$virtualSystemSnapshots
}
function Get-VmReferencePoints
{
Param(
[Parameter(Mandatory=$True)]
[string]$VmName = [String]::Empty
)
# Retrieve an instance of the virtual machine computer system that contains reference points
$Msvm_ComputerSystem = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ComputerSystem -Filter "ElementName='$VmName'"
# Retrieve all refrence associations of the virtual machine
$allrefPoints = $Msvm_ComputerSystem.GetRelationships("Msvm_ReferencePointOfVirtualSystem")
# Enumerate across all of the instances and add all recovery points to an array
$virtualSystemRefPoint = @()
$enum = $allrefPoints.GetEnumerator()
$enum.Reset()
while($enum.MoveNext())
{
$virtualSystemRefPoint += ([WMI] $enum.Current.Dependent)
}
# Return the array of recovery points
$virtualSystemRefPoint
}
function New-VmBackupCheckpoint
{
Param(
[Parameter(Mandatory=$True)]
[string]$VmName = [String]::Empty,
[ValidateSet('ApplicationConsistent','CrashConsistent')]
[string]$ConsistencyLevel = "Application Consistent"
)
# Retrieve an instance of the virtual machine management service
$Msvm_VirtualSystemManagementService = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemManagementService
# Retrieve an instance of the virtual machine snapshot service
$Msvm_VirtualSystemSnapshotService = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemSnapshotService
# Retrieve an instance of the virtual machine computer system that will be snapshotted
$Msvm_ComputerSystem = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ComputerSystem -Filter "ElementName='$vmName'"
# Create an instance of the Msvm_VirtualSystemSnapshotSettingData, this class provides options on how the checkpoint will be created.
$Msvm_VirtualSystemSnapshotSettingData = ([WMIClass]"\\.\root\virtualization\v2:Msvm_VirtualSystemSnapshotSettingData").CreateInstance()
# Identify the consistency level for the snapshot.
# 1: Application Consistent
# 2: Crash Consistent
switch ($ConsistencyLevel)
{
"ApplicationConsistent" {
$Msvm_VirtualSystemSnapshotSettingData.ConsistencyLevel = 1
}
"CrashConsistent" {
$Msvm_VirtualSystemSnapshotSettingData.ConsistencyLevel = 2
}
default {
throw "Unexpected Consistancy Level Specified"
}
}
# Specify the behavior for disks that cannot be snapshotted (i.e. pass-through, virtual fibre channel)
$Msvm_VirtualSystemSnapshotSettingData.IgnoreNonSnapshottableDisks = $true
# Create the virtual machine snapshot, this method returns a job object.
$job = $Msvm_VirtualSystemSnapshotService.CreateSnapshot(
$Msvm_ComputerSystem,
$Msvm_VirtualSystemSnapshotSettingData.GetText(2),
32768)
# Waits for the job to complete and processes any errors.
($job | ProcessWMIJob -WmiClass $Msvm_VirtualSystemSnapshotService -MethodName "CreateSnapshot") | Out-Null
# Retrieves the snapshot object resulting from the snapshot.
$snapshot = (([WMI]$job.Job).GetRelated("Msvm_VirtualSystemSettingData") | % {$_})
# Returns the snapshot instance
return $snapshot
}
function Remove-VmReferencePoint
{
Param(
[Parameter(Mandatory=$True)]
[System.Management.ManagementObject]$ReferencePoint = $null
)
# Retrieve an instance of the virtual machine refrence point service
$Msvm_VirtualSystemReferencePointService = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemReferencePointService
# Removes the virtual machine reference, this method returns a job object.
$job = $Msvm_VirtualSystemReferencePointService.DestroyReferencePoint($ReferenceSnapshot)
# Waits for the job to complete and processes any errors.
($job | ProcessWMIJob -WmiClass $Msvm_VirtualSystemReferencePointService -MethodName "DestroyReferencePoint") | Out-Null
}
Comments
Anonymous
May 26, 2015
The comment has been removedAnonymous
October 09, 2015
I am seeing the same issue as Chris mentioned above. Is there any update on the issue?Anonymous
November 17, 2015
The comment has been removedAnonymous
January 21, 2016
Msvm_VirtualSystemSnapshotSettingData is not supported with Windows 2012. In Windows 2012 hyperv host, how do we create the snapshot with application-consistency ?