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:
- you should ideally connect the standard user, not the admin user, with your Microsoft account
- 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:
- Press
Shift+F10
(orFn+Shift+F10
, depending on the laptop) to open a command prompt. - Run this command:
oobe\bypassnro
. - The computer will restart, and take us back to the "Select your Country" screen.
- Select a country and keyboard layout. (I use the US layout on my UK keyboard. I know.)
- At the "Let's connect you to a network" screen, select "I don't have internet".
- 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
. - Complete the Windows setup.
- Connect to the internet.
- 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:
- Disconnect from the internet.
- Press start and search for "other users".
- 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.
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!