11 KiB
Hyper-V Backup Script
Version: 1.0.1 Last Updated: 2026-01-26
Overview
Production-ready automated backup solution for Hyper-V virtual machines with scheduling, checkpoints, retention management, and remote storage support.
Features
- ✅ Automated VM Backup - Exports all VMs on the host (Export-VM handles checkpoints internally)
- ✅ Flexible Scheduling - Schedule backups by month, weekday, and time with interval control
- ✅ Remote Storage Support - Backup to UNC shares with secure credential management
- ✅ Retention Management - Automatically cleanup old backups based on retention count
- ✅ Checkpoint Management - Automatic cleanup of backup checkpoints (keeps last 2 for rollback)
- ✅ Space Validation - Dynamic space checks for temp (per VM) and destination before copy
- ✅ VM Exclusion - Exclude specific VMs from backup
- ✅ Detailed Logging - Comprehensive logging with timestamps and severity levels
- ✅ Lock Files - Prevents concurrent execution
- ✅ Error Handling - Proper exit codes and error reporting
Requirements
System Requirements
- Windows Server with Hyper-V role installed
- PowerShell 5.1 or later
- Administrator privileges
- Hyper-V PowerShell module
Dependencies
SchedulerTemplate.psm1module (located in parent directory)scriptsettings.jsonconfiguration file
File Structure
HyperV-Backup/
├── hyper-v-backup.bat # Batch launcher with admin check
├── hyper-v-backup.ps1 # Main PowerShell script
├── scriptsettings.json # Configuration file
└── README.md # This file
Installation
-
Copy Files
# Copy the entire HyperV-Backup folder to your desired location # Ensure SchedulerTemplate.psm1 is in the parent directory -
Configure Settings
Edit
scriptsettings.jsonwith your environment settings:{ "schedule": { "runMonth": [], "runWeekday": ["Monday"], "runTime": ["00:00"], "minIntervalMinutes": 10 }, "backupRoot": "\\\\your-nas\\backups", "credentialEnvVar": "YOUR_ENV_VAR_NAME", "tempExportRoot": "D:\\Temp\\HyperVExport", "retentionCount": 3, "excludeVMs": ["vm-to-exclude"] } -
Setup Credentials (for UNC paths)
If backing up to a network share, create a Machine-level environment variable:
# Create Base64-encoded credentials $username = "DOMAIN\user" $password = "your-password" $creds = "$username:$password" $encoded = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($creds)) # Set Machine-level environment variable [System.Environment]::SetEnvironmentVariable("YOUR_ENV_VAR_NAME", $encoded, "Machine") -
Test Manual Execution
# Run as Administrator .\hyper-v-backup.bat # or .\hyper-v-backup.ps1
Configuration Reference
Schedule Settings
| Property | Type | Description | Example |
|---|---|---|---|
runMonth |
array | Month names to run. Empty = every month | ["January", "June", "December"] or [] |
runWeekday |
array | Weekday names to run. Empty = every day | ["Monday", "Friday"] |
runTime |
array | UTC times to run (HH:mm format) | ["00:00", "12:00"] |
minIntervalMinutes |
number | Minimum minutes between runs | 10 |
Backup Settings
| Property | Type | Required | Description |
|---|---|---|---|
backupRoot |
string | Yes | UNC or local path for backups. Hostname is appended automatically. |
credentialEnvVar |
string | No* | Name of Machine-level environment variable with credentials (*Required for UNC paths) |
tempExportRoot |
string | Yes | Local directory for temporary VM exports. Space checked dynamically per VM (1.5x VM size). |
retentionCount |
number | Yes | Number of backup generations to keep (1-365) |
excludeVMs |
array | No | VM names to exclude from backup |
Version Tracking
| Property | Type | Description |
|---|---|---|
version |
string | Configuration schema version |
lastModified |
string | Last modification date (YYYY-MM-DD) |
Usage
Manual Execution
Using Batch File (Recommended):
REM Right-click and select "Run as administrator"
hyper-v-backup.bat
Using PowerShell:
# Run as Administrator
.\hyper-v-backup.ps1
# With verbose output
.\hyper-v-backup.ps1 -Verbose
Automated Execution
The script supports automated execution through the UScheduler service:
# Called by scheduler with -Automated flag
.\hyper-v-backup.ps1 -Automated -CurrentDateTimeUtc "2026-01-24 00:00:00"
When -Automated is specified:
- Schedule is enforced (month, weekday, time)
- Lock files prevent concurrent execution
- Interval checking prevents duplicate runs
- Logs are formatted for service logger (no timestamps)
How It Works
Backup Process Flow
-
Initialization
- Load SchedulerTemplate.psm1 module
- Load and validate scriptsettings.json
- Validate required settings
- Set up backup paths
-
Pre-flight Checks
- Verify Administrator privileges
- Check Hyper-V module availability
- Verify Hyper-V service is running
- Check temp directory and free space
- Authenticate to backup share (if UNC)
- Create backup destination directory
-
Backup Execution
- Retrieve all VMs on the host
- Filter excluded VMs
- For each VM:
- Check temp space (requires 1.5x VM size)
- Export VM to temp location (Export-VM handles checkpoints internally)
- Check destination space before copy
- Copy to final backup location
- Cleanup temp export
-
Cleanup
- Remove old backup checkpoints (keeps last 2 for rollback)
- Delete old backup folders beyond retention count
-
Summary
- Display backup statistics
- Report success/failure counts
- List any errors encountered
Directory Structure Created
\\backupRoot\Hyper-V\Backups\hostname\
├── 20260124000000\ # Backup folder (timestamp)
│ ├── VM-Name-1\
│ ├── VM-Name-2\
│ └── VM-Name-3\
├── 20260117000000\ # Previous backup
└── 20260110000000\ # Older backup (will be deleted if retentionCount=2)
Lock and State Files
When running in automated mode, the script creates:
hyper-v-backup.lock- Prevents concurrent executionhyper-v-backup.lastRun- Tracks last execution time for interval control
Logging
Log Levels
| Level | Description | Color (Manual) |
|---|---|---|
Info |
Informational messages | White |
Success |
Successful operations | Green |
Warning |
Non-critical issues | Yellow |
Error |
Critical errors | Red |
Log Format
Manual Execution:
[2026-01-24 00:00:00] [Info] Hyper-V Backup Process Started
[2026-01-24 00:00:01] [Success] All prerequisites passed
[2026-01-24 00:05:30] [Success] Backup completed successfully for VM: server01
Automated Execution:
[Info] Hyper-V Backup Process Started
[Success] All prerequisites passed
[Success] Backup completed successfully for VM: server01
Exit Codes
| Code | Description |
|---|---|
0 |
Success or no VMs found |
1 |
Error occurred (module load, config, prerequisites, backup failure) |
Troubleshooting
Common Issues
1. Module Not Found
Error: Failed to load SchedulerTemplate.psm1
Solution: Ensure SchedulerTemplate.psm1 is in the parent directory (../SchedulerTemplate.psm1)
2. UNC Path Authentication Failed
Error: Failed to connect to \\server\share
Solution:
- Verify
credentialEnvVaris set in scriptsettings.json - Verify environment variable exists at Machine level
- Verify credentials are Base64-encoded in format:
username:password - Test with:
net use \\server\sharemanually
3. Insufficient Space
Error: Insufficient temp space for VM 'xxx' (need ~150 GB, have 100 GB)
Error: Insufficient space on destination for VM 'xxx'
Solution:
- Free up space on temp drive or destination
- Use different temp location with more space
- Check destination share quota/capacity
4. Lock File Exists
Guard: Lock file exists. Skipping.
Solution:
- Another instance is running, or previous run didn't complete
- Manually delete
.lockfile if stuck - Check for hung PowerShell processes
5. Export Failed
Error: Failed to export VM 'xxx'
Solution:
- Verify VM is in a valid state
- Check Hyper-V event logs
- Ensure sufficient disk space for export
- Verify no other export/checkpoint operations in progress
Debug Mode
Run with verbose output:
.\hyper-v-backup.ps1 -Verbose
Best Practices
- Test First - Always test backups manually before scheduling
- Monitor Space - Ensure adequate space on both temp and backup locations
- Verify Backups - Periodically test restore from backups
- Secure Credentials - Use Machine-level environment variables, never store passwords in scripts
- Schedule Wisely - Run backups during low-usage periods
- Review Logs - Check backup summaries regularly
- Update Retention - Adjust
retentionCountbased on storage capacity - Exclude Carefully - Only exclude VMs that don't need backup
Security Considerations
- Credentials are stored Base64-encoded in Machine-level environment variables (not encryption, just encoding)
- Script requires Administrator privileges
- Network credentials are passed to
net usecommand - Consider using dedicated backup account with minimal required permissions
- Backup data should be stored on secured network shares with appropriate ACLs
Performance Considerations
- Export time depends on VM size and disk I/O performance
- Temp location should be on fast local storage (SSD recommended)
- Network speed affects copy time to remote shares
- Checkpoints consume disk space temporarily
- Multiple VMs are processed sequentially (not parallel)
Version History
1.0.0 (2026-01-24)
- Initial production release
- Automated backup with scheduling
- Export-VM based backup (handles checkpoints internally)
- Retention management
- UNC share support with credential management
- Lock file and interval control
- Comprehensive error handling and logging
1.0.1 (2026-01-26)
- Improved disk space checking: Dynamic per-VM validation (1.5x VM size) for temp and destination
- Removed static
minFreeSpaceGBsetting in favor of smart per-VM space checks - Enhanced checkpoint retention: Keep last 2 backup checkpoints for rollback capability
- Removed manual checkpoint creation (Export-VM handles checkpoints internally)
- Improved UNC path validation
- Better error messages for space-related failures
- Performance improvement: Skip unnecessary space checks
- Refactored parameter splatting for Invoke-ScheduledExecution
Support
For issues or questions:
- Check the Troubleshooting section
- Review script logs for error details
- Verify all Requirements are met
- Check Hyper-V event logs for VM-related issues
License
See LICENSE in the root directory.
Related Files
../SchedulerTemplate.psm1- Shared scheduling and logging modulescriptsettings.json- Configuration filehyper-v-backup.bat- Batch launcherhyper-v-backup.ps1- Main script