How I setup up Windows machines for development

I just got a new Windows laptop to write some code and figured I might as well document the setup process so that I have something to refer to in the future. I have setup my machines this way since switching back to Windows in 2019 and it has served me well.

The crux of my setup is to use two Windows users: a local admin user for UAC approvals and a standard non-admin user for actual use.

Windows & admin user setup

When you start a laptop with Windows pre-installed for the first time, it shows a screen that asks you to select your Country.

A note about the default Windows setup experience

If I were to go through the Windows setup steps, it would force me to connect to the internet during setup, install updates, and then force me to setup an admin user linked to a Microsoft account.

This is not ideal for two reasons:

  1. you should ideally connect the standard user, not the admin user, with your Microsoft account
  2. you do not get to select the user's folder name in the C:\Users directory if you create a user linked to a Microsoft account.

There's a workaround to this as described by Mauro Huculak in How to bypass internet connection to install Windows 11 (2023) by Leo Notenboom in Setup Windows 11 with only a local account (2024). Thanks Mauro & Leo!

I hope Windows includes an advanced setup option for developers in the future.

Here's how I setup windows and the admin user:

  1. Press Shift+F10 (or Fn+Shift+F10, depending on the laptop) to open a command prompt.
  2. Run this command: oobe\bypassnro.
  3. The computer will restart, and take us back to the "Select your Country" screen.
  4. Select a country and keyboard layout. (I use the US layout on my UK keyboard. I know.)
  5. At the "Let's connect you to a network" screen, select "I don't have internet".
  6. At the "Who's going to use this device" screen, enter your admin username. I prefer using a short lowercase username for the admin user. This user's files will be stored at C:\Users\username .
  7. Complete the Windows setup.
  8. Connect to the internet.
  9. Press start and search for "updates" to install updates. You might have to restart a couple times.

Creating a standard user

I create a standard user as follows:

  1. Disconnect from the internet.
  2. Press start and search for "other users".
  3. Click on Add account, and follow the steps to create a standard user.

Again, remember to user a lowercase username.

At this point, I restart the computer and log into the standard user. I like to connect it to my Microsoft account, and set the user up (Windows theme, wallpaper, etc.) to my liking.

From this point on, I almost never log into the admin account. If I ever need to perform a task that requires admin permissions, the UAC prompt shows up and I'd use the admin user credentials to authorize. This is Windows' way of doing sudo.

Installing software

As far as possible, I install everything I need within the standard user's space.

To install command-line tools for use in Windows, I use scoop which installs the tools in the user space by default. For everything else I use winget but it does not always install to the current user.

To install scoop, follow the steps at scoop.sh:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression

I can use scoop to get the tools I need within Windows:

scoop install git
scoop install busybox
# ...

By default, Windows comes with "Windows PowerShell" pre-installed. I prefer using the cross-platform "PowerShell" as my shell on Windows:

winget install Microsoft.PowerShell

I like to use Visual Studio for development with large C# projects, and I can install that with winget:

# Get a list of supported Visual Studio versions
winget search VisualStudio

# Install the latest community release (personal machine)
winget install Microsoft.VisualStudio.2022.Community

Installing Ubuntu LTS (WSL2) and Docker Desktop

I store most of my NodeJS/Python/Go source code within a WSL2 distro, and use dev containers for development.

WSL2 cannot be installed/enabled for a single user, unfortunately. It can be installed with:

wsl --install

Next, I install a distro, which will be local to the current user:

# Get a list of supported Ubuntu distros 
winget search Canonical.Ubuntu

# Read more about a distro
winget show Canonical.Ubuntu.2404

# install the latest Ubuntu LTS distro
winget install Canonical.Ubuntu.2404

# Open a Ubuntu session from the terminal to setup an Ubuntu user

Next, I install Docker Desktop:

winget install Docker.DockerDesktop

Using Docker Desktop from a standard user requires a separate step as described in Understand permission requirements for Windows. From an elevated command prompt, add the current user to the docker-users group:

net localgroup docker-users <current-user> /add

Restart the computer, start Docker, go to Settings Resources WSL integration, and enable integration with Ubuntu-24.04. Docker commands should now run from within the WSL distro.

💡
I prefer to keep my main WSL distro clean: I try not to apt install anything within this distro unless absolutely needed. The static binaries I need (kubectl, nvim, etc.) go in the ~/.local/bin directory.

Conclusion

I still have some more setup work to do, but this is the gist of it. If I ever need to reset my computer, I can always log into the admin user and simply delete and recreate the standard user.

I don't know if this is the perfect setup for everyone, but I know this works for me since I almost never use the computer for anything other than development. If you need to store data (photo dump, videos, data sets, etc.), you might want to consider creating a disk partition.

Anyway, this has been a long post. Let me know what you think!