命令行备份恢复Hyper-V虚拟机

自从Windows Server 2012开始,微软增加了存储池和去重功能,我就开始增大Hyper-V的使用范围。

早期的在线备份直接用disk2vhd.exe做脚本备份,当然这个方法也适用于P2V。

自从Windows Server 2016开始,Hyper-V就不再支持VHD格式,仅支持VHDX格式了,同样的,disk2vhd高版本虽然也支持VHDX,但是在老一些的系统上,只能用低版本disk2vhd就无法满足需求了。

搜索一番,如果只备份比较简单

备份指定虚拟机

1
Export-VM -Name "tKC-VM" -Path "D:\vmbak"

备份所有虚拟机

1
Get-VM | Export-VM -Path "D:\vmbak"

导入虚拟机

1
Import-VM -Path 'D:\<vm export path>\2D91FED3-F1E0-4FFF-D8DE-29CED892A95A.vmcx'

使用新ID导入虚拟机

1
Import-VM -Path 'D:\<vm export path>\2D91FED3-F1E0-4FFF-D8DE-29CED892A95A.vmcx' -Copy -GenerateNewId

如果有差异备份恢复的需求,可以用下面这个powershell脚本,安装使用方法如下:

首先是安装改PowerShell组件,源自 https://www.powershellgallery.com/packages/xHyper-VBackup/

1
Install-Module -Name xHyper-VBackup

备份脚本:

1
2
3
4
5
6
7
8
9
10
11
$vmName = "tKC-VM" # 需要备份的虚拟机名称
$fullBackupPath = "D:\vmbak\$vmName\Full" # 虚拟机完整备份路径

# 创建和保存该虚拟机最新快照信息
$checkpoint = New-VmBackupCheckpoint -VmName $vmName -ConsistencyLevel CrashConsistent

# 导出该快照到前面目标文件夹
Export-VMBackupCheckpoint -VmName $vmName -DestinationPath $fullBackupPath -BackupCheckpoint $checkpoint

# 删除刚才创建的快照
Convert-VmBackupCheckpoint -BackupCheckpoint $checkpoint

恢复完整备份:

1
2
3
4
5
6
7
8
9
10
11
12
$vmName = "tKC-VM" # 需要恢复的虚拟机名称
$fullBackupPath = "D:\vmbak\$vmName\Full" # 完整备份路径
$restorePath = "D:\Restored-Full\$vmName"

# 查找虚拟机配置文件
$vmConfigFile = Get-ChildItem -Path $fullBackupPath -Recurse -Include "*.vmcx"

# 从备份导入虚拟机
$imported = Import-VM -Path $vmConfigFile.FullName -GenerateNewId -Copy -VirtualMachinePath $restorePath -VhdDestinationPath "$restorePath\Virtual Hard Disks"

# (可选) 重命名虚拟机
$imported | Rename-VM -NewName "$($imported.Name)-restored-full"

增量备份:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$vmName = "tKC-VM" # 需要备份的虚拟机名称
$diffBackupPath = "D:\vmbak\$vmName\Diff_$(Get-Date -UFormat "%Y-%m-%d_%H%M%S")" # 增量备份路径

# 创建和保存该虚拟机最新快照信息
$checkpoint = New-VmBackupCheckpoint -VmName $vmName -ConsistencyLevel CrashConsistent

# 选择用于差异备份的参考点
$referencePoint = Get-VmReferencePoints -VmName $vmName

# 导出差异备份
Export-VMBackupCheckpoint -VmName $vmName -DestinationPath $diffBackupPath -BackupCheckpoint $checkpoint -ReferencePoint $referencePoint

# Removes backup snapshot and converts it as reference point for future incremental backups
Convert-VmBackupCheckpoint -BackupCheckpoint $checkpoint

恢复差异备份:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$vmName = "tKC-VM" # 需要恢复的虚拟机名称
$fullBackupPath = "D:\vmbak\$vmName\Full" # 完整备份路径
$diffBackupPath = "D:\vmbak\$vmName\Diff_$(Get-Date -UFormat "%Y-%m-%d_%H%M%S")" # 差异备份路径
$restorePath = "D:\Restored-Diff\$vmName"

# 提前从完整备份中复制虚拟磁盘,以确保在导入期间差异可以正确合并
$disksPathSource = Join-Path $fullBackupPath "Virtual Hard Disks"
$diskPathDestination = Join-Path $restorePath "Virtual Hard Disks"
Copy-Item $disksPathSource $diskPathDestination -Recurse -Force -ErrorAction SilentlyContinue

# 查找虚拟机配置文件
$vmConfigFile = Get-ChildItem -Path $diffBackupPath -Recurse -Include "*.vmcx"

# 从备份导入虚拟机
$imported = Import-VM -Path $vmConfigFile.FullName -GenerateNewId -Copy -VirtualMachinePath $restorePath -VhdDestinationPath "$restorePath\Virtual Hard Disks"

# (可选) 重命名虚拟机
$imported | Rename-VM -NewName "$($imported.Name)-restored-diff"