Multiple Ubuntus on Hyper-V: a Time-Saving Setup Guide
If you have a 64-bit Windows 10 Pro, Enterprise, or Education, you can use the built-in hypervisor to host guest virtual machines (typically, running Ubuntu Linux). The official Microsoft docs give you a complex, error-prone, and outdated way to configure Hyper-V and its networking. If you wish to avoid pitfalls, this straightforward guide is for you.
Before We Start…
If you need just one instance of Ubuntu for command-line tasks, it is better to install Windows Subsystem for Linux (WSL2) and get Ubuntu from the Windows App Store. WSL simulates the Linux kernel by mapping its API to the Windows kernel; thus, your Linux programs will appear in Windows Task Manager as native. Besides, they will have a near-native performance. The drawback is the complexity of configuring GUI.
Besides Hyper-V, you can look at VirtualBox or QEmu as free alternatives.
Install Hyper-V (admin required)
Want to install graphically? Press the Win key and search for “Hyper-V.” Select the suggestion named “Turn Windows features on or off.”
In the “Windows Features” dialog, select the “Hyper-V” checkbox.
I suppose that searching for “Hyper-V” is more direct than navigating through Settings → Apps → Optional features (a link) → More Windows features (a link on the right). Notice that with each next Windows update, Microsoft tends to hide settings even deeper.
Want to install via the power shell? Then just hit the Win key, type “PowerShell,” right-click on the best match, and choose “Run as administrator.” Then copy (Ctrl+C) and paste (Ctrl+V) into the power shell this command:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
Launch Hyper-V Manager for the First Time
If you are not an admin, ask your admin to add you to the “Hyper-V Administrators” group (hint: that can be done by launching “netplwiz” from the already familiar search field).
To launch the Hyper-V dashboard, hit the Win key and search for the “Hyper-V Manager.” Click “Connect to Server…” in the Actions panel on the right, and choose “Local computer.”
Why Ubuntu?
If you value your time, just go with Ubuntu! It is maintained by Canonical and supported by the community. Ubuntu is also respected by the majority of software and hardware vendors targeting Linux. Besides, almost any Ubuntu-related issue can be solved just by googling for it. Finally, Ubuntu is supported by Hyper-V itself: its "Quick Create…" wizard can download one of the predefined Ubuntu .iso files and do all the dirty work for you!
Creating a Virtual Machine from the Image of Your Choice
Quick Create Wizard (admin required)
If you wish, you can feed an .iso image of your choice to the same “Quick Create…” wizard. However, uncheck the secure boot checkbox for Linux guests:
Sadly, the Quick Create wizard seems not to work correctly with .vhd images. Besides, it requires the administrator privileges to run; ask Microsoft why.
Fortunately, there is also the…
…Traditional Create Wizard
For a more controlled install (or if you are not an admin but just an ordinary member of the “Hyper-V Administrators” group), launch the traditional wizard by choosing New → Virtual Machine…
On Virtual Hard Disk (.vhd) Images
The out-of-the-box Ubuntu 20.04 server image (the .vhd file) can be obtained here. Download the “Windows Azure/Hyper-V image.” However, the current version of Hyper-V seems not to like .vhd files. Thus, please do not attach the .vhd disk in the wizard; attach it later as a SCSI Controller (choose Settings → Add Hardware). Put the .vhd file on a local path (Hyper-V doesn’t like the paths starting from “\\”). When browsing for the .vhd file, enter the mask “*.*” since Hyper-V looks for the .vhdx files by default.
Alternatively, you can convert a .vhd file to a .vhdx file.
Since modern Linux distros, including Ubuntu, support UEFI boot, you can specify "Generation 2" for their virtual machines.
When configuring networking, choose the “Default Switch.” Your host will act as a home router with multiple switch ports, implementing a NAT network. Your guest will be virtually connected to one of these ports and automatically get local IP addresses.
Trust me: the default switch will save your time! Later I will explain how to add another switch, should you need one (e.g., when you need to access the guests by their static IPs).
If you use a digitally unsigned Linux boot image (a typical case), then right after creating the virtual machine, go to its settings and uncheck Security → Enable Secure Boot.
Notice that Ubuntu 18.04 supports the secure boot feature on Hyper-V if you are OK with that version.
Start the Virtual Machine
Hyper-V runs virtual machines in the background (think of virtual machines as services). When you double-click on a machine, you connect to it, i.e., its virtual display is shown. If the machine has not been started, press the “Start” button on display (alternatively, right-click on the machine and choose “Start”).
If installing from the .iso, follow the installation instructions, but do not enable auto-login (that is important if you wish to use the enhanced session mode explained in the next section).
If you use an Ubuntu server .vhd image, the system will boot to the console and ask for a password. But there is a problem: Ubuntu cloud images are designed to log in via SSH (SSH keys are usually being uploaded by the cloud service provider or by a cloud-init script). However, since we are not in the cloud, we will have to press F2 continuously while booting. (By the way, the initial delay is because Hyper-V tries to boot from LAN first; you can change that order later in the settings for the given virtual machine.)
When the grub (boot loader) menu appears, we wish to navigate to the recovery mode and go to the root shell prompt (choose Advanced options for Ubuntu→… (recovery mode)→Drop to root shell prompt). From there, we will able to set the password for the default user "ubuntu":
# passwd ubuntu
Integrate Ubuntu with Hyper-V for Enhanced Mode
If you installed Ubuntu from the .iso with graphical environment, you might notice that the Ubuntu desktop environment is slow within Hyper-V. To support enhanced graphics and deeper integration with Hyper-V, Microsoft has developed these scripts. The latest script version is for Ubuntu 18.04, but it also works with Ubuntu 20.04 with some workarounds explained below.
First, get the script and install it:
# wget https://raw.githubusercontent.com/microsoft/linux-vm-tools/master/ubuntu/18.04/install.sh# chmod +x install.sh
# sudo ./install.sh
Since Hyper-V integrates with Ubuntu's GUI via Remote Desktop Protocol (RDP), the script installs xrdp. However, you will probably get an error regarding xrdp. Thus, edit the /etc/xrdp/xrdp.ini file (via sudo) and change these lines:
port=vsock://-1:3389
use_vsock=false
However, that's not all yet! To be able to log in via RDP, we need to run another script. Since the user can be logged in to the desktop only once (either into the slow desktop session or into the enhanced session), I asked you not to enable the auto-login feature. Here are the installation commands (run as a normal user; the script will ask for the sudo password):
wget https://www.c-nergy.be/downloads/xrdp-installer-1.2.2.zip
unzip xrdp-installer-1.2.2.zip
chmod +x xrdp-installer-1.2.2.sh
./xrdp-installer-1.2.2.sh
Now switch back to Windows 10, open PowerShell, and run the following command (replace vm_name with the name of your Ubuntu machine, as it is shown in Hyper-V Manager):
Set-VM -VMName vm_name -EnhancedSessionTransportType HvSocket
Finally, restart Ubuntu.
Access Ubuntus by Static IPs
The default switch gives dynamic IPs to guests. To be able to specify static IPs, we need to create our own virtual switch.
Three Types of Virtual Switches
Windows 10 has the built-in capability to define virtual switches. In addition to the already known “Default Switch,” you can create your own external, internal, or private virtual switches.
Try to Avoid External Switches
An external virtual switch is virtually connected to your physical LAN. It must be associated with a physical interface (NIC) of the host. Thus, if you connect virtual machines to an external switch, they will be directly accessible from the devices connected to the same physical LAN, to which the host is connected.
However, I suggest not to use external virtual switches (unless you really need them). First, they seem not to work with Wi-Fi adapters. You can try, but you need to be an admin and not connected to the Wi-Fi; otherwise, you may experience problems trying to create or even to delete it! Second, if you attach an external virtual switch to a LAN port, the cable has to be always plugged in; otherwise, the virtual switch will also be “unplugged.”
Internal and Private Switches
An internal virtual switch is connected to your host via a virtual NIC; thus, it does not need a plugged wire to operate. By default, your virtual machines will not be accessible from the Internet (the external network), but you can define a route to them.
The private virtual switch is available for inter-connecting the guests only; it is not visible to the host.
Create Your Internal Switch (admin required)
To create an internal switch, invoke the “Virtual Switch Manager…” from the Actions panel on the right of Hyper-V Manager. Choose “internal” and click Create.
Then in Windows 10, navigate to Settings→Network & Internet →Change adapter options. Right-click on your brand new virtual switch and choose “Properties.” Select “Internet Protocol Version 4 (TCP/IPv4)” and press the “Properties” button.
Click on the "Use the following IP address" radio control. Enter a desired local IP address and a mask, say 10.10.10.1 and 255.255.255.0. Why do we need to enter the IP address for the switch? That is because the internal switch is attached to the corresponding virtual NIC, to which the IP address will belong. The NIC will be virtually connected to the switch. Since we use the 255.255.255.0 mask, our guests will be able to use IP addresses in the form of 10.10.10.x, where x is from 2 to 254 (0 and 255 are reserved, while we have just assigned 1 to the virtual NIC of the host).
Add the Second NIC (eth1) to Each Ubuntu
Shut down Ubuntu before adding a switch. Then, in Hyper-V Manager, right-click on the machine and choose Add Hardware→Network Adapter. Connect it to the switch created in the previous step.
Configure eth1 for each Ubuntu
The first interface (eth0) is connected to the default switch and shares the Internet connection with the host. The default switch assigns a dynamic IP to eth0.
We will use the second interface (eth1) to give our Ubuntu a static IP. Since Ubuntu manages networking using netplan, we will reconfigure it.
If you use a cloud image, you need to perform two additional steps in advance. First, instruct the cloud image not to control the network settings:
$ sudo echo "network: {config: disabled}" > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
Second, remove Azure-specific netplan settings since they interfere with our eth1:
$ sudo rm /mnt/etc/netplan/90-hotplug-azure.yaml
In any case, continue as follows.
Go to /etc/netplan, find the appropriate .yaml file and add eth1 to the network→ethernets part as follows (use four spaces to align, not tabs; keep the eth0 part as is):
network:
ethernets:
eth0:
dhcp4: true
# keep other lines as is...
eth1:
dhcp4: false
addresses: [10.10.10.123/24] # 123=x varies among guests
Apply the changes (they will persist after the reboot):
sudo netplan apply
If something goes wrong, you can forcibly set the IP and mask as follows (replace 123 with the desired number for the given guest):
ip link set eth1 down
ip addr add 10.10.10.123/24 dev eth1
ip link set eth1 up
Notice, however, that these changes won’t persist after the reboot.