Using winget to automate software deployment to a new laptop
I got my first new laptop in six years this week! The new hardware is definitely exciting, but reviews aren’t really my thing, so while I’ll inevitably tweet about how the Microsoft Surface Laptop fares, that’s not the purpose of this post. This is more about the mundane job of porting all my usual applications over to a new PC, and a handy new Windows feature that helped to make things a little easier - winget
.
Before we get started, I want to acknowledge both that I’m late to the party on winget
and that there have been package managers around on Windows for years - but it’s certainly a cool and useful addition to the core operating system, which bucks the trend when you consider how frequently Microsoft removes more advanced features and options these days (or at least applies confusing double UIs).
I’ll also concede that taking the time to write a PowerShell script to automate software deployment is probably overkill for most users - myself included. The time spent on development and testing is probably greater than the amount of time it would take to download and install each package individually, but at the end of the day I now have a pre-baked script I can use to drop my software on any future systems.
Initial research
Before I even got as far as creating a PS1
file, my first step was to do some research to identify the software packages I wanted to install. To achieve this, I used the following winget
command.
This ran a search across all the configured repositories (by default, basically the Microsoft Store and winget
’s own one). The most important details were in the Id
column, which generally follows the format Developer.Product
. There were a lot of third-party apps that had the names of popular software in their own names, so this helped to sort the wheat from the chaff and identify the real packages.
During this planning stage, I considered the software I wanted to deploy to my new system and ran the winget search
command to find the corresponding packages until I had a complete list.
The PowerShell script
Now I could start writing a PowerShell script to iterate through my list of applications and try to install each of them. Firstly, I created an array to store the list (note that only the Id
values here match the repository data - the names are my own more readable ones, for display and logging only).
Next, I used a foreach
loop to work through each application in $install_apps
and attempt to run winget
to install the corresponding package according to its Id
, using the --silent
flag to keep output to a minimum and require as little user interaction as possible to complete the deployment.
There are a number of reasons why installation of any given application might fail - a missing package or insufficient permissions to name just a couple. To prevent missing software from flying under the radar, I used an if
/else
statement based on the winget
exit code ($LASTEXITCODE
) to detect any issues.
And that’s pretty much all I needed to get going! I also added a section to install Windows Subsystem for Linux (with Ubuntu) and a few extra lines to log failures to a file (in case I missed them in the terminal), but the code above would be perfectly adequate to try to install all the packages in the given list.
The results
So how did things go with the new laptop? Did my winget
PowerShell script solve all my problems and allow me to kick back and relax as my applications were automatically deployed to my new system?
Well, to tell the complete truth, not quite… But it was very close.
As you can see from the screenshot above, winget
undoubtedly made the job much quicker and easier, but it wasn’t entirely hands-off. Spotify was the only app that failed to install for some reason (perhaps because it’s one of those apps that come half-installed on a fresh Windows system?), but there were also a couple of others that required me to hit the Y
key to accept licence agreements and terms of use.
I eventually found a solution to this part of the issue - unfortunately just after I ran the script. You can accept licence agreements automatically by using the --accept-source-agreements
and --accept-package-agreements
parameters when running winget
.
Still, it was a fun experiment, saved a lot of time downloading installers from developer websites and running them manually via the GUI, and leaves me with a script that will be easy to repurpose to (almost) automate the setup of any new computers I adopt in future. While winget
isn’t the perfect zero-touch solution, I’d definitely recommend giving it a go - particularly if you ever find yourself in a situation where you need to set up multiple systems in a short time and a cheat code would help to preserve your sanity.