将VmWare虚拟磁盘转换为HyperV时出错

时间:2016-05-27 10:58:53

标签: vmware hyper-v virtual-disk

我从客户端收到VmWare图像用于某些测试目的。我需要将其转换为Hyper-V。 我按照http://www.askme4tech.com/how-convert-vmware-virtual-machine-hyper-v中的步骤进行操作。我安装了Microsoft Virtual Machine Converter并开始在PowerShell中转换虚拟磁盘。但是我感到很恐怖:

C:\Windows\system32> ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath "c:\temp\disk2.vmdk" -DestinationLiteralPath "c:\data\HyperV\PH\" -VhdType DynamicHardDisk -VhdFormat Vhdx

ConvertTo-MvmcVirtualHardDisk : The entry 1 is not a supported disk database entry for the descriptor.
At line:1 char:1
+ ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath "c:\temp\disk2.vmdk"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (Microsoft.Accel...nversionService:DriveConversionService) [ConvertTo-MvmcVirtualHardDisk], VmdkDescriptorParseException
    + FullyQualifiedErrorId : DiskConversion,Microsoft.Accelerators.Mvmc.Cmdlet.Commands.ConvertToMvmcVirtualHardDiskCommand

ConvertTo-MvmcVirtualHardDisk : One or more errors occurred.
At line:1 char:1
+ ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath "c:\temp\disk2.vmdk"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (Microsoft.Accel...nversionService:DriveConversionService) [ConvertTo-MvmcVirtualHardDisk], AggregateException
    + FullyQualifiedErrorId : DiskConversion,Microsoft.Accelerators.Mvmc.Cmdlet.Commands.ConvertToMvmcVirtualHardDiskCommand

7 个答案:

答案 0 :(得分:69)

我找到了一些特殊的解决方案 - 或许有点破解,但至少可以起作用。

深入研究google上发现的类似问题我找到了一个从VMDK文件中提取磁盘描述符的工具。我的VMDK描述符的内容是这样的:

# Disk DescriptorFile
version=1
encoding="windows-1252"
CID=5379bf0f
parentCID=ffffffff
isNativeSnapshot="no"
createType="monolithicSparse"

# Extent description
RW 209715200 SPARSE "00054_C8PHS1096_151216-disk2.vmdk"

# The Disk Data Base 
#DDB

ddb.adapterType = "lsilogic"
ddb.geometry.biosCylinders = "13054"
ddb.geometry.biosHeads = "255"
ddb.geometry.biosSectors = "63"
ddb.geometry.cylinders = "13054"
ddb.geometry.heads = "255"
ddb.geometry.sectors = "63"
ddb.longContentID = "64d4e008b7227bcce8aa54995379bf0f"
ddb.toolsInstallType = "1"
ddb.toolsVersion = "10241"
ddb.uuid = "60 00 C2 96 f7 70 f2 fd-b5 02 9e 46 6c df 00 2e"
ddb.virtualHWVersion = "10"

我注意到错误消息和提取的描述符的内容,特别是行:

ddb.toolsInstallType = "1"

因为它包含我的错误消息中1的奇怪值。我编辑了描述符 - 只注释掉带有#(哈希标记)的单行,将其注入VMDK并瞧 - 现在转换工作正常。

致信此链接https://communities.vmware.com/thread/343214?start=0&tstart=0,当然还有Dariusz Stanislawek的工具。

