我想在 Hyper-V 2012 上 克隆正在运行的VM 的虚拟磁盘。
我知道对 VM 进行快照会生成一个差异磁盘(文件扩展名为 .AVHDX)。所有后续写入都针对此快照,并且其父级是只读的。
但是,该父级也可能是快照,这意味着我不能简单地复制父级。
如何在我的快照之前获取包含所有虚拟硬盘驱动器数据的单个文件?
换句话说,如何将当前快照的父级导出到单个 .VHDX 文件?
理想情况下,我想知道如何使用 Hyper-V V2 WMI API 做到这一点。
我想在 Hyper-V 2012 上 克隆正在运行的VM 的虚拟磁盘。
我知道对 VM 进行快照会生成一个差异磁盘(文件扩展名为 .AVHDX)。所有后续写入都针对此快照,并且其父级是只读的。
但是,该父级也可能是快照,这意味着我不能简单地复制父级。
如何在我的快照之前获取包含所有虚拟硬盘驱动器数据的单个文件?
换句话说,如何将当前快照的父级导出到单个 .VHDX 文件?
理想情况下,我想知道如何使用 Hyper-V V2 WMI API 做到这一点。
使用 Windows 2012 R2?
您可以使用Msvm_VirtualSystemManagementService 类的 ExportSystemDefinition 方法直接导出
来自 Taylor Brown 的PowerShell 示例:
# Obtain Msvm_ComputerSystem object corresponding to VM to export
$vmName = "MyVirtualMachine"
$Msvm_ComputerSystem = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_ComputerSystem -Filter "ElementName='$vmName'"
# Edit copy of the Msvm_VirtualSystemExportSettingData associated with your VM
$Msvm_VirtualSystemExportSettingData = $Msvm_ComputerSystem.GetRelated("Msvm_VirtualSystemExportSettingData","Msvm_SystemExportSettingData",$null,$null, $null, $null, $false, $null)
$Msvm_VirtualSystemExportSettingData.CopySnapshotConfiguration = 0 # 0=ExportAllSnapshots, 1=ExportNoSnapshots, 2=ExportOneSnapshot
# Call ExportSystemDefinition method of Msvm_VirtualSystemManagementService singleton
$Msvm_VirtualSystemManagementService = Get-WmiObject -Namespace root\virtualization\v2 -Class Msvm_VirtualSystemManagementService
$Msvm_VirtualSystemManagementService.ExportSystemDefinition($Msvm_ComputerSystem, "c:\export_folder", $Msvm_VirtualSystemExportSettingData.GetText(1))
Hyper-V 2012 及更高版本支持快照的实时合并,但不支持正在运行的 VM 的导出。
Hyper-V 2012 R2 支持实时导出。所以,升级并继续前进,这里没什么可看的。
然而...
如果您拍摄虚拟机的快照,则可以将差异磁盘添加到快照的父磁盘,从中创建虚拟机,导出该虚拟机,然后销毁虚拟机,然后销毁差异磁盘。
看起来很迂回,但这是我知道“克隆”正在运行的 Hyper-V VM 的唯一方法(因为 VHD 成为问题,可以复制设置并创建新的 VM,这些设置不需要被“克隆”)。
如果您的 VM 没有任何快照,那么您需要创建一个以使其正常工作。您将“克隆”快照,同时允许正在运行的 VM 状态写回称为“现在”的 AVHDX。
由于正在创建的这个副本从未打开电源,因此 CPU 和 RAM 无关紧要。
因为这不是快照,所以通过导出 Hyper-V 可为您提供差异磁盘和父磁盘。
如果您导出快照,您将获得一个虚拟磁盘,因为 Hyper-V 对 AVHDX 文件执行特殊操作。
如果您想要一个文件,则合并导出中的差异。合并最终会破坏导出 VM 的配置,因为差异磁盘已删除,因此您必须重命名它。
但同样,我们这样做是为了以非常干净(且正确)的方式获取磁盘副本。
是的,运行出口需要做很多工作。并避免虚拟磁盘的任何文件锁定问题。
没有时间写完整的代码,但我通过 PowerShell 来验证它是否可行。
$snap = Get-VMSnapshot "datest"
PS C:\Windows\system32> $snap.HardDrives
VMName ControllerType ControllerNumber ControllerLocation DiskNumber Path
------ -------------- ---------------- ------------------ ---------- ----
DATest IDE 0 0 D:\DATest\Server2012.vhdx
PS C:\Windows\system32> New-VHD -Differencing -ParentPath $snap.HardDrives[0].Path -Path D:\test\test.vhdx
ComputerName : SWEETUMS
Path : D:\test\test.vhdx
VhdFormat : VHDX
VhdType : Differencing
FileSize : 4194304
Size : 42949672960
MinimumSize : 42948624384
LogicalSectorSize : 512
PhysicalSectorSize : 4096
BlockSize : 2097152
ParentPath : D:\DATest\Server2012.vhdx
FragmentationPercentage :
Alignment : 1
Attached : False
DiskNumber :
IsDeleted : False
Number :
PS C:\Windows\system32> New-VM -Name Test -Path D:\Test -VHDPath D:\test\test.vhdx
Name State CPUUsage(%) MemoryAssigned(M) Uptime Status
---- ----- ----------- ----------------- ------ ------
Test Off 0 0 00:00:00 Operating normally
Export-vm -Name Test -Path d:\newTest -Passthru
# Get the FullName of the parent disk for renaming later
Merge-VHD 'D:\NewTest\Test\Virtual Hard Disks\test.vhdx' -Force
Rename-Item 'D:\NewTest\Test\Virtual Hard Disks\Server2012.vhdx' 'D:\NewTest\Test\Virtual Hard Disks\test.vhdx'
我现在必须把所有这些都写在博客上。。