Hyper-V | Assign Graphics Card to Virtual Machine
Table of Contents
INTRO
A while back I wanted to see how I could get a graphics card installed in my Hyper-V Server 2019 Core host to map to a VM of my choosing. I was curious if a graphics card would add any benefit to the RDP experience or rendering of the display.
I also wanted to test emulating the game Jak and Daxter: The Precursor Legacy (OpenGOAL port) in the VM and also use an Xbox controller connected to my laptop by USB which would be redirected into the RDP session to the VM with the graphics card mapped.
INIITIAL RESEARCH
The graphics card of choice for this was a NVIDIA Quadro K2200. The graphics card shows up via Device Manager when remote to my (Hyper-V 2019 Core) server. Device Manager is usable by installing Server Core App Compatibility Feature on Demand (FOD) on the server.
This will be very helpful for this guide. Initial research led to the following article by Microsoft, Deploy graphics devices using RemoteFX vGPU. Which no longer is accurate as it has a security vulnerability.
Additionally, mapping a USB device such as a Xbox controller to a VM worked with the following article, Introducing Microsoft RemoteFX USB Redirection: Part 1. This actually worked just fine, and the controller worked in the VM no problem. Now I just needed to get the graphics card working.
DISCRETE DEVICE ASSIGNMENT
So, to do this we need to use something called Discrete Device Assignment. You can read the following article for more information, Deploy graphics devices using Discrete Device Assignment. Essentially just follow the article and run a few scripts on the Hyper-V server.
Microsoft explains how to do the steps individually, but at the end they include a script which does it all and is geared for NVIDIA cards. You will need to edit the scripts for your VM name and hardware.
MOUNTING A GPU TO A VM SCRIPT
#Configure the VM for a Discrete Device Assignment
$vm = "Windows 10 22H2 x64"
#Set automatic stop action to TurnOff
Set-VM -Name $vm -AutomaticStopAction TurnOff
#Enable Write-Combining on the CPU
Set-VM -GuestControlledCacheTypes $true -VMName $vm
#Configure 32 bit MMIO space
Set-VM -LowMemoryMappedIoSpace 3Gb -VMName $vm
#Configure Greater than 32 bit MMIO space
Set-VM -HighMemoryMappedIoSpace 33280Mb -VMName $vm
#Find the Location Path and disable the Device
#Enumerate all PNP Devices on the system
$pnpdevs = Get-PnpDevice -presentOnly
#Select only those devices that are Display devices manufactured by NVIDIA
$gpudevs = $pnpdevs |where-object {$_.Class -like "Display" -and $_.Manufacturer -like "NVIDIA"}
#Select the location path of the first device that's available to be dismounted by the host.
$locationPath = ($gpudevs | Get-PnpDeviceProperty DEVPKEY_Device_LocationPaths).data[0]
#Disable the PNP Device
Disable-PnpDevice -InstanceId $gpudevs[0].InstanceId
#Dismount the Device from the Host
Dismount-VMHostAssignableDevice -force -LocationPath $locationPath
#Assign the device to the guest VM.
Add-VMAssignableDevice -LocationPath $locationPath -VMName $vm
REMOVING A GPU AND RETURNING IT BACK TO THE HOST SCRIPT
#Find the Location Path and disable the Device
#Enumerate all PNP Devices on the system
$pnpdevs = Get-PnpDevice
#Select only those devices that are Display devices manufactured by NVIDIA
$gpudevs = $pnpdevs |where-object {$_.Class -like "Display" -and $_.Manufacturer -like "NVIDIA"}
#Select the location path of the first device that's available to be dismounted by the host.
$locationPath = ($gpudevs | Get-PnpDeviceProperty DEVPKEY_Device_LocationPaths).data[0]
#Remove the device from the VM
Remove-VMAssignableDevice -LocationPath $locationPath -VMName "Windows 10 22H2 x64"
#Mount the device back in the host
Mount-VMHostAssignableDevice -LocationPath $locationPath
#Enable the PNP Device
Enable-PnpDevice -InstanceId $gpudevs[0].InstanceId
CONCLUSION
Once mapped to the VM you can run Windows Update or install the driver manually. The conclusion to my test was that the game ran just fine but the display lag with RDP session made playing impossible. It was a fun little test, but don’t waste your time ever trying to play a game over an RDP connection. Hopefully this guide will help others out there looking to support some actual business applications.
Hey folks, my name is Dex and you’ve landed on my website. Ponder this; was it by coincidence or did God bring you here? Either way, I hope you find something of value. We may not agree on everything, but that’s just part of the fun here!
It’s my hope here that you also become inspired to join the good fight against evil. There are no ads here, just truth bombs. So change your tune because the best is yet to come, and nothing can stop what’s coming!
John 3:16: For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life.
Leave a Reply
Want to join the discussion?Feel free to contribute!