Wednesday, 12 August 2015

Converting a Hyper-V guest to Linux KVM

Recently I have been doing work with Microsoft Virtualisation and getting guest replication working. However due to the setup of the rest of the infrastructure, it wasn't possible for me to use Hyper-V replication on Windows Server 2012 R2. As such, found myself finding ways to migrate Windows Server from Hyper-V to another solution (in this instance it was Linux KVM).

Migrating a Hyper-V UEFI Generation 2 Windows server 2012 R2 guest to a Linux KVM host is possible, but required some thought and time.

If you are using a Windows Server 2008 R2 guest, you are most likely using this with a normal BIOS, MBR partition, and Generation 1 Hyper-V config. In this case migration is straight forward, you can convert the disk with qemu-img and attach this without issues. For Windows Server 2012 R2 / Hyper-V Generation 2 servers using GPT, I have found that the guest would crash when trying to boot into Windows.

Having spent a couple weeks trying different ways to get this to work I now have a complete and comprehensive way of migrating a Hyper-V Generation 2 UEFI Windows Server 2012 R2 guest to Linux KVM BIOS.


You will need the below:
  • Windows PE boot disk with diskpart.exe imagex.exe bootrec.exe bootsect.exe and bcdboot.exe (I will not be explaining how to create this disk or where to obtain the software tools or how to create a Windows PE disk in this article)
  • Windows Hyper-V server you wish to migrate.
  • Local administrator account.
  • Linux KVM server. We are using the standard KVM/Qemu tools that come with CentOS 6.6.
  • The Linux VirtIO drivers (.iso format is acceptable)

Note – the guest server can be using a .vhdx or .vhd disk format as long as it is using a fixed sized disk. If is it a dynamic disk you will need to shut down the VM and use the builtin Hyper-V tool in Hyper-V Manager to convert it to a fixed size disk. If you attempt to convert a Hyper-V dynamic size disk to another format on the Linux KVM server you will get a read error from the Qemu tools.


Get the VirtIO drivers onto the Hyper-V guest. You can attach the .iso and copy all the folders onto a directory on the server.
Make a record of disks and drive letters, and networking configuration. Shutdown the server and copy the virtual hard disks over to your Linux server.

Using qemu-img convert all the disks to a raw .img disk
sudo qemu-img convert -p SYSTEM.vhdx -O raw SYSTEM.img

Create a new Virtual Machine, attach and boot from the Windows PE disk, attach the raw system/boot virtual hard disk (IDE – not VirtIO), and create and attach a spare disk greater than the size of the system/boot disk (this is best as a raw image IDE – not VirtIO).

Once booted into WindowsPE, use diskpart to prepare the spare disk by creating a primary partition, formatting it to NTFS and assign a drive letter.
select disk 1
create partition primary
format fs=ntfs quick label=spare

Use imagex to capture the C:\ of the existing system disk and place the image as a .wim on the newly prepared spare disk.
imagex /capture c:\ d:\capture.wim “description of image”

Now we can clear the system disk of all partition tables, re-create a new primary partition, format for NTFS, assign a drive letter, and ensure it is set to active.
select disk 0
create partition primary
format fs=ntfs quick label=spare

Apply the captured .wim image using imagex.
imagex /apply d:\capture.wim 1 c:\

Optional – disable the spare disk using diskpart. Now we need to fix the boot record and sectors for the system disk.
BootRec.exe /fixmbr
bootsect.exe /nt60 all /force
BootRec.exe /rebuildbcd
bcdboot.exe c:\windows /l en-us

Once these have completed, shutdown the server and remove the spare disk and the Windows PE disk.
Optionally you can attach any other data disks the server had previously.

Start the server and ensure you can boot. If at this stage you have problems locating a bootable disk, you will need to boot back into the Windows PE boot disk and run through the instructions for fixing the boot record. If Windows crashes through the boot process, you potentially have a much larger problem, and may need to start back from converting the disk from the Hyper-V format to RAW .img.

The server should start up and allow you to login to a local user account. Ensure you login to the server and check things like the disks all have the correct drive letters and the network configure is as you would want it to be.

Bonus Round!!!

You may for reasons want to make use of the VirtIO disk/drivers or even go further than that to use a logical volume than a virtual disk.


To make your system disks use the VirtIO drivers you first need to shutdown the server and attach a new virtio disk of any size - the purpose for this is to ensure Windows loads the VirtIO drivers on boot. You may also want attach the .iso containing the VirtIO drivers if you don't already have them.

Start the server, check Windows to see if new disk is attached. You may have to go to disk management to find this, if you cannot see it here install the drivers from the .iso, the “viostor” driver should be sufficient.

Once you are able to see the disk in Windows Explorer, shutdown the server. Remove the temp disk and change all the existing disks from IDE to VirtIO (not VirtIO SCSI).

Start the server and ensure you can login.

If you are at this stage, you may also want to stop using an in-filesystem disk image and go straight to a logical volume for the Windows disks. Create the LV with the LVM tools and use the dd tool to copy from the raw .img to the logical volume, and then attach this as the disk instead.