仅供参考,我已完成的步骤:

  • 下载并解压缩dsfok工具
  • 使用dsfo.exe "c:\temp\disk2.vmdk" 512 1024 descriptor1.txt提取描述符
  • 在Notepad ++中编辑描述符文件:注释上面提到的行(因为我添加了额外的单个字符(#)我还从末尾删除了一个NULL字符以保持文件大小为1024字节(不确定是否需要)。
  • 使用dsfi.exe "c:\temp\disk2.vmdk" 512 1024 descriptor1.txt将描述符注入VMDK
  • 为其他磁盘重复这些步骤(我的VM有两个.vmdk文件)
  • 重新发出ConvertTo-MvmcVirtualHardDisk命令

<强> REMARK

在Hyper-V中创建VM后,机器无法启动,它仍然保持黑屏,快速闪烁光标(所谓的黑屏死机)。我不知道它是由转换引起的还是由于VMWare中的原始磁盘是SCSI而我将它们作为IDE连接的事实。为了解决这个问题,我附上了带有Windows图像并从DVD启动的DVD。我运行了Rapair系统,启动了命令行并运行了

bootrec.exe /fixBoot

最后,VM启动并运行..故事结束。

答案 1 :(得分:15)

我有一个问题,试图将VMWare映像转换为VHD。我的解决方案类似于eXavier,但我只用文本编辑器就可以做到。

我可以做一个更简单的修复的原因是我从VMWare获得的vmdk是一个小文本文件,引用了许多其他文件。它看起来像这样:

# Disk DescriptorFile
version=1
encoding="windows-1252"
CID=4bd4d907
parentCID=ffffffff
isNativeSnapshot="no"
createType="twoGbMaxExtentSparse"

# Extent description
RW 8323072 SPARSE "Windows Server 2012-s001.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s002.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s003.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s004.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s005.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s006.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s007.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s008.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s009.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s010.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s011.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s012.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s013.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s014.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s015.vmdk"
RW 983040 SPARSE "Windows Server 2012-s016.vmdk"

# The Disk Data Base 
#DDB

ddb.adapterType = "lsilogic"
ddb.geometry.cylinders = "7832"
ddb.geometry.heads = "255"
ddb.geometry.sectors = "63"
ddb.longContentID = "439d288830654baf53d1f9594bd4d907"
ddb.toolsInstallType = "1"
ddb.toolsVersion = "10240"
ddb.uuid = "60 00 C2 97 21 a0 4e af-fc 21 68 15 2f 12 7f 22"
ddb.virtualHWVersion = "12"

修复是使用文本编辑器删除#Disk数据库行及其下面的所有行,以便我的文件看起来像这样:

# Disk DescriptorFile
version=1
encoding="windows-1252"
CID=4bd4d907
parentCID=ffffffff
isNativeSnapshot="no"
createType="twoGbMaxExtentSparse"

# Extent description
RW 8323072 SPARSE "Windows Server 2012-s001.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s002.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s003.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s004.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s005.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s006.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s007.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s008.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s009.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s010.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s011.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s012.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s013.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s014.vmdk"
RW 8323072 SPARSE "Windows Server 2012-s015.vmdk"
RW 983040 SPARSE "Windows Server 2012-s016.vmdk"

然后转换为VHD没有问题。

答案 2 :(得分:9)

我尝试了上面的解决方案,但在我的描述符中没有toolsInstallType属性,因此它没有工作(具有相同的错误)。

经过一番研究后,我找到了这个工具:https://cloudbase.it/qemu-img-windows/

命令是这样的:

qemu-img.exe convert c:\PATH_TO_FILE\disk.vmdk -O vhdx c:\PATH_TO_FILE\disk.vhdx -p

此工具的文档位于此处QEMU Documentation -p标志允许您查看转换的进度。

此外,我发现它更易于使用,因为它是一种便携式工具。在这种特定情况下,它也不需要修复引导加载程序,我只是将vhdx连接到新VM并且它已成功启动。

答案 3 :(得分:5)

我有另一个解决这个问题的解决方案对我有用,所以我想将它添加到任何未来的读者中。

我从这里下载了StarWindConverter工具(免费)。

https://www.starwindsoftware.com/tmplink/starwindconverter.exe

它支持多种目标格式,并为您提供了一个很好的向导演练。选择完所有选项后,您将看到如下进度屏幕:

progress-bar

将离线.vmdk文件转换为.vhdx的过程很简单。

答案 4 :(得分:3)

如果你仍然坚持转换,那么上述答案的补充。

在我的情况下qemu-img.exe convert ...方法成功,但结果 .VHD 图像无法在Hyper-V中启动:

Virtual hard disk files must be uncompressed and unencrypted and must not be sparse.

使用十六进制编辑器(编辑块0x100..0x200)或上述dsfi.exe / dsfo.exe方式在 .VMDK 文件中注释掉这些属性:

ddb.uuid.image="... Some guid here ..."
ddb.uuid.parent="00000000-0000-0000-0000-000000000000"
ddb.uuid.modification="00000000-0000-0000-0000-000000000000"
ddb.uuid.parentmodification="00000000-0000-0000-0000-000000000000"
ddb.comment=""

只需替换ddb -> #db

之后,MMVC转换为我成功而没有失败,输出图像有效:

Import-Module "C:\Program Files\Microsoft Virtual Machine Converter\MvmcCmdlet.psd1"
ConvertTo-MVMCVirtualHardDisk -SourceLiteralPath .\win10-32-disk1.vmdk -DestinationLiteralPath . -VHDFormat Vhdx -VHDType DynamicHardDisk

答案 5 :(得分:3)

这是使用powershell / .net的答案,它不需要您下载任何其他内容。这对我有用。 这里有一些关于它的文章:https://badflyer.com/vmdx-to-vhd-conversion/

VMDK描述符中可能存在某些转换cmdlet无法理解的内容。在这种情况下,仅将其注释掉就足够了。

如果未安装notepad ++,则需要更改打开的编辑器。

第1步:

# Open VM-ware disk, read 1024 bytes at position 512
$vmdkFileName = 'D:\VM\CNC Windows 7 Professional\Windows 7 Professional-cl1.vmdk'
$vmdkFileStream = [System.IO.File]::Open($vmdkFileName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite)
$vmdkFileStream.Position = 512

$bytes = [byte[]]::new(1024);
$vmdkFileStream.Read($bytes, 0, 1024)

# Write to a temp file
$tempPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetTempFileName())
$tempfile = [System.IO.File]::OpenWrite($tempPath)
$tempfile.Write($bytes, 0, 1024)
$tempfile.Dispose()

# Open the editor. Wait for exit doesn't always seem to work for npp...
# Use whichever edit you like, it needs to show text, and also helpful if it can show whitespace/control characters
$editor = Start-Process 'C:\Program Files\Notepad++\notepad++.exe' -ArgumentList $tempPath -PassThru -Wait
$editor.WaitForExit()

# TODO, change what is causing the problem in the opened file.

如果错误消息抱怨“ 1”,则在描述符中查找值为“ 1”的行。例如:ddb.toolsInstallType =“ 1” 您可以像这样将其注释掉:

# ddb.toolsInstallType = "1"

然后保存编辑器,并将字节写回到VMDK。确保保存时使用的编辑器不会更改数据的编码...

第2步:

# Read back the temp file
$tempfile = [System.IO.File]::OpenRead($tempPath)
$tempfile.Read($bytes, 0, 1024);
$tempfile.Dispose()

# Write back to the vmdk
$vmdkFileStream.Position = 512
$vmdkFileStream.Write($bytes, 0, 1024)

# Cleanup
$vmdkFileStream.Dispose();
del $tempPath

现在再次尝试转换。

答案 6 :(得分:0)

现代VMDK文件具有一个主描述符文件和单独的数据文件。无需使用dsfo / dsfi工具。

  • Ubuntu.vmdk <-描述符

  • Ubuntu-s001.vmdk,Ubuntu-s002.vmdk等。<-数据文件

在这种情况下,您只需要注释以下行即可:

#ddb.toolsInstallType = "4"