Windows in a Libvirt KVM VM

A screenshot of Windows 98 Second Edition running in a Virtual Machine on a Linux Desktop


These are some updated personal notes about setting up the Windows side of a nice combined Windows and Linux productivity and development environment in Virtual Machine running under Libvirt Qemu/KVM (that is with Linux as the host OS). It uses open source software combined with some key proprietary pieces on a single machine.  It also allows using the Linux subsytem from within Windows1.

I have thought about automating this (especially since I have a tendency to refresh systems fairly often), but I make enough changes between installs, and I’m using retail Windows licenses rather than volume licenses, so automation is not really practical.

It is important to note that this environment is geared to those who are used to the Linux ecosystem and also want to use or try the new hybrid model.

Installation Notes

Use at least Windows 10 Pro, Version 2004, Version 20H2 preferred. Windows 10 Home might work for some of this, but not all features are available.

Setting up the Virtual Machine on a Linux Host

NOTE This guide doesn’t use bleeding edge setting. Instead we stick (Linux side) to stable and tested technologies that, except bug fixes, performance improvements, and generally getting better over time, have been available in Linux for at least five years.

That means, for example, we don’t use a UEFI VM (for that item there is no real point, quite yet, as the SecureBoot/certificate chain for WHQL-certified VirtIO drivers for Windows isn’t (yet) available outside of a paid RedHat subscription — it appears Ubuntu has a Windows Server edition version of the VirtIO drivers that use that technology, but I am not aware of the same for Windows 10).

Install Virtual Machine Manager and Virt-Viewer on Your Linux Host

  1. For example, on Debian/Ubuntu/Linux Mint issue the commmand: sudo apt-get install libvirt-daemon virt-clients virt-manager virt-viewer
  2. Add an ‘isolated’ network to use for communication between the Linux host and guests (the default install already adds a ‘NAT’ network named default for communicating to other hosts).
    1. Launch Virtual Machine Manager
    2. Double-click on the line labelled QEMU/KVM:…
    3. Click on the Virtual Networks Tab
    4. Click on the + icon (aka Add Network)
    5. Give the network a name.
    6. Chose Mode: Isolated.
    7. Configure the networking information.
    8. Click Finish.
  3. If you want to be able to allow network traffic from other hosts on the network or internet to the virtual machine you will need to do some searching and reading about Linux networking — that is out of scope for this article.

Download and Install Windows and Drivers

We’re doing this a slightly harder way (using virtio drivers during install) that give better cpu, disk, and network performance.

Download the Necessary CD Images
  1. Make sure you have a Windows 10 Product Key to verify your right to use Windows 10.
  2. Download the most recent Windows 10 Pro release, which is 20H2 (October 2020 Release) as of this writing. For this guide you definitely want the English 64-bit version.
  3. This will download a file named Win10_20H2_English_x64.iso
  4. I recommend you also click on ‘Verify your download` on the microsoft download page, and find the ‘hash’ the ‘English 64-bit’ version.
  5. Once the ISO is downloaded, open a terminal.
    1. cd ~/Downloads
    2. sha256sum Win10_20H2_English_x64.iso
    3. The output should match the hash from the site above (case doesn’t matter).
    4. If the output does not match the given hash, the download failed; try again.
  6. Download the Latest stable KVM VirtIO drivers ISO from The Fedora Project
  7. Copy both .iso files to /var/lib/libvirt/images. You will need to do the copy as root (e.g. using sudo).
  8. Alternatively, or if Libvirt is running on a different Linux machine than the one with the .iso files:
  9. ls -al '*.iso' and make note of the file sizes of the ISO you want to use with libvirt.
  10. virsh -c <URI-to-libvirt-host> vol-create-as --pool default --allocation <size-of-file-from-ls> --capacity <size-of-file-from-ls> --format raw --name <name-of-ISO>
  11. virsh -c <URI-to-libvirt-host> vol-upload --pool default --vol <name-of-ISO> --file <path-to-and-ISO-name>
  • Example URIs for libvirt hosts include:
    • For a local qemu/kvm libvirt: qemu:///system
    • For accessing qemu/kvm libvirt via SSH: qemu+ssh://user@host/system
Initial Steps for Creating the Windows Virtual Machine

Using Virtual Machine Manager create a virtual machine for Windows

  1. In VMM (Virtual Machine Manager) select the icon in the top left (‘Create a new virtual machine’)
  2. Choose Local Install media (ISO image or CDROM)
  3. Verify ‘Architecture options|Architecture’ is x86_64
  4. Select ‘Forward’
  5. Browse for the Windows ISO
  6. For ‘Choose the operating system you are installing’ enter/select ‘Microsoft Windows 10’
  7. Select ‘Forward’
  8. If you have enough memory, give the virtual machine 8192 MB (8 GB) of memory, otherwise use the defaults (minimum 4096 MB)
  9. Recommending giving at least two cpus, but four would be better.
  10. Select ‘Forward’
  11. Set the size of Hard Disk to give the Windows Virtual Machine. I recommend at least 80 GB, although according to Microsoft the VMM default of 40 GB ought to be ‘enough’.
  12. Select ‘Forward’
  13. Give the virtual machine a name for VMM purposes (this is different than the Windows hostname).
  14. Make sure Customize configuration before install is checked.
  15. Select ‘Finish’.
Finalize the Configuration of the Windows Virtual Machine
  1. In Overview, make sure the virtual machine has the name you want.
  2. Also in overview, use a Q35 BIOS virtual machine
  3. Select SATA Disk 1
    1. Under Advanced Options change Disk bus to VirtIO and click Apply
    2. SATA Disk 1 will become VirtIO Disk 1
  4. Select NIC:xx:xx:xx
    1. Change Device model to virtio
  5. Select Add Hardware
    1. Choose Select or create custom storage
    2. Select Manage... and select the VirtIO driver ISO
    3. Change Device type to CDROM device
    4. Select Finish
  6. Select ‘Add Hardware`
    1. Choose Network
    2. Change Network source to the isolated network you created
    3. Change Device model to virtio
    4. Select Finish
  7. Select Add Hardware
    1. Choose Channel
    2. For Name select org.qemu.guest_agent.0
    3. Select Finish
  8. Select Add Hardware
    1. Choose Channel
    2. For Name select org.spice-space.webdav.0
    3. Select Finish
  9. Select Add Hardware
    1. Choose RNG
    2. Select Finish
  10. Select Begin Installation

The Parts that Come with Your Windows License and/or Base VM Requirements

The Windows Install Bootstrap (Early Install)

  1. A VMM graphical console showing the Windows boot process and then installer screen will open.
  2. Select your language and other preferences and then click ‘Next’.
  3. Click ‘Install Now’
  4. Enter your Windows Product Key and Click ‘Next’
  5. As if you had a real choice (not using Windows is unrealistic for most in today’s world); check ‘I accept the license terms’
  6. Select ‘Install Windows’
  7. Install the VirtIO drivers we need
    1. Select ‘Load Driver’
    2. Click Browse
    3. Select the virtio driver ISO (probably drive E:)
    4. Double-click on NetKVM, then w10, then amd64, then click OK
    5. The VirtIO Ethernet Driver should be selected, so Click ‘Next’
    6. Select ‘Load Driver’
    7. Click Browse
    8. Select the virtio driver ISO (probably drive E:)
    9. Double-click on viostor, then w10, then amd64, then click OK
    10. The VirtIO SCSI Driver should be selected, so Click ‘Next’
  8. Drive 0 Unallocated Space should be selected, so click ‘Next’
  9. Wait while Windows installs the base system.
  10. Reboot (will occur automatically after a bit).

Finishing The Base Windows Install

After the initial installation phase the Windows install will reboot at which point you will do the usual Windows 10 Pro first boot procedure. This article won’t cover those steps as there are many thorough guides available.

  • When prompted about whether to make this computer publicly visible to other computers and devices on the network, it is safe to say ‘yes’ because the network is actually a local (to the Linux host) network that is has a NAT between the Windows VM and anything outside the Linux host. (It is still recommended to add a firewall to your Linux host, but that is outside the scope of this article). If you don’t plan on using Windows File Sharing from the virtual machine to other hosts you can safely (and and it’s safer) to say ‘no’ here.

  • If you want to be able to access Windows file sharing resources on your local network outside the Linux host from the Windows Virtual Machine you will have to make this network a ‘Private’ (trusted) network so that File and Print sharing will work on that network for the Windows VM. For the prompt mentioned above, that means choosing ‘Yes’.

  • If you will be wanting other devices to access network resources on the Windows VM you will need to do some additional reading / research to learn how to set up the network to allow this. Such a configuration is beyond the scope of this article.

Install the QEMU Guest Agent and Spice Guest Tools
  1. In File Explorer open the KVM VirtIO drivers CD.
  2. Double-click virtio-win-guest-tools and follow the prompts.
Update with Windows Update
  • Make sure your machine is activated and fully up to date with Windows Update.
  • If you wish, configure ‘Advanced Options’ and ‘Delivery Optimization’ of ‘Windows Update’.
Make the Isolated (host-only) Second Network a ‘Private’ Network

We want the isolated second network we created to be used as a ‘trusted’ communications network between the VM and the host, which means we need to convince Windows to label it a ‘Private’ network.

  1. In an ‘Administrator’ Powershell, issue the command ipconfig and make note of which ‘Ethernet’ adaptor is associated with which network (that is host-only vs. default/NAT network).
  2. In the same powershell, issue route print and note which interface number is the ‘host-only’ network
  3. Also note the IP address associated with the host-only network
  4. In the same powershell, issue route -P add mask <IP-address-of-host-only-network> metric 1500 if <interface-number-from-above>

You should be prompted to allow other computers to see this host on this network which will likely be called ‘Network 2’. Say yes — that makes this a private (trusted) network.

You can now exit the administrator powershell.

  • If you want to verify which networks on the virtual machine are considered ‘Private’, click on the network icon in the taskbar, and then select “Network & Internet Settings”.
  • On the left, select ‘Ethernet’, and click on each network listed there, in turn.
  • When you select the network you should see the option to configure it as ‘Public’ or ‘Private’. ‘Public’ means the network is not trusted and uses a more restrictive firewall.
Configure Language and Regional Settings as Appropriate
  1. In the Settings app, select Time & Language
  2. Select Language
  3. If your ‘Windows display language’ is for your region you probably don’t need to do anythng more.
  4. Otherwise, look in the list of ‘Preferred Languages’
  5. Select the language corresponding to your region, or ‘Add a language’ if your language and region are not in the list.
  6. Select Options for your language and region.
  7. For any and all Download buttons in your Language options page, click Download.
  8. Wait for the downloads and installs to complete.
  9. Verify your desired keyboard type and layout is first (or only) in the list of keyboard types/layouts
  10. Go back to the main Language page.
  11. Set your Windows display language to your language and region.
Tweak the Base Install

Tweak the base install (before adding any software or apps) and settings to your preferred base configuration2. I also recommend creating a copy of your freshly installed virtual hard drive.

(Optional) Create a ‘System Image’

You may also wish to use the Window Backup tool to create a ‘System Image’, although I’d recommend creating a copy of your virtual hard drive first.

  1. On your Linux host download the latest ‘System Rescue CD’ and place it in your libvirt image directory (e.g. /var/lib/libvirt/images).
  2. Set the CDROM attached to your Windows VM to point to the System Rescue CD image.
  3. Configure your Windows VM to boot from CD.
  4. Reboot your Windows VM and log into System Rescue CD as root (it’s passwordless).
  5. Execute startx
  6. Select the gparted icon or launch gparted from a terminal in System Rescue CD.
  7. Decrease the size of the second partition on /dev/vda by 100 MB and move it as far to the right as possible (there should be no free space after the second partition, but there now should be space before the second parition.
  8. Increase the size of the first partition to fill the space between the first and second partition (the first partition should end up being about 150 MB in size.
  9. Apply the changes. This could take a long time.
  10. Once complete shutdown the VM.
  11. Change the first CDROM attached to your Windows VM to point to the Windows 10 Install ISO.
  12. Change the second CDROM attached to your Windows VM to point to the VirtIO driver ISO.
  13. Boot the Windows VM into the CD (press ENTER when the press any key prompt appears).
  14. Choose ‘Troubleshoot’ and then ‘Command Prompt’.
  15. At the command prompt type e: followed by the ENTER key.
  16. Execute cd viostor\w10\amd64
  17. Execute pnputil -i -a viostor.inf
  18. The screen should indicate that the VirtIO SCSI driver was loaded.
  19. Type g: followed by the ENTER key
  20. Execute cd windows\system32
  21. Execute bcdboot g:\windows /l en-us
  22. Exit the Command Prompt
  23. Shutdown the Windows Rescue Mode
  24. Configure your Windows VM to boot from the hard drive.
  25. Boot the Windows VM
  26. Execute bcdboot /l en-US /bcdclean full
  27. Execute chkdsk c: /f
  28. Shutdown the Windows VM.
  29. Boot the Windows VM.

You should now be able to use the Back up and Restore (Windows 7) application that is in Control Panel. This allows you to create a ‘System Image’.

I recommend that once you have successfully created a system image that you turn off scheduled backups using the Back up and Restore (Windows 7) application. The object of the system image, for the purposes of this article, is to have a known good base image.

Configure ‘Network and Sharing’, if Applicable

If you want to allow this virtual machine to access Windows file shares on hosts on networks you have marked as ‘Private’ (trusted) networks you need to configure ‘File and Printer Sharing’.

  1. Open Settings
  2. Select Network & Internet
  3. Select Network and Sharing Center
  4. Click on Change advanced sharing settings
  5. Under the ‘Private’ section, ‘File and printer sharing’ subsection, select Turn on file and printer sharing
  6. Under the ‘Public’ section, ‘File and printer sharing’ subsection, select Turn off file and printer sharing
  7. The ‘Network discovery` subsections are irrelevant because of the type of networking used in the configuration in this article. This VM can’t discover hosts outside the Linux host, and hosts outside the Linux hosts can find this VM, even if the options are enabled.
  8. Under All networks, Password protected sharing subsection, make sure Turn on password protect sharing is enabled.
Configure ‘For developers’ in ‘Upgrades & Security’
  • You should go through these settings as many of them are useful to power users and developers – be careful though as there are often security implications to the options. I certainly don’t enable all the options.
  • If you have enabled networking into the virtual machine, and you do allow ‘Remote Desktop’ I recommend altering the default firewall rule to be for ‘Private’ networks only, perhaps even only for your particular subnet (assuming you aren’t using the default for your router).

Add Windows (System) Features

Developer Essentials

This could almost be part of the ‘Base Windows Install’ except that we are adding components that wouldn’t make sense for an environment that doesn’t need Linux and/or some handy developer features.

Useful Features from Programs & Features in Control Panel
  • Install Hyper-V if you need virtualization — Also enable all the Hyper-V options in the control panel applet. If Hyper-V is not supported on your machine you can install VirtualBox using Chocolatey (see below).
  • Extras — Likewise, you might want the “Telnet Client” and “TFTP Client”, depending on your planned uses.
  • “Services for NFS” — There is also a small possibility you will benefit from “Services for NFS”, depending on the hosts on your network.
Allowing SSH Into Your Machine
  • Install “OpenSSH Server” if you plan on using SSH into the virtual machine — See Microsoft’s instructions for installing OpenSSH, and the related configuration guides. Like the ‘Remote Desktop’ option, if you have enabled networking into the virtual machine so that you can use SSH into it, you probably should change the default firewall rule to be more restrictive (e.g. Private networks only).

Add Some (Free) Bits from the Windows Store

  • Windows Terminal — It’s a Microsoft Open Source project that you can participate in on GitHub. It is also quite a nice and usable terminal, that is only likely to get better with time. Currently it’s nice and light.

  • WinDbg Preview — This allows you to look at Windows ‘Crash dumps’

  • A Linux distribution from the available choices – I now use Ubuntu LTS but have used Debian. You can use whichever suits your needs.

Maybe a Paid Microsoft Purchase (besides Windows)

  • Microsoft 365 — If you can afford it, there are may be advantages over a free office suite, which I’ll mostly leave it to other sites to discuss, except…

  • I will say I’m not so sure about this one. I like the native desktop apps, but I am not a fan of the Software as a Service (SaaS) model of MS 365. As it happens I have licenses for Office 2016 Home and Business which gives me the desktop apps I want from the MS 365 offering, and without all the SaaS baggage.

  • I think the standalone 2019 offering is too expensive, so in future I may abandon the Microsoft office products altogether and just use LibreOffice

  • LibreOffice software is really more than enough for what I actually need, and MS Office is getting to be too much of a hassle.

  • Besides that, on my Linux desktops I don’t have MS Office native apps as an option anyway.

  • Your call for your install.

The Rest (on the Windows Side)

Install Chocolatey (a package manager for Windows)

Just follow the official Chocolatey install guide.

Install Software for Windows Available Through Chocolatey

NOTE: The original software licenses still apply so it is important that they are compatible with your situation. You can verify that by using the Chocolatey Online Package Browser, or ChocolateyGUI (a graphical interface for Chocolatey).

Most of the software is open source and ought to be no problem for internal use; if you are planning on ‘distributing’ anything then you need to pay close attention to licensing terms. I’ve made note of any software that you may need to play closer attention to the licensing terms, even for internal use, for which I am aware of the more complicated situation.

Install Regular User Software

Software Applicable to Windows in VM on a Linux Host
  • When running Windows in a Linux virtual machine, one doesn’t need the same set of packages one would when running Windows on bare metal because much of the software available for Windows is also available for Linux and it makes more sense to run software natively (i.e. on the host) when possible.

  • The following is a list of software that is useful even when running in a Windows virtual machine, with most software you use running on the Linux host.

  • This particular list is for regular users (i.e. not related to Linux, development, or system administration). Obviously you will want to modify accoring to your needs and wants.

choco install 7zip.install adobereader chocolateygui Firefox gpg4win keepassxc libre-hardware-monitor notepadplusplus.install rufus screentogif synctrayzor vlc wincompose.install
7zip7-zipCompress/Decompression and archiving/unarchiving
adobereaderAdobe Acrobat Reader DCThe official Adobe PDF reader; proprietary license
chocolateyguiChocolateyGUIGUI for Chocolatey
FirefoxFirefoxPrivacy-oriented Web Browser
gpg4winGnuPG for WindowsPublic/Private Key encryption tool
graphvizGraphVizGraph Visualizer — included here to enhance Zim
keepassxKeePassXCPassword management tool
libre-hardware-monitorLibreHardwareMonitorSystem (CPU, memory, disk, temp, and so on monitoring in system tray)
notepadplusplusNotepad++A better notepad (text editor) for Windows
paint.netPaint.NETPhoto editing software
rufusRufusUSB and SD card writer
screentogifScreenToGifScreen, webcam, and sketch board recorder and editor
synctrayzorSyncTrayzorSystem tray and GUI for Syncthing, for syncing files without ‘the cloud’ – note that I recommend disabling the autodiscovery and NAT traversal relays, at least if you’re still a bit paranoid like me.
vlcVideoLan ClientVideo and audio player
wincomposeWinComposeCompose key for windows – intuitive entry of unusual characters
Software You Might Want on Bare Metal Windows

The following list of software is interesting if you are running Windows on bare metal (that are not listed above).

choco install audacity audacity-lame calibre cdburnerxp dia freac gimp graphviz InkScape libreoffice-fresh kmymoney microsoft-teams.install quodlibet rufus scribus workrave zim zoom
audacityAudacityAudio recording and editing software
audacity-lameLAME for AudacityAllow Audacity to create MP3 files
calibreCalibree-Book Library Management
cdburnerxpCDBurnerXPCreate and burn data CD, DVDs, and Blu-ray
diaDiaCreate and edit diagrams
freacFre:acAudio file converter/encoder/decoder and CD ripper
gimpGIMPA very powerful graphics / image manipulation program
graphvizGraphVizGraph Visualizer — included here to enhance Zim
InkScapeInkScapeVector graphics creator and editor
kmymoneyKMyMoneyPersonal Financial Management
libreoffice-freshLibreOffice FreshStable version of LibreOffice
microsoft-teamsMicrosoft TeamsVideo conferencing – note the licensing terms!
quodlibetQuod LibetMusic Collection / Player Software
rufusRufusUSB and SD card writer
scribusScribusDesktop publishing software (cross-platform)
workraveWorkraveRSI prevention utility (require regular breaks)
zimZimDesktop wiki / notes / freeform lists (including checkboxes) stored in plaintext format
zoomZoomVideo conferencing / chat. NB If you have more than one computer your probably need to install manually due to download restrictions; also pay attention to the licensing terms.

Install Useful Power Tools

Software Applicable to Windows in VM on a Linux Host
choco install putty.install rsync sysinternals vcxsrv wireshark
puttyPuTTYSSH GUI (unrelated to OpenSSH above)
rsyncrsyncOne-way file sync common on other OSes
sysinternalsSysInternalsPower tools for Windows
vcxsrvVcXsrvAn X-Windows server for Windows; useful for running X11 applications remotely and using a local display
wiresharkWiresharkWatch and analyze activity on your network
Software You Might Want on Bare Metal Windows
choco install OpenSSL.Light xca
OpenSSL.LightOpenSSLThe command line tool for SSL certificates and more
xcaXCASSL certificate creation and management

Install Development Software

Software Applicable to Windows in VM on a Linux Host

This is highly dependent on what you are developing and what languages you are using. This list is an example.

choco install git git-credential-manager-for-windows golang openscad vagrant vim virtualbox vscode yarn
gitGit for WindowsThe major version control and source code management system in the software world
git-credential-manager-for-windowsGit Credential Manager for WindowsManage Git credentials using the Windows system secrets store
golangGoThe Go language and standard library
openscadOpenSCADProgrammatic CAD
vagrantVagrantcommand line tools for creating and using virtual machines (vagrant ‘boxes’) similar to the way one would use docker containers
vimVimA enhanced version of the classic vi text editor, including GVim
virtualboxOracle VirtualBoxRun Virtua Machines under Windows (with or without Hyper-V).
vscodeVisual Studio CodeCode and text editor and development environment, and more
yarnYarnAn improved package manager for Node.js
Software You Might Want on Bare Metal Windows

This is highly dependent on what you are developing and what languages you are using. The following is a list that reflects my current situation.

choco install arduino docker-compose docker-desktop html-tidy hugo nodejs.install pandoc shellcheck thonny
arduinoArduinoIDE for developing Arduino sketches
docker-composeDocker ComposeTool for launching and managing Docker machines
docker-desktopDocker DesktopDocker for modern machines, integrates with WSL2; for older machines use Docker Toolbox instead
html-tidyTidyValidate and clean HTML5
hugoHugoStatic website generator
nodejsNode.jsJavaScript as a language for cross-platform apps and services; includes NPM the package manager for Node.js
pandocPandocConvert between document formats (e.g. markdown, pdf, docx, xml, html, and tex) on the command line
shellcheckShellCheckCheck bash / sh / dash / ksh scripts for syntax and common errors and style issues
thonnyThonnyPython IDE for beginners

Windows Development

You absolutely want Visual Studio. Chocolatey can probably install what is needed by most developers. Verify what you are installing though — licensing can be tricky here.

In addition to the Visual Studio Installer and Visual Studio 20XX Community or Visual Studio 20XX Build Tools core applications you will want to install ‘workloads’ that support the type of applications you are wanting to develop or to which you wish to contribute. A fairly ‘kitchen sink’ example install command is given below.

choco install -y visualstudio2019buildtools visualstudio2017feedbackclient visualstudio2017buildtools VisualStudio2017Community visualstudio2019community visualstudio2017-workload-visualstudioextension visualstudio2019-workload-visualstudioextension visualstudio2017-workload-python visualstudio2017-workload-azure visualstudio2017-workload-visualstudioextensionbuildtools visualstudio2015-nugetpackagemanager microsoft-build-tools visualstudio2017-remotetools visualstudio2019-remotetools visualstudio2017-workload-node visualstudio2019-workload-node visualstudio2019-workload-azure visualstudio2019-workload-python visualstudio2019-workload-visualstudioextensionbuildtools visualstudio2017sql visualstudio2017-performancetools visualstudio2019-performancetools visualstudio2017-workload-nativecrossplat visualstudio2019-workload-nativecrossplat visualstudio2017-workload-azurebuildtools visualstudio2017-workload-nodebuildtools visualstudio2019-workload-azurebuildtools visualstudio2017-workload-netcorebuildtools visualstudio2017-workload-manageddesktop visualstudio2019-workload-manageddesktop visualstudio2017-workload-vctools visualstudio2019-workload-vctools visualstudio2017-workload-netcoretools visualstudio2017-workload-netcrossplat visualstudio2017-workload-netweb visualstudio2017-workload-universal visualstudio2017-workload-webcrossplat visualstudio2019-workload-netcrossplat visualstudio2017-workload-nativedesktop visualstudio2017-workload-data visualstudio2019-workload-universal visualstudio2019-workload-netweb visualstudio2019-workload-nativedesktop visualstudio2019-workload-netcoretools visualstudio2017-workload-universalbuildtools visualstudio2019-workload-nodebuildtools visualstudio2019-workload-universalbuildtools visualstudio2019-workload-manageddesktopbuildtools visualstudio2019-workload-netcorebuildtools visualstudio2017-workload-webbuildtools visualstudio2019-workload-webbuildtools visualstudio2017-workload-manageddesktopbuildtools windowsdriverkit10 vcredist2017

Android Development

E.g. choco install AndroidStudio

Additional Software

There may be additional software you want to install that is not available from the Windows Store or Chocolatey. If so, you should probably install it.

Linux Side

I don’t cover installation of packages and configuration of the general Linux environment except as is particular to this hybrid setup, as there are a great many guides for general Linux setup and configuration already written, and the WSL2 environment doesn’t have much that isn’t generic Linux.

Likewise with the non-VM configuration of the Linux host.

Configuration Notes

Now that the software is installed there is a bit of configuration to do.

Configuring WSL so Windows Filesystems Have Proper Unix Permissions

In the WSL environment you should add /etc/wsl.conf containing something like:

enabled = true
options = metadata,uid=1000,gid=1000,umask=0022,fmask=0011

generateHosts = true
generateResolveConf = true

See Configuring WSL Launch Settings

Once you restart WSL (which involves more than just closing your current WSL terminal; the easiest way to guarantee a WSL restart is to reboot Windows), while in WSL files and directories from Windows (e.g. under /mnt) will have more normal Unix permission. You will be able to override with chmod for the effective permissions in WSL. Also note that in some cases there are Windows ACLs that also affect your effective permissions.

And finally, it’s generally not possible to delete files which are opened by another process in Windows, and therefore in WSL (which differs from plain Linux).

Configure Visual Studio Code for Developing in WSL/WSL2

See the Visual Studio Code Guide to Developing in WSL

Using Windows SSH Client for Git for Windows

Enable the ‘ssh-agent’ Service

  • On the latest Windows 10 Pro OpenSSH agent should be installed by default. If not it can be installed by installing the “OpenSSH Client” Windows ‘feature’.

  • Execute the commands:

    Set-Service -Name 'ssh-agent' -StartupType 'Automatic'
    Start-Service 'ssh-agent'

Make Windows OpenSSH Client the Default for Git for Windows

To set this for a single user set the environment variable GIT_SSH to point to the OpenSSH binary in the user’s environment variables.

[Environment]::SetEnvironmentVariable("GIT_SSH", "$((Get-Command ssh).Source)", [System.EnvironmentVariableTarget]::User)

To set it for all users, set GIT_SSH in the system environment variables.

In an admin PowerShell:

[Environment]::SetEnvironmentVariable("GIT_SSH", "$((Get-Command ssh).Source)", [System.EnvironmentVariableTarget]::Machine)

Configure Git for Windows for Better Linux Compatibility

1Ignore changes do file ‘mode’ bits (e.g. execute permissions)
2Make the default line ending for files Unix mode line endings. Windows 10 2004 supports text/source files of this type easily.
3Disable changing the line endings depending on whether checking out on Windows or under WSL.
4Set the default user name for commits and emails
5Set the default user email for commits and emails
6Make the default credential manager Git Credential Manager for Windows
git config --global core.fileMode false
git config --global core.eol lf
git config --global core.autocrlf false
git config --global "Your Name"
git config --global "Your email address"
git config --global credential.helper manager

A Bit of Extra GfW Configuration for Safer Pulls

This option prevents pulls from creating a merge or a forced update (i.e. rewriting history) or rebase. You can still git fetch and manually merge or rebase as necessary.

git config --global pull.ff only

Enabling Backups of WSL

Using a tool (in WSL) that can be run on a period basis and does ‘push’ backup is recommended. The tool I use is Borg but there are other options (like Restic).

  1. Install your backup program (e.g. apt-get install borgbackup).
  2. Create a script to do the backup.
    1. You want your ‘regular’ user for a home dir only backup.
    2. If you want to backup parts like /etc, you want the script to be executable by root, but readable only by root (or at least any passwords, etc.)
  3. In Windows, as the user account in which you installed the Linux distribution use Task Scheduler to create a period task that runs the script.
    1. Create a task (you probably want it to run even if you are not logged in).
    2. Choose your triggers.
    3. For the action:
      1. Use wsl.exe as the program to execute: NB Using the bare filename and making the C:\WINDOWS\System32 the working folder is required due to a bug in Task Scheduler.
      2. Set the folder to use as C:\WINDOWS\System32
      3. Set the arguments to -u user_to_runas -- /path/to/your/script.
    4. Complete creating the task.
    5. Save and do a test run. The ‘action’ should complete with exit code 0.

Make WSL the Default Environment for OpenSSH Server

OpenSSH on Windows is most useful for accessing the WSL/WSL2 environment. For GUI Windows applications you will need ‘Remote Desktop’ or an alternative and for system-level management you should probably use WinRMI. On the plus side, with WSL2 you can execute Windows commands from within the WSL2 environment.

To make WSL the default for OpenSSH server, in an admin PowerShell execute:

Set-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell "C:\WINDOWS\System32\wsl.exe"
Restart-Service 'sshd'

See also Microsoft’s Guide to Configuring OpenSSH Server

The Rest, as Suits Your Needs and Preferences

The rest is about learning what makes for a comfortable environment for you. I personally tend to get annoyed with ‘opinionated’ or ‘perfect’ setup guides, and am trying to create more flexible set of suggestions that can easily be adapted to suit you.

By Daniel F. Dickinson

Daniel Dickinson has been using and exploring computer and electronic technologies for over three decades. He is proficient with various flavours of Linux (including varieties of desktop, server, and embedded systems) as well as modern Windows. Daniel still enjoys software and firmware development, but prefers integration and extending existing open source solutions to quickly achieve desired goals. Fo more details see

Leave a comment

Your email address will not be published. Required fields are marked *