Anything I work on is either natively in the cloud like design documents and emails or it has a common distributed backup strategy with a few hundreds of replicas. I mean git repositories...
Everything else is transient on this machine, from unpublished commits to investigation files for an on-site issue.
So what makes changing machine complicated is the machine configuration and installed applications. Those need to be backed up somehow and I'll humbly share how I do it. Your mileage may vary.
Changing machines the painful way
I am always surprised to see programmers who will manually install everything they need whenever they get a new machine. I've seen many people postpone machine upgrades for months because of the overhead of transferring to the new machine.
And then when they do switch machines, there is a problem. It usually sounds like "one component is missing in my Visual Studio installation and an F# library won't build on my machine".
With a sufficiently large software, these issues amount to a list that ends up in a knowledge base and tribal knowledge gets built around the solutions. Countless hours are spent investigating these issues multiple times within each silo in the organization. I've even seen a case where the generally accepted solution was to install the company's software, then uninstall it so the dependencies will be present for the local build to succeed!
Simpler microservices and especially containerized development environments will change the game by adding the dependencies of the software under development as part of a source controlled container definition. Yet there will remain a certain number of applications which need to be installed, even if it's just git and some way to run the container. I think solving the problem of actually configuring a development machine in a repeatable manner will remain worthwhile for the foreseeable future.
Yearly is a pain, monthly is a breeze
The problem actually is quite similar to that very common backup strategy where we focus entirely the backup procedure instead of the restore procedure . We're sure we documented everything, but the problems emerge when we try to consume this documentation.
If we all reimaged our development machines every few months, any sane developer would have automated their machine setup. Next thing you'd know, teams would have put the common bits of that automation together in a shared starter package.
And as with automated tests, infrastructure as code and other routine automation, a big part of the value of automating the task doesn't come from the time saved not doing it manually, but from sharing the knowledge in the most unambiguous way possible : Code.
The team's setup script
Part of our machine setup is shared and maintained by the team in a shared version controlled location.
We use Chocolatey to install a few common packages, then install Visual Studio. The script also clones the mono-repo and builds the monolith application, but I'll leave that out. If you're using a more modern containerized multi-repo architecture, the bits of script below are only dependent on the .NET technology stack and git workflow.
Chocolatey and packages
I'll leave the actual installation of Chocolatey to the official documentation since they have changed it over the last year and it will keep up to date longer : docs.chocolatey.org/en-us/choco/setup
And what follows is a subset of our agreed upon choice of tools.
choco install git.install --params "/NoAutoCrlf /SChannel /NoShellIntegration /GitOnlyOnPath"
choco install linqpad -y
choco install sysinternals -y
choco install everything -y
choco install sql-server-express -y
choco install sql-server-management-studio -y
Visual Studio
This next script installs Visual Studio 2022.
# Visual Studio 2022
(New-Object System.Net.WebClient).DownloadFile("https://aka.ms/vs/17/release/vs_enterprise.exe", (Get-Item .).FullName + "/vs_enterprise.exe")
Start-Process "vs_enterprise.exe" -ArgumentList "--update --passive --wait" -Wait # Updates the Installer
Start-Process "vs_enterprise.exe" -ArgumentList "--passive --wait" -Wait # Installs Visual Studio 2022 if not present
Start-Process "vs_enterprise.exe" -ArgumentList "update --passive --wait" -Wait # Updates Visual Studio 2022
Remove-Item "vs_enterprise.exe"
And then apply the common .vsconfig file. In our case, the file is stored on a git repository which is cloned by the script.
If Visual Studio was not initially installed, it usually requires a reboot to proceed at this point, but the script is idempotent and can be executed again after the reboot to continue with the setup.
$VSInstallPath = & "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -version 17.0 -property installationPath
Start-Process "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vs_installer.exe" -ArgumentList "modify --config ""PathToVsConfig\.vsconfig"" --installPath ""$VSInstallPath""" -Wait
Visual Studio 2022 may have turned 64 bits and moved to "C:/Program Files", but Microsoft guaranteed to maintain the path for vswhere.exe and vs_installer.exe back in Visual Studio 2017, so we can safely hardcode the "Program Files(x86)" path for the foreseeable future.
Personal customization
Now this is where the $PROFILE file comes in for those parts of the setup that are custom to me.
I maintain an idempotent "setup-machine" Powershell function with the following.
Rider
First off, I am a big fan of Jetbrains' Rider. I use it for all of my main C# development and only fallback to Visual Studio for C++ and memory dump investigations.
Rider has a Chocolatey package that is regularly updated, but it doesn't add Rider to the PATH. Also, its installation path changes every minor version, so maintaining any sort of alias is painful. And their direct download link changes every minor version as well.
I currently install Rider using chocolatey and maintain an alias to it manually. I would be grateful for any better solution!
choco install jetbrains-rider -y
Git and pull requests
I use the following script to create Pull Requests for Azure DevOps directly from the command line.
function gitlogin
{
echo SECRET-PRIVATE-ACCESS-TOKEN | az devops login --organization https://AzureDevopsServerUrl.com/DefaultCollection
}
choco install azure-cli -y
refreshenv
az extension add --name azure-devops
Replace AzureDevOpsServerUrl with the URL to your DevOps Server SECRET-PRIVATE-ACCESS-TOKEN with your own PAT .
Using a PAT is only necessary when using an on-premise Azure DevOps Server. It will also show messages about not being supported, but if you're running a relatively recent version of Azure DevOps Server, it should work fine for the simple use cases.
This line sets up an alias for az repos pr
as git pr
( documentation ).
az devops configure --use-git-alias true
The following also makes git push a little easier to use by automatically creating the missing remote branch when pushing a new local branch.
git config --global push.default current
Combining these lets the normal git flow look like this :
gitlogin
git checkout -b user/kcoulombe/MyNewBranch
git add .
git commit -m "A very informative commit message"
git push
git pr create --open
The last command will open a browser tab with the PullRequest open to adjust the description.
More apps
This is my personal preference of tools.
Install-Module -Name posh-git
choco install powershell-core -y
choco install microsoft-windows-terminal -y
choco install paint.net -y
choco install powertoys -y
In order, these were...
- posh-git : Adds current branch information within the Powershell command prompt.
- Powershell Core : The next version of Powershell
- Windows Terminal : Making command line on Windows easier
- Paint.Net : Mostly just for editing screenshots
- Windows PowerToys : Power User tools for Windows
I have excluded a few other more niche applications like HxD , PerfView and quite a few internal tools.