Previous editions Link to heading

Why would I do this? Link to heading

In this guide, I will show you how I (primarily a Linux user) setup a Windows workstation to get:

  • a nice terminal emulator (Windows Terminal)
  • a package manager to automate installing and updating software (winget)
  • a set of desktop utilities for Windows (PowerToys)
  • a UNIX-like work environment (Windows Subsystem for Linux)
  • a good text editor that won’t mess with formatting (Visual Studio Code)
  • a solution to create and manage virtual machines (VirtualBox and Vagrant)

Changes since 2017 Link to heading

Purpose20172020
Package managerChocolateyWinget
Terminal EmulatorCmderWindows Terminal
ShellPowerShell 5.1PowerShell 7.0
Text EditorNotepad++Visual Studio Code
UNIX EnvironmentMSYS2Windows Subsystem for Linux
VirtualizationVirtualBox + VagrantVirtualBox + Vagrant

Much has changed in the field of software packaging for Windows, as Microsoft now provides official open source solutions with:

  • the Winget package manager, that is currently in preview;
  • the Windows Terminal emulator;
  • the Visual Studio Code text editor, with official plugins for common programming languages, and an active community providing additional extensions on the marketplace;
  • the revival of the PowerToys project, which comes with useful Quality of Life improvements.

On the personal side:

  • I haven’t had to use a Windows host as my main development machine for a while;
  • ditto for corporate environments; nowadays most developers are provided with a Linux or macOS laptop;
  • I now mostly work with Python and Go, which allows me to to most of the development, integration and testing on a Linux host, and cross-build installers and/or binaries for Windows;
  • I still do some testing on Windows, so it is nice keeping a decent setup!

OS Information Link to heading

  • Windows 10
  • Professional Edition (required for Windows Subsystem for Linux)
  • 64-bit

Step 1: Install the Winget package manager Link to heading

There is now an official Windows Package Manager, with open source repositories for:

Once installed, winget can be used from any terminal to install, update or remove packages:

$ winget search python

Watch for new packages, as the list of available software is steadily growing!

Step 2: Install the Windows Terminal emulator and shell session manager Link to heading

Windows Terminal is another open source nicety that provides a native terminal emulator and shell session manager, with all the features you would expect:

  • tabs and panes;
  • color schemes;
  • font selection;
  • PowerShell integration.

It is available on Winget as Microsoft.WindowsTerminal:

$ winget install Microsoft.WindowsTerminal

Step 3: Install (or upgrade) PowerShell Link to heading

PowerShell has come a long way since being a quirky shell abstraction over Win32 / .Net APIs. I’d recommend installing the latest stable version available from Winget to benefit from the latest features and integrations.

It is available on Winget as Microsoft.PowerShell:

$ winget install Microsoft.PowerShell

Step 4: Install the PowerToys desktop utilities Link to heading

Microsoft PowerToys date back to Windows 95, and provide:

  • utilities to tweak system settings;
  • convenient keyboard shortcuts;
  • user interface customizations;
  • utilities to rename files, work with images, setup alternate keyboard layouts;
  • various Quality of Life improvements.

PowerToys for Windows 10 has been published under an open source license, and provides useful utilities such as:

They are available on Winget as Microsoft.PowerToys:

$ winget install Microsoft.PowerToys

Step 5: Install the Visual Studio Code text editor Link to heading

Visual Studio Code provides a straightforward text editing interface, similar to the Atom and Sublime Text editors.

There are many official and community extensions available on the marketplace for common programming languages and frameworks.

It is worth noticing that Microsoft has led two efforts to improve and homogenize:

These protocols define standardized interfaces for language servers and debuggers, that can be implemented by programming language maintainers and tooling developers, as well as by maintainers of other text editors and Integrated Development Environments.

Visual Studio Code is available on Winget as Microsoft.VisualStudioCode:

$ winget install Microsoft.VisualStudioCode

Alternative: VSCodium Link to heading

VSCodium is a community-driven, freely-licensed and telemetry-free rebuilt of Microsoft’s Visual Studio Code.

Please note that for legal and licensing reasons, VSCodium uses a distinct marketplace for extensions: OpenVSX.

Here are the most noticeable differences I have observed:

  • extensions may be published under a (slightly) different name;
  • extensions may be published by a different user or organization;
  • some extensions specific to Microsoft are not available through VSCodium (such as Live Share or Pylance).

If you’re feeling crafty, there are some workarounds to configure VSCodium to use Microsoft’s marketplace:

VSCodium is available on Winget as VSCodium.VSCodium:

$ winget install VSCodium.VSCodium

Step 6: Install the Windows Subsystem for Linux Link to heading

Windows Subsystem for Linux provides a way to run a Linux environment on a Windows machine, with an official Ubuntu image available.

See WSL Installation for setup instructions.

Once installed, this provides a convenient development environment that allows installing and using GNU/Linux build toolchains to (cross-)compile and package software for windows, without having to:

  • setup MSYS2 / Cyngwin / MinGW;
  • setup a virtual machine with a Linux distribution.

There are some limitations though:

  • WSL is not a full Linux environment, rather a compatibility layer for running Linux binaries on Windows;
  • there is no actual Linux kernel running;
  • filesystems supported by Linux may not be supported by WSL (e.g. ext4);
  • applications with graphical interface are likely not to work.

Step 7: Install VirtualBox and Vagrant to manage virtual machines Link to heading

VirtualBox Link to heading

VirtualBox is a convenient virtualization solution available for Windows, Linux and MacOS, that comes with a graphical interface, and good drivers for graphics, CPU, RAM, networking and storage virtualization.

VirtualBox is available on Winget as Oracle.VirtualBox:

$ winget install Oracle.VirtualBox

Before creating new virtual machines, you may want to configure:

  • networking: host, bridge or NAT
  • graphics drivers: to run a graphical environment inside a VM (such as Gnome or KDE)
  • CPU, RAM and storage quotas: to provide appropriate resources to virtual machines
  • folder synchronization: to share data between the host (your Windows computer) and the guest (the virtual machine)
  • USB passthrough: to use USB devices from inside a VM

A limitation here is that to spin up a VM, you have to either:

  • use the installation image (ISO) and go through the full installation wizard;
  • start with an image of an existing VM, that may have incomplete or incorrect configuration (or someone else’s credentials, even).

As setting up a new VM can quite time-consuming as well as error-prone, this is where Vagrant will help!

Vagrant Link to heading

Vagrant is a tool by HashiCorp that automates setting up virtual machines with various virtualization providers, such as VirtualBox.

Vagrant is available on Winget as HashiCorp.Vagrant:

$ winget install HashiCorp.Vagrant

Once installed, you can use Vagrant to create and start virtual machines, such as:

  • a graphical environment, display manager and desktop environment that can be used for development;
  • a headless environment to run databases and servers.

Vagrant reads a Vagrantfile, that:

  • defines which provider is used to provision (create and manage) virtual machines;
  • describes the configuration and desired state of the virtual machines;
  • can invoke tools such as Ansible or Puppet to provision virtual machines.

Instead of starting from scratch, Vagrant comes with existing, pre-configured virtual machine templates, called Boxes.

With many boxes available from the Vagrant team and the community, this will make setting up new VMs a breeze!

Use cases Link to heading

Some scenarii I have been putting the tools mentioned above to good use.

Throw-away VMs Link to heading

  • Write a Vagrantfile to define and configure a new VM
  • Run vagrant up to create and start the VM
  • (…)
  • Run vagrant halt to stop the VM
  • Run vagrant destroy to delete the VM

Local development servers Link to heading

  • Configure VirtualBox networking so the VMs are created with a local IP address that can be reached from your host;
  • Write a Vagrantfile to define and configure one (or several) VMs
  • Run vagrant up to create and start the VMs
  • Reuse existing scripts, Ansible playbooks or Puppet manifests to provision the VMs
  • Deploy your applications to the VMs and run tests
  • Run vagrant halt to stop the VM
  • Run vagrant destroy to delete the VM

Local development environments Link to heading

Same as the above, with the addition of:

  • a graphical environment, display manager and desktop environment (Gnome, KDE, i3, etc.)
  • your favourite text editor or IDE
  • additional development tools such as Git, Postman, DBeaver, etc.

Shared development environment templates Link to heading

I have successfully (and repeatedly) used Vagrant, VirtualBox and Ansible to:

  • create a template VM
  • provision it with Ansible, using:
    • the same Ansible roles as on production servers
    • additional roles to setup a graphical environment, development tools, IDEs, etc.
    • adapted playbooks
  • archive the resulting VM as an base image
  • publish it to a shared location that can be used by developers to create their own VMs from

This ensures all developers:

  • start with a functional VM, with all requirements installed and pre-configured
  • can then configure their VMs to their needs
  • can quickly recreate a new VM