Step-by-Step Guide: Converting VMWare VMDK to Hyper-V VHD with Reliable Methods and Troubleshooting Tips


2 views

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:

  1. Verify the VMDK isn't using unsupported features like snapshots or compression
  2. Try converting to VHD first instead of VHDX
  3. 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"
}