Modern Desktop Architect

Using Winget with custom manifests (and auto updates)


With the release of Winget, we now have another app deployment method which works nicely with Intune.

At the moment building a custom Winget repo is not an easy task, but you can deploy using a custom manifest.

This blog post will cover how to use a custom manifest stored online to deploy an application and then using a runbook

The first thing to note is that a custom manifest has to be local, either on the machine itself, or on a network drive. Therefore we’ll grab the file and store it locally

The scripts I’m using are here: https://github.com/andrew-s-taylor/public/tree/main/Powershell%20Scripts/Winget

If you want to grab some manifests to test, the official repo is here: https://github.com/microsoft/winget-pkgs/tree/master/manifests

If we use Chrome as an example, most manifests will include 3 files, an installer, a locale and an app one, we need to get all 3

First up, create a temp folder for the files to live in (I’ve opted for a random with the date):

$directory = $env:TEMP
#Create Temp location
$random = Get-Random -Maximum 1000 
$random = $random.ToString()
$date =get-date -format yyMMddmmss
$date = $date.ToString()
$path2 = $random + "-"  + $date
$path = $directory + "\" + $path2 + "\"
new-item -ItemType Directory -Path $path

Now specify the filenames to use:

##File Name
$templateFilePathinstaller = $path + "chrome.installer.yaml"
$templateFilePathlocale = $path + "chrome.locale.yaml"
$templateFilePathversion = $path + "chrome.yaml"

Then download them:

Invoke-WebRequest `
   -Uri "https://raw.githubusercontent.com/andrew-s-taylor/winget/main/manifests/g/Google/Chrome/92.0.4515.107/Google.Chrome.installer.yaml" `
   -OutFile $templateFilePathinstaller `
   -UseBasicParsing `
   -Headers @{"Cache-Control"="no-cache"}


   Invoke-WebRequest `
   -Uri "https://raw.githubusercontent.com/andrew-s-taylor/winget/main/manifests/g/Google/Chrome/92.0.4515.107/Google.Chrome.locale.en-US.yaml" `
   -OutFile $templateFilePathlocale `
   -UseBasicParsing `
   -Headers @{"Cache-Control"="no-cache"}
   
   

   Invoke-WebRequest `
   -Uri "https://raw.githubusercontent.com/andrew-s-taylor/winget/main/manifests/g/Google/Chrome/92.0.4515.107/Google.Chrome.yaml" `
   -OutFile $templateFilePathversion `
   -UseBasicParsing `
   -Headers @{"Cache-Control"="no-cache"}  

Finally, install them. Note, as it is a multi-file manifest, the path is the containing folder which is why it’s best to download each into their own folder. With a single file manifest, you can specify the manifest file, but I find it’s easier to use the folder to keep things the same

winget install --silent  --manifest $path

The next thing we can do is use Proactive Remediations to keep your apps up to date:

Again, scripts are both on github:
https://github.com/andrew-s-taylor/public/blob/main/Powershell%20Scripts/winget-update-check.ps1

https://github.com/andrew-s-taylor/public/blob/main/Powershell%20Scripts/winget-upgrade.ps1

Winget at present isn’t the most powershell friendly so the check is simply counting the number of lines returned, anything 3 or less means no updates

Try {
    $updatecheck = winget upgrade
    If ($updatecheck.count -lt 3){
        Write-Output "Compliant"
        Exit 0
    } 
    Write-Warning "Not Compliant"
    Exit 1
} 
Catch {
    Write-Warning "Not Compliant"
    Exit 1
}

Then upgrade:

winget upgrade --all --force --silent

Note 1: I haven’t yet found a way to exclude an application from an -all upgrade which is slightly annoying because I’d prefer office updates to be handled via Intune directly. If anyone has found a way, let me know in the comments!

Note 2: When adding to Intune, make sure to select Run in the logged-in credentials or the scripts will fail:

That’s it, run at whatever schedule suits you and let the apps update themselves. Remember if it’s a custom app with a custom manifest, you’ll need to update the manifest file version too.

I’ll add a post on a custom repo once it’s a bit more user friendly

Add a Comment

Your email address will not be published. Required fields are marked *

LinkedIn
LinkedIn