Skip to main content
RunBook Academy

Proxmox VEXXI · Migration to ProxmoxHyper-V to Proxmox

Migrating from Hyper-V: VHDX conversion and Generation 1/2 handling

Advanced⏱ ~25 minqemu-imgPowerShell on Hyper-V host optional

What you'll learn

  • Export Hyper-V VMs in formats Proxmox can import
  • Convert VHDX disks and handle Generation 1 vs Generation 2 differences
  • Resolve Hyper-V-specific quirks synthetic drivers, integration services
  • Validate and troubleshoot migrated Hyper-V guests

Prerequisites

Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-07

Not yet marked complete on this device.

Hyper-V in context

Hyper-V ships with every Windows Server licence and is widely deployed in Microsoft shops. Common drivers, formats, and toolchain:

  • Disk format: VHDX (modern, default since Server 2012 R2) or VHD (legacy)
  • VM definitions: Generation 1 (BIOS, IDE, legacy NIC) or Generation 2 (UEFI, SCSI, secure boot)
  • Synthetic drivers: Hyper-V Integration Services (Linux: hyperv_* kernel modules; Windows: built-in since 2012 R2)

The good news: VHDX is well-supported by qemu-img, and Linux Hyper-V guests are some of the easiest to migrate. Windows guests need Integration Services removed before KVM boot.

Generation 1 vs Generation 2

This is the single most important thing to know about Hyper-V migrations.

AspectGeneration 1Generation 2
FirmwareBIOSUEFI
Default disk controllerIDESCSI
Boot modeMBRGPT
Secure BootNoYes
Proxmox equivalentSeaBIOS + IDE/SCSIOVMF + SCSI

Step 1: Export the VM from Hyper-V

Two options for getting the disk off the Hyper-V host.

Option A: PowerShell export (preserves configuration)

# On the Hyper-V host
Export-VM -Name "Web01" -Path "D:\Exports" -CaptureLiveState CaptureDataConsistentState

# Result: D:\Exports\Web01\Virtual Hard Disks\Web01.vhdx
# Plus a .exp export bundle you can extract for the configuration

Option B: Copy the VHDX directly

If the VM is shut down, the VHDX is just a file. Copy it via SMB, robocopy, or any other file transfer.

# Shutdown first
Stop-VM -Name "Web01"

# Copy off
robocopy "D:\VMs\Web01\Virtual Hard Disks\Web01.vhdx" "\\proxmox\tmp\" Web01.vhdx

Step 2: Convert

# Inspect first
qemu-img info Web01.vhdx

# VHDX to qcow2 (Linux guest, Generation 1 or 2)
qemu-img convert -f vhdx -O qcow2 Web01.vhdx vm-102-disk-0.qcow2

# Or to raw for LVM-thin
qemu-img convert -f vhdx -O raw Web01.vhdx vm-102-disk-0.raw

# Verify
qemu-img check vm-102-disk-0.qcow2

Step 3: Create the Proxmox VM shell

The key parameter is the firmware:

# Generation 1 (BIOS) VM
qm create 102 --name "web01" --memory 4096 --cores 4 \
  --net0 virtio,bridge=vmbr0 \
  --bios seabios \
  --boot order=scsi0

# Generation 2 (UEFI) VM
qm create 102 --name "web01" --memory 4096 --cores 4 \
  --net0 virtio,bridge=vmbr0 \
  --bios ovmf --efidisk0 local-lvm:1,efitype=4m,pre-enrolled-keys=1 \
  --boot order=scsi0

Step 4: Import and attach

qm importdisk 102 vm-102-disk-0.qcow2 local-lvm -format qcow2
qm set 102 --scsi0 local-lvm:vm-102-disk-0

# If Generation 2 originally, the disk is GPT. Force virtio-scsi-single (modern default)
qm set 102 --scsihw virtio-scsi-single

# Start it
qm start 102

Linux guest quirks

Linux guests with Hyper-V Integration Services have these kernel modules installed:

  • hv_vmbus, hv_storvsc, hv_netvsc — disk and network
  • hv_utils, hv_balloon, hv_timesync — utilities

These are harmless on KVM. The kernel will simply not load them or use them — the initramfs will pick up virtio devices instead. You can leave them in; some admins uninstall them for cleanliness but it’s not required.

# Optional: clean up the hyperv modules from initramfs
# Debian/Ubuntu
sed -i '/hv_/d' /etc/initramfs-tools/modules
update-initramfs -u

# RHEL/CentOS
# Remove the hv_* entries from /etc/dracut.conf.d/ then
dracut -f

Windows guest quirks

Windows guests with Hyper-V Integration Services enabled store “synthetic” drivers in the critical device database. Booting on KVM can confuse Windows into trying to load the wrong driver stack.

The fix: install the virtio drivers before the first boot, similar to VMware.

The boot-time install trick

You can’t easily install virtio drivers inside a Hyper-V VM that’s still running there. Options:

  1. Pre-install with merged ISO — mount a Windows ISO + virtio ISO inside Hyper-V using a second virtual DVD drive, install the drivers, shut down, migrate. (Requires VM downtime.)
  2. Post-conversion with IDE boot — convert, create the Proxmox VM with --scsihw ide (or even --ide2 for the boot disk), boot, install virtio drivers, shut down, switch to virtio-scsi, boot again.
  3. virt-v2v-injectedvirt-v2v -i vmx ... style injection works for Hyper-V via virt-v2v -i hyperv if you have the libvirt hyperv driver configured.

Network mapping

Hyper-VProxmox
External virtual switch on eth0vmbr0 on eth0
Internal switch LabNet (no uplink)vmbr1 (host-only)
VLAN ID on the virtual switchSDN VNet with VLAN tag, or tagged on vmbr0
Network adapter “Network Adapter” (synthetic)virtio model
Legacy network adapter (emulated)e1000 model (slow)

For Linux guests, the hv_netvsc synthetic NIC works in KVM via the netvsc shim — but it requires the hyperv-daemons package and the hv_netvsc driver to be present. Cleaner to switch to virtio-net in the Proxmox config.

Step 5: Validation

  • Boots to login prompt
  • Network connectivity
  • Disk performance (compare before/after with fio if perf-critical)
  • Backup runs (PBS job completes)
  • Live migration works
  • Windows: Device Manager has no errors, no “unknown” devices
  • Windows: Activation still valid

Common issues

Issue: VM boots to UEFI shell instead of OS. Cause: Generation 2 VM but Proxmox set to SeaBIOS. Fix: qm set 102 --bios ovmf and ensure an EFI disk is attached.

Issue: “INACCESSIBLE_BOOT_DEVICE” blue screen. Cause: Windows can’t find the boot disk because it’s on virtio-scsi without drivers. Fix: Boot with --ide2 local-lvm:vm-102-disk-0,format=qcow2 (temporarily), install virtio drivers, switch back to SCSI.

Issue: Linux VM boots but no network. Cause: hyperv-daemons removed but /etc/network/interfaces still references the old eth0 from hyperv_netvsc. Fix: Configure the virtio NIC inside the guest; the name will likely change from eth0 to ens3 or similar.

Issue: VM boots but filesystem is read-only. Cause: initramfs missing virtio_blk module. Fix: Boot into a rescue ISO, mount the root filesystem, regenerate initramfs.

Key takeaways

  • Hyper-V VHDX files convert with qemu-img convert -f vhdx
  • Match Generation 1 → SeaBIOS, Generation 2 → OVMF
  • Linux guests migrate cleanly; kernel handles the hyperv → virtio transition
  • Windows guests need virtio drivers installed before first KVM boot
  • Watch for Windows activation; Hyper-V may have used a different “hardware” profile

Knowledge check

Knowledge check · 4 questions

  1. Q1. A Hyper-V Generation 2 VM uses which firmware mode in Proxmox?

  2. Q2. Which command exports a Hyper-V VM and captures a crash-consistent state?

  3. Q3. Which qemu-img flag identifies a VHDX file for conversion?

  4. Q4. Reconstruct the answer from the lesson context.

Passing score: 75%. Answers are checked in this browser.