Forwarding USB connections through Hyper-V — or anywhere on your network!
My development workflow revolves around virtual machines: I have dev VMs for multiple concurrently-running projects. Some are Windows, some are Linux. My hypervisor of choice used to be VirtualBox, but with the introduction of VBS, VirtualBox has become extremely slow because it’s forced to function under Hyper-V. So I switched to just using Hyper-V by itself.
The biggest missing piece for my workflows with Hyper-V, as compared to VirtualBox, is USB forwarding. Some of the projects I work on require connecting a piece of hardware through USB for debugging or testing. With VirtualBox, this was as easy as a couple of clicks in a menu. Hyper-V, however, has no native support for forwarding a USB connection from the host machine to the guest OS. So, can we get USB forwarding to work? Or are we stuck with limited connectivity or slow VMs?
Don’t despair! A solution exists, although it’s a tad more cumbersome than the VirtualBox one. The key is USB over IP.
More specifically, we can use a USB over IP server on the host machine and forward a USB connection to the guest, which runs a USB over IP client.
🚨 DANGER!
The following steps can expose your USB peripherals to an untrusted network. Please make sure that firewall rules are in place to let only trusted clients connect to the host machine!
Host setup
To configure the host machine to take over a USB device and forward it, do the following:
- Download and install
usbipd-win
by either executingwinget install usbipd
or downloading and running the latest release from GitHub. - Open an elevated (administrative) command prompt and execute
usbipd list
to see a listing of all connected USB devices. For example, here’s the list from my machine:
BUSID VID:PID DEVICE STATE 1-3 0c45:6a1b Integrated Webcam Not shared 1-14 8087:0033 Intel(R) Wireless Bluetooth(R) Not shared 3-1 17e9:436e Dell D3100 USB3.0 Dock Not shared 3-3 17e9:436e Dell D3100 USB3.0 Dock, Dell USB Audio, Dell GigabitEthernet Not shared 5-4 1038:1702 USB Input Device, SteelSeries Rival 100, SteelSeries GG C... Not shared 6-2 045e:07f8 USB Input Device Not shared
- Bind one of the devices to allow it to be shared. Using the above example, if I wanted to share my Integrated Webcam with my Hyper-V guest, I would type:
usbipd bind --busid 1-3
That’s it for the host side! Next, we’ll tackle the guest.
Guest setup
On the guest side, we’ll do a similar setup procedure, with a few changes:
- Download
usbip-win
(note, this is different from the host side!) from GitHub and extract it. - Open an elevated (administrative) command prompt, browse to the location where you extracted the above file, and execute
usbip install
to install the required Windows driver. - Determine the IP address of the host from the guest’s perspective by executing
ipconfig
and looking for the Default Gateway address. For example, my output looks like this:
Ethernet adapter Ethernet: Connection-specific DNS Suffix . : mshome.net Link-local IPv6 Address . . . . . : fe80::3207:336e:3f5b:d0f5%4 IPv4 Address. . . . . . . . . . . : 172.20.5.225 Subnet Mask . . . . . . . . . . . : 255.255.240.0 Default Gateway . . . . . . . . . : 172.20.0.1
- Attach to the bound USB device (in my example, the IP address of the host is 172.20.0.1 and the bus ID is 1-3) like so:
usbip attach --remote=172.20.0.1 --busid=1-3
Assuming no errors were shown, your USB device is now attached to your guest machine. You can use it as if it were physically attached. Congratulations!
Bonus
As an added bonus, you can use the same procedure without Hyper-V anywhere on your network (but again, please make sure access is appropriately restricted). Additionally, this works with Linux as a host or as a guest, too, because the usbip
tool is cross-platform!