A PowerShell script that creates backups of stopped Hyper-V virtual machines using timestamp-based change detection with three different backup methods.
The script automatically backs up Hyper-V VMs by:
- Backing up stopped VMs using one of three configurable methods
- Only backing up VMs when their disk files have changed since the last backup
- Keeping a configurable number of recent backups per VM
- Cleaning up old backups automatically
- Skipping VMs that are not turned off
The script checks the LastWriteTime of each VM's VHD/VHDX files against the timestamp of the most recent backup folder. If any disk file is newer than the last backup, it creates a new backup using the configured method.
-
Export-VM (
$BackupMethod = "Export")- Creates complete VM backups including configuration and disks
- Uses Hyper-V's built-in Export-VM command
- Stored in
BackupRoot\<VMName>\<timestamp>\Export\ - Largest backup size but includes everything needed to restore the VM
-
!!! NOT TESTED !!! Robocopy (
$BackupMethod = "Robocopy")- Copies only VHD/VHDX disk files
- Uses robocopy for fast, reliable file copying
- Stored in
BackupRoot\<VMName>\<timestamp>\Disks\ - Faster than Export-VM, smaller backup size, but no VM configuration
-
7-zip (
$BackupMethod = "7zip")- Compresses VHD/VHDX disk files into a single archive
- Uses fastest compression setting with multithreading
- Stored as
BackupRoot\<VMName>\<timestamp>\<VMName>.7z - Smallest backup size, moderate speed, no VM configuration
Backups are stored in folders named with timestamps (yyyy-MM-dd_HH-mm-ss format) under BackupRoot\<VMName>\.
- Windows with Hyper-V role installed
- PowerShell with Hyper-V module
- Administrator privileges
- Sufficient disk space at the backup destination
- 7-zip command line utility (only if using 7-zip backup method)
Edit the variables at the top of the script:
$BackupRoot = "T:\Arhiv\VM" # Backup destination path
$MaxBackupsPerVM = 2 # Number of backups to keep per VM
$TimestampFormat = "yyyy-MM-dd_HH-mm-ss" # Folder naming format
$BackupMethod = "Export" # "Export", "Robocopy", or "7zip"
$RobocopyFlags = "/E /Z /B /MT:8 /R:3 /W:10" # Robocopy parameters
$SevenZipPath = "7z" # Path to 7z.exe
$SevenZipFlags = "a -t7z -mx=1 -mmt=4 -ms=off" # 7-zip parameters- Stop the VMs you want to back up
- Run PowerShell as Administrator
- Execute the script:
.\BackupHyperVDisks.ps1
You can of course create a desktop shortcut to run the script. In this case, the PowerShell switch -NoExit is recommended, so you can inspect the script output when it's done.
For the Export-VM and Robocopy methods, you might want to enable NTFS compression on the backup folder to save space. The 7-zip method already provides compression.
-
Antivirus exclusions: Real-time antivirus scanning can significantly slow down backup operations. Consider adding exclusions for:
- The backup destination folder (
$BackupRoot) - The VM disk files being backed up
- The PowerShell script itself
- The backup destination folder (
-
7-zip optimization: The default 7-zip flags use
-ms=off(non-solid mode) which significantly speeds up writing to spinning drives. Additional optimizations:- For fast CPUs with slow target drives, consider higher compression (
-mx=3to-mx=5) for better space efficiency - Adjust thread count (
-mmt=4) based on your CPU cores
- For fast CPUs with slow target drives, consider higher compression (
- Only stopped VMs are backed up
- Running or paused VMs are listed but skipped
- The script uses atomic operations (temporary folders) to prevent incomplete backups
- Failed backups are automatically cleaned up
- Change detection is based on disk file timestamps, not VM configuration changes
- Export-VM method creates complete backups that can be imported directly
- Robocopy and 7-zip methods only backup disk files - VM configuration must be recreated manually
- 7-zip method requires 7z.exe to be installed and accessible in PATH or specify full path in
$SevenZipPath