Winget PowerShell module

I’ve been using Winget for a while now and whilst it’s fantastic, the command line interface sometimes wasn’t ideal, especially as I tend to live in PowerShell and like to be able to manipulate the output a bit.

For my winget scripts, I have been using some functions put together for an old Microsoft event which simply manipulate the command line output.

I was very excited to learn there is now an official Winget PowerShell module (still in alpha release) with some very exciting commands. In this post I’ll run through installing it and the commands available within it. This module needs PowerShell 7!

I also think this could be the answer to our Company Portal deployment issues, check that out below!

Testing the module

First, we need the module itself:

Install-Module -Name Microsoft.WinGet.Client

Then obviously we need to import it:

import-module -Name Microsoft.Winget.Client

Now we have the module installed, we can dig around and see what it can do:

(Get-Module microsoft.winget.client).ExportedCommands

As we can see, the commands are fairly similar to those available in the standard CLI, only these give us PS Objects to use:

To give an idea of the improvements, lets search for everything and export to a txt file

In the CLI:

winget search "" > c:\temp\wingetcli.txt

It works to an extent, but anything with a large package name is truncated which is a nightmare when trying to automate as then you have to deal with non-absolutes and you risk installing the wrong thing. Let’s use Windows Spotlight as an example:

Windows-Spotlight                           Windows-Spotlight.Windows-Spotliā€¦ 1.0.0.0        Moniker:  winget

Now we can switch to the PowerShell module. As this returns a PS Object, we can use out-gridview rather than messing with txt files

 Find-WinGetPackage "" | out-gridview

That’s an excellent start!

Just to double check:

Find-WinGetPackage "" | where-object Name -eq "Windows-Spotlight"

One which is particularly useful, I tend to search for a package before installing it. With the CLI that was a search and then a second command. With PowerShell, we can simply pipe through:

Find-WingetPackage "appname" | Install-WingetPackage

Ok, so the basic commands work better, but what about these new ones in the list?

Company Portal?

The one I am most excited about is repair-wingetpackagemanager

This command will re-install the Winget application as well as all dependancies. You may well be thinking “so what, Winget never breaks anyway”, BUT there is a huge advantage to this. When deploying a new machine, the Microsoft Store waits 15 minutes from first login before it downloads or updates any applications so the user can start working. This means that your Winget update is stopped and your Company Portal deployment is halted.

Using this PowerShell module and command we could package a Win32 app (or script) to:

  • Install the module
  • Repair Winget to update it
  • Install Company Portal (and any other required apps)

Let’s give it a try:

First we need to install nuget:

        $provider = Get-PackageProvider NuGet -ErrorAction Ignore
        if (-not $provider) {
            Write-Host "Installing provider NuGet"
            Find-PackageProvider -Name NuGet -ForceBootstrap -IncludeDependencies
        }

Then install and import our module

install-module microsoft.winget.client -Force -AllowClobber
import-module microsoft.winget.client

Install/Repair Winget

repair-wingetpackagemanager

Finally install the apps:

install-wingetpackage 9WZDNCRFJ3PZ -source msstore
install-wingetpackage 7zip.7zip

If deploying as an app, you may want to add a reg key, text file etc. at the end to use as a detection method.

Remember to deploy PowerShell 7 during ESP as a pre-requisite when using this!

Of course, this is one of my posts, so here is a script to sort it for you. It will deploy PS7 (latest version), then install Winget and company portal:

# GitHub API endpoint for PowerShell releases
$githubApiUrl = 'https://api.github.com/repos/PowerShell/PowerShell/releases/latest'

# Fetch the latest release details
$release = Invoke-RestMethod -Uri $githubApiUrl

##Find asset with .msi in the name
$asset = $release.assets | Where-Object { $_.name -like "*msi*" -and $_.name -like "*x64*" }

# Get the download URL and filename of the asset (assuming it's a MSI file)
$downloadUrl = $asset.browser_download_url
$filename = $asset.name

# Download the latest release
Invoke-WebRequest -Uri $downloadUrl -OutFile $filename

# Install PowerShell 7
Start-Process msiexec.exe -Wait -ArgumentList "/I $filename /qn"

# Start a new PowerShell 7 session
$pwshExecutable = "C:\Program Files\PowerShell\7\pwsh.exe"

# Run a script block in PowerShell 7
& $pwshExecutable -Command {
     $provider = Get-PackageProvider NuGet -ErrorAction Ignore
        if (-not $provider) {
            Write-Host "Installing provider NuGet"
            Find-PackageProvider -Name NuGet -ForceBootstrap -IncludeDependencies
        }
        install-module microsoft.winget.client -Force -AllowClobber
import-module microsoft.winget.client
repair-wingetpackagemanager
install-wingetpackage 9WZDNCRFJ3PZ -source msstore

}

You can also grab it from GitHub here:

https://github.com/andrew-s-taylor/public/blob/main/Powershell%20Scripts/Intune/deploy-winget-during-esp.ps1

Things to watch

Remember, this module is still in alpha so some things aren’t perfect, some commands don’t yet accept a pipe pass-through and the get-help needs help itself:

It is open source though so if you have time to help, I am sure it will be very much appreciated!

3 thoughts on “Winget PowerShell module”

  1. Hello Andrew,

    Many thanks for this, this helps me reaching for something I’d like to do, although I can’t seem to do it.

    I tried to bundle all this in an app and make it install as a mandatory app during AutoPilot, but that failed. Then I tried to make it as an app running after AutoPilot, and still no luck.

    If I try to run the lines in PowerShell, it works as expected and installs my list of WinGet apps. Would you please have an idea how to do this step by step? I’m missing something here, I think. Thanks a lot.

    Reply

Leave a Comment