When migrating virtual machines from VMWare to Hyper-V, the most critical step is converting the virtual disk format. The VMDK (Virtual Machine Disk) format used by VMWare needs to be converted to Hyper-V's native VHD or VHDX format.
The Microsoft Virtual Machine Converter (MVMC) is the recommended solution for enterprise environments:
# PowerShell command to install MVMC
Install-PackageProvider -Name NuGet -Force
Install-Module -Name Microsoft.VirtualMachineConverter -Force
Conversion command example:
ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath "C:\vm\myvm.vmdk" -DestinationLiteralPath "D:\hyperv\converted.vhdx" -VhdType DynamicHardDisk -VhdFormat Vhdx
For cases where MVMC or vmdk2vhd fails with "Invalid vmdk" errors:
# Using qemu-img (cross-platform solution)
qemu-img convert -O vhdx -o subformat=dynamic input.vmdk output.vhdx
# Using StarWind V2V Converter (GUI option)
# Free tool that handles complex VMDK configurations
When encountering "Invalid vmdk" errors:
- Verify the VMDK isn't using unsupported features like snapshots or compression
- Try converting to VHD first instead of VHDX
- Use VMWare's vmkfstools to repair the VMDK first:
vmkfstools --repair mydisk.vmdk
For production environments:
- VHDX offers better performance than VHD (supports larger sizes and 4KB sectors)
- Dynamic disks save space but fixed disks offer better performance
- Consider aligning partitions to 4KB boundaries for optimal performance
PowerShell script for batch processing:
$vmdkFiles = Get-ChildItem -Path "C:\vmware\*.vmdk"
foreach ($file in $vmdkFiles) {
$vhdPath = "D:\hyperv\" + $file.BaseName + ".vhdx"
ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath $file.FullName -DestinationLiteralPath $vhdPath -VhdType FixedHardDisk -VhdFormat Vhdx
}
When migrating virtual machines from VMware to Hyper-V, the disk format conversion from VMDK to VHD/VHDX is often the trickiest part. While Microsoft's official vmdk2vhd
tool exists, many administrators (including myself) have encountered its "Invalid vmdk" errors with perfectly valid disks.
Here are three battle-tested approaches I've used in production environments:
Method 1: Using Microsoft's Virtual Machine Converter (MVMC)
As MSDN subscribers, you have access to this official tool:
# Download from MSDN
Install-Module -Name Microsoft.VirtualMachineConverter -Force
# Convert command
ConvertTo-MvmcVirtualHardDisk -SourceLiteralPath "C:\vm\vmware.vmdk"
-DestinationLiteralPath "C:\hyperv\converted.vhdx"
-VhdType DynamicHardDisk
-VhdFormat Vhdx
Method 2: QEMU's qemu-img (Most Reliable)
This open-source tool handles even problematic VMDKs:
# Install on Windows via Chocolatey
choco install qemu
# Conversion command
qemu-img convert -p -O vhdx "source.vmdk" "output.vhdx"
# For fixed-size VHD (required for Gen1 VMs)
qemu-img convert -p -O vpc "source.vmdk" "output.vhd" -o subformat=fixed
Method 3: Hyper-V Manager's Import
For VMware OVF exports:
# PowerShell alternative
Import-VM -Path "C:\exported_vm\vm.ovf" -Copy -GenerateNewId
Problem: "Invalid VMDK" errors
Solution: Check disk integrity first:
qemu-img info problem.vmdk
vmware-vdiskmanager -R problem.vmdk
Problem: Converted VHD won't boot
Solution: Ensure proper disk controller emulation:
Set-VMHardDiskDrive -VMName MyVM -ControllerType SCSI
For production workloads, always:
- Use VHDX format (supports >2TB and better performance)
- Enable TRIM on dynamic disks:
Optimize-VHD -Path disk.vhdx -Mode Full
- Align partitions after conversion (use diskpart's
create partition align=1024
)
Here's a complete PowerShell script I use for bulk conversions:
# BulkVMDKtoVHDX.ps1
param(
[string]$sourceDir,
[string]$destDir
)
$vmdks = Get-ChildItem -Path $sourceDir -Filter *.vmdk
foreach ($vmdk in $vmdks) {
$outputPath = Join-Path -Path $destDir -ChildPath ($vmdk.BaseName + ".vhdx")
Write-Host "Converting $($vmdk.Name) to VHDX..."
& qemu-img convert -p -O vhdx $vmdk.FullName $outputPath
if ($LASTEXITCODE -ne 0) {
Write-Warning "Failed to convert $($vmdk.Name)"
continue
}
Optimize-VHD -Path $outputPath -Mode Full
Write-Host "Successfully converted to $outputPath"
}