There are tons of options for backing up your Hyper-V VMs, our favorite being Altaro Hyper-V Backup. However, if you are not ready to shell out $500 for a license and you have plenty of space available, you can use a bit of PowerShell and the Hyper-V API to create a custom backup solution for free.
The idea is simple: replicate the VMs you would like to backup to a Hyper-V host, and every day at midnight, run a task that will automatically export the replicas to a centralized storage in a folder using the current date/hour/seconds as the name of the folder.
This post assumes you already have the machines you would like to back up replicated to a Hyper-V server.
The script to export all replicas to a designated storage space is done with the following functions:
function Export-Replicas { [CmdletBinding()] [OutputType([int])] Param ( # The Hyper-V Server to look for VMs $HyperVServer, # ExportFolder $ExportFolder ) $a = Get-Date $DatedFolderName = [string]::Format("{0:00}-{1:00}-{2}-{3:00}{4:00}{5:00}",$a.Month, $a.Day, $a.Year, $a.Hour, $a.Minute,$a.Second) $ExportFolderName = ($ExportFolder + "" + $DatedFolderName) New-Item (Convert-LocalPathToUNCPath -LocalPath $ExportFolderName -RemoteMachine $HyperVServer) -type directory $VMstoRename = get-VM -ComputerName $HyperVServer | Where-Object {$_.ReplicationMode -eq "Replica"} foreach ($VM in $VMstoRename) { Write-HostWithTimeStamp([string]::Format("Exporting {0}", $VM.Name)) Export-VM -Path $ExportFolderName -VM $VM } } #MISC. FUNCTIONS function Convert-UNCPathToLocalPath { Param( #The UNC path [Parameter(Mandatory=$True)] [string] $UNCPath, [Parameter(Mandatory=$True)] [string] $RemoteMachine ) $TempLocalPath = $UNCPath.Replace(("\" + $RemoteMachine + ""),"") $TempLocalPath = $TempLocalPath.Replace("$",":") return $TempLocalPath } function Convert-LocalPathToUNCPath { Param( #The Local Path [Parameter(Mandatory=$True)] [string] $LocalPath, # The name of the remote machine [Parameter(Mandatory=$True)] [string] $RemoteMachine ) $TempUNCpath=($LocalPath).Replace(":", "$") # replaces the ":" with a "$" in a local path (e.g. C:temp => C$temp) $TempUNCpath=$TempUNCpath.Insert(0, "\"+$RemoteMachine+"") # adds \$maschinename (e.g. C$temp => \$maschinenameC$temp) return $TempUNCpath } function Write-HostWithTimeStamp { Param ( $Message ) Write-Host(“$(Get-Date -format g)” + " --> " + $Message) -BackgroundColor Black -ForegroundColor Yellow }
If you attach the following line at the end of the script, you can then create a Windows task that can run this script every day at midnight.
Export-Replicas -HyperVServer [NAME-OF-REPLICA-SERVER] -ExportFolder [EXPORT-FOLDER]
This way you will have a history of your VMs for as long as you want. I know this is completely inefficient in terms of space since it’s the whole VM that is being exported every time (not the differential portion), but if space and time are not a problem, this works just fine.
Nathan says:
Hi,
I’m interested to know whether this approach would be supported by Microsoft?