如何在 Hyper-V 2012 上克隆正在运行的 VM 的虚拟磁盘



我想克隆Hyper-V 2012上运行的虚拟机的虚拟磁盘。

我知道快照 VM 将生成一个差异磁盘(文件扩展名 .AVHDX(。 所有后续写入都针对此快照,其父级是只读的。

但是,该父项

也可能是快照,这意味着我不能简单地复制父项。

如何在快照之前获取包含所有虚拟硬盘驱动器数据的单个文件?

换句话说,如何将当前快照的父级导出为单个.VHDX 文件?

理想情况下,我想知道如何使用 Hyper-V V2 WMI API 执行此操作。

>Hyper-V 2012 及更高版本支持快照的实时合并,但不支持导出正在运行的 VM。
Hyper-V 2012 R2 支持实时导出。 所以,升级并继续前进,这里没有什么可看的。

然而。。。

如果拍摄 VM 的快照,则可以将差异磁盘添加到快照的父磁盘,从该磁盘创建 VM,导出该 VM,然后

销毁该 VM,然后销毁差异磁盘。

这似乎很迂回,但这是我所知道的"克隆"正在运行的Hyper-V VM的唯一方法(因为VHD成为问题,可以复制设置并创建新的VM,这些设置不需要"克隆"(。

如果 VM 没有任何快照,则需要创建一个快照才能完成此操作。 您将"克隆"快照,同时允许正在运行的虚拟机状态写回称为"现在"的 AVHDX。

由于正在创建的此副本永远不会打开电源,因此 CPU 和 RAM 无关紧要。

由于这不是快照,因此通过导出 Hyper-V 可为您提供差异磁盘和父级。
如果导出快照,则会获得单个虚拟磁盘,因为Hyper-V对AVHDX文件执行特殊操作。
如果需要单个文件,则合并导出中的差异。 合并最终会破坏导出的 VM 的配置,因为差异磁盘已删除,因此必须重命名它。
但同样,我们这样做是为了以一种非常干净(和适当(的方式获取磁盘的副本。

是的,运行导出需要做很多工作。 并避免虚拟磁盘出现任何文件锁定问题。

没有时间编写完整的代码,但我通过PowerShell演练了一下,只是为了验证它是否可行。

$snap = Get-VMSnapshot "datest"
PS C:Windowssystem32> $snap.HardDrives
VMName ControllerType ControllerNumber ControllerLocation DiskNumber Path                     
------ -------------- ---------------- ------------------ ---------- ----                     
DATest IDE            0                0                             D:DATestServer2012.vhdx

PS C:Windowssystem32> New-VHD -Differencing -ParentPath $snap.HardDrives[0].Path -Path D:testtest.vhdx

ComputerName            : SWEETUMS
Path                    : D:testtest.vhdx
VhdFormat               : VHDX
VhdType                 : Differencing
FileSize                : 4194304
Size                    : 42949672960
MinimumSize             : 42948624384
LogicalSectorSize       : 512
PhysicalSectorSize      : 4096
BlockSize               : 2097152
ParentPath              : D:DATestServer2012.vhdx
FragmentationPercentage : 
Alignment               : 1
Attached                : False
DiskNumber              : 
IsDeleted               : False
Number                  : 

PS C:Windowssystem32> New-VM -Name Test -Path D:Test -VHDPath D:testtest.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:NewTestTestVirtual Hard Diskstest.vhdx' -Force
Rename-Item 'D:NewTestTestVirtual Hard DisksServer2012.vhdx' 'D:NewTestTestVirtual Hard Diskstest.vhdx'

我现在必须写博客所有这些。

使用 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 rootvirtualizationv2 -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 rootvirtualizationv2 -Class Msvm_VirtualSystemManagementService
$Msvm_VirtualSystemManagementService.ExportSystemDefinition($Msvm_ComputerSystem, "c:export_folder", $Msvm_VirtualSystemExportSettingData.GetText(1))

最新更新