Running Hyper-V in Windows on ARM

Edit: Windows 10 Insiders Build 19559 now fully supports Hyper-V and includes the management tools. Treat this guide as a way to do things from an alternative means. There's one thing in this post that still does apply, regardless .

Yes, this is not a prank. It is totally possible to run virtual machines in Hyper-V from Windows 10 ARM64. It's one of the main things that I've wanted to do since buying my Surface Pro X, since my ASUS NovaGo had an SoC that doesn't have the proper virtualization capabilities. If you're ready to virtualize, then let's go!

Prerequisites

  • A Windows 10 ARM64 device with an SoC that has the right capabilities to run WSL2. This will not work with the first-gen devices like those that contain a Snapdragon 835.
  • I've tested this on build 19555, so I can't speak for any earlier builds.
  • Remote Desktop Connection Manager
  • WindowsImageTools PowerShell Package
  • Windows 10 ARM64 installation media (I'm not providing this. You're on your own. If you ask me, I'm going to point you back to this bullet-point).


Installing Hyper-V


There are at least three different ways to install Hyper-V, but we're going to focus on doing it through PowerShell since you'll be running commands for many things in this post. First thing to do is to load an elevated PowerShell process (Run as Administrator), then run the command to enable the Hyper-V feature.

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V –All


If the command is successful, you'll be prompted to restart. Before moving on to the next session, be sure to open up another elevated PowerShell process or else none of the commands will work.

Creating and Managing Virtual Machines


At the time of this post, the Hyper-V Management Console Snap-in doesn't install even though a shortcut in the Start Menu does. Luckily, we can still utilize the Hyper-V PowerShell Cmdlets to do everything we would normally do from the GUI.


Creating the Virtual Machine

To create a Virtual Machine through PowerShell, the nifty New-VM cmdlet does the trick. We're going to create a VM named "Win10ARM" with 2GB RAM and 2 CPU. We're not going to need to attach a virtual hard drive yet, so we're going to skip it for now.


New-VM -Name "Win10ARM" -MemoryStartupBytes 2GB –Switch "Default Switch" | Set-VMProcessor -Count 2


To see information about your newly created VM, you can run the Get-VM cmdlet while passing the name of your VM into the Name parameter.


Get-VM -Name "Win10ARM" | select Name, VMId, MemoryStartup, ProcessorCount


How do we connect to the virtual machine? This is where the Remote Desktop Connection Manager comes in. We need this program since the VMConnect application that opens an RDP connection to the VM also didn't install with the feature at the time of this post.


Connecting to the Virtual Machine

Assuming you've installed Remote Desktop Connection Manager, connecting to the virtual machine involves creating a remote desktop group, and adding a server with VM console connect enabled.

The VMId property of the Get-VM cmdlet above will be needed in order to connect to it from this app.



There are a few things you'll run into upon attempting to connect for the first time, but luckily Erwin Bierens made a blog post that outlines how to get past the roadblocks. Once you've gone through the steps, you'll be ready to connect.



In order to power on the VM, run the Start-VM cmdlet.


Start-VM -Name Win10ARM


After running the cmdlet, you can connect to the VM from the Remote Desktop Connection Manager.


By now, you should be excited that we made it this far. Now for the fun part! Upon acquiring your Windows 10 ARM64 ISO, WIM, or ESD – we will convert it to an VHDX and attach it to the VM by using the Convert-Wim2VHD cmdlet from the WindowsImageTools PowerShell package. The following command will do the job. Modify the Path, SourcePath and Size parameters with your own configuration.


Convert-Wim2VHD -Path c:\somefolder\Win10ARM.vhdx -SourcePath "C:\pathto\TheWin10ARM64Image.iso" -Size 30GB -Dynamic -DiskLayout UEFI -force


By now, you will have a Win10ARM.vhdx on your filesystem somewhere. To attach this to your VM, first we'll need to power it off, attach the virtual harddrive, set it as the first boot source, then power it back on. You will have to connect to the VM again from RDCMan.


$vm = Get-VM -Name Win10ARM;

$vm | Stop-VM -Name Win10ARM;

$vm | Add-VMHardDiskDrive -Path c:\somefolder\Win10ARM.vhdx;

$vm | Set-VMFirmware -FirstBootDevice ($vm | Get-VMHardDiskDrive);

$vm | Start-VM


This should walk you through the same Windows 10 setup that you're used to and similar to the tweet that caused me to make this blog post



Quick Closing Remarks

From what I've seen so far, this runs pretty darn well! The x86 emulation works from within the Windows 10 ARM64 VM and I could actually use it to test updates without blowing up my main machine. I initially embarked on this journey because I couldn't get Windows Sandbox and WDAG working properly. I'm curious to what is in store for virtualization with ARM64 SoCs. One thing I know you won't be doing right now is running VMs within a VM. Enabling the Virtual Machine Platform feature will make it hang at boot.

Also, don't even try to connect x86 ISOs to the VM. It won't boot. I'm hoping this post will kickstart the Linux distros to incorporate the Hyper-V fixes made in order for WSL2 to function properly and bring more people to use Windows on ARM and even adopt ARM64 heavily.

Enjoy!