Die einfachste Art, alle winget Applikationen via Intune oder allgemein zu updaten, ist via Scheduled Task oder mit einem Proactive Remediation Skript. Nicht immer ist es aber gewünscht beziehungsweise sinnvoll, alle Applikationen zu updaten. Darum habe ich begonnen, Updates ausgewählte winget Applikationen mit der Proactive Remediations Funktion auf dem neusten Stand zu halten.

Nachfolgen zeige ich dir auf, wie du beide Varianten, alle Applikationen oder nur eine selektiv, updaten kannst.

Die Funktion Proactive Remediations ist mit der Lizenz “Microsoft 365 Business Premium” nicht verfügbar, wie du sie trotzdem nutzen kannst, zeige ich dir hier: "Proactive Remediation for Business" | scloud

Table of Contents

Alle Applikationen Updaten

Mit dem Befehl "winget upgrade --all" kannst du alle ausstehenden Updates, die beim Windows Package Manager zur Verfügung stehen, updaten.
Diese Funktion können wir mit einem Proactive Remediations Paket anstossen, sobald winget Updates aussehend sind.

Wichtig zu beachten ist dabei, dass alle (auch nicht via winget installierte) Pakete auf dem Computer Updates erhalten.

Hier findest du beide Scripts zum Herunterladen:

Winget kann im System Kontext nicht einfach mit dem Befehl winget aufgerufen werden. Darum findest du in allen Scripts, die wir im Systemkontext laufen lassen, die Auflösung des Pfades zur winget.exe:

$Winget = Get-ChildItem -Path (Join-Path -Path (Join-Path -Path $env:ProgramFiles -ChildPath "WindowsApps") -ChildPath "Microsoft.DesktopAppInstaller*_x64*\winget.exe") 
Code language: PowerShell (powershell)

Diese wird dann im Code mit dem Befehl &$winget aufgerufen.

Detecion Rule - Sind winget Updates vorhanden?

Um herauszufinden, ob irgendein Update zur Verfügung steht, können wir einfach den Befehl "winget upgrade" absenden und anschliessend prüfen, ob uns dieser ein Feedback gibt.

$Winget = Get-ChildItem -Path (Join-Path -Path (Join-Path -Path $env:ProgramFiles -ChildPath "WindowsApps") -ChildPath "Microsoft.DesktopAppInstaller*_x64*\winget.exe")

if ($(&$winget upgrade) -gt 3) {
	Write-Host "Upgrade(s) available."
	exit 1 # upgrade available, remediation needed
}
else {
	Write-Host "No Upgrade available"
	exit 0 # no upgrade, no action needed
}
Code language: PowerShell (powershell)

Remediation Script - alle Updates durchführen

Wird das Detection Script mit dem Exit Code "1" beendet, signalisiert dies, dass das Remediation Script ausgeführt werden muss.
In diesem stossen wir nun den Upgradebefehl mit den nötigen Parametern an, um sicherzugehen, dass der User nichts sieht und die Updates "silent" durchlaufen.

try{
    $Winget = Get-ChildItem -Path (Join-Path -Path (Join-Path -Path $env:ProgramFiles -ChildPath "WindowsApps") -ChildPath "Microsoft.DesktopAppInstaller*_x64*\winget.exe")

    # upgrade command for ALL
    &$winget upgrade --all
    exit 0

}catch{
    Write-Error "Error while installing upgrade for: $app_2upgrade"
    exit 1
}
Code language: PowerShell (powershell)

Bis vor kurzem war der Update Befehl von winget wie nachstehend. Dieser funktioniert mit der aktuellen Version aber leider nicht.

&$winget upgrade --all --silent --force --accept-package-agreements --accept-source-agreements

Spezifische Appliaktion Updaten

Viel lieber als alle Apps update ich nur die, die ich will und das am liebsten pro Applikation gesteuert.
Dazu habe ich dann zusätzlich für jede Applikation eine einzelne Gruppe, die sowohl der App wie auch dem Proactive Remediations Paket zugewiesen ist.

Weil das Erstellen pro App etwas mühsamer ist, habe ich dazu ein Script erstellet, welches das entsprechende Paket gleich vorbereitet. Mehr dazu weiter unten.

Detecion Rule für winget Updates

Um zu erkennen, ob ein spezifisches App ein Update hat, rufe ich wieder den Befehl winget upgrade auf. Dieses Mal filtere ich ihn aber nach der winget ID und stosse die Remediation nur an, wenn diese in den ausstehenden Updates erkannt wird.
In der Detection ist es wichtig, dass du in der ersten Zeile anstelle von WINGETPROGRAMID die gewünschte ID eingibst (z.B. Microsoft.VisualStudioCode).

$app_2upgrade = "WINGETPROGRAMID"

# resolve and navigate to winget.exe
$Winget = Get-ChildItem -Path (Join-Path -Path (Join-Path -Path $env:ProgramFiles -ChildPath "WindowsApps") -ChildPath "Microsoft.DesktopAppInstaller*_x64*\winget.exe")

if ($(&$winget upgrade) -like "* $app_2upgrade *") {
	Write-Host "Upgrade available for: $app_2upgrade"
	exit 1 # upgrade available, remediation needed
}
else {
	Write-Host "No Upgrade available"
	exit 0 # no upgrade, no action needed
}
Code language: PowerShell (powershell)

Remediation - Update einer einzelnen App

Nun haben wir erkannt, dass unsere App ein ausstehendes Update hat und möchten dieses natürlich ausführen.
Dazu rufen wir den Upgrade-Befehl mit dem --exact Parameter und der entsprechenden ID auf. Die ID kannst du wieder in der obersten Zeile hinterlegen.

$app_2upgrade = "WINGETPROGRAMID"

try{
    # resolve and navigate to winget.exe
    $Winget = Get-ChildItem -Path (Join-Path -Path (Join-Path -Path $env:ProgramFiles -ChildPath "WindowsApps") -ChildPath "Microsoft.DesktopAppInstaller*_x64*\winget.exe")

    # upgrade command
    &$winget upgrade --exact $app_2upgrade --silent --force --accept-package-agreements --accept-source-agreements
    exit 0

}catch{
    Write-Error "Error while installing upgrade for: $app_2upgrade"
    exit 1
}
Code language: PowerShell (powershell)

Proactive Remediation Script erstellen / hochladen

Ob du dich für das Update aller Apps oder einer spezifischen entschieden hast, spielt keine Rolle. Das Erstellen des Pakets im Endpoint Manager ist bei beiden gleich.

Die Proactive Remediation Funktion ist etwas versteckt, du findest sie unter:
Reports > Endpoint analytics > Proactive remediations
Hier wählst du "Create script package" und vergibst einen aussagekräftigen Namen:

Im zweiten Schritt kannst du bereits das Detection- und Remediation-Script hochladen. Falls du eine spezifische App updatest, vergiss nicht, die ID vor dem Upload anzupassen.
Dass die Auflösung der winget.exe korrekt funktioniert, lassen wir das Script im x64 Bit Kontext laufen.

Proactive remediations, scripts

Einen Scope Tag musst du nicht zwingend setzten.

Bei der Zuweisung weisst du die gewünschte Zielgruppe zu.
Ich wähle dazu bei spezifischen Apps eine Gruppe mit dem App Namen, welcher ich dann Geräte oder andere Gruppen zuweisen kann.
Als Intervall setze ich "Täglich". Ist das Gerät zur Ausführungszeit nicht aktiv, wird die Aufgabe nachgeholt.

Proactive remediations, Zuweisung und Schedule

Nun musst du nur noch "Next" klicken und die Konfiguration abzusenden.

Proactive Remediations automatisiert erstellen

Hast du nun 10, 20 oder mehr Applikationen und möchtest für alle eine PAR-Regel einrichten, musst du jedes Mal das Detection- und Remediation-Script anpassen, diese hochladen und zuweisen - Mühsam!
Darum habe ich ein einfaches Script zur Automatisierung gemacht.

Das Script nimmt als Basis dieselben Dateien wie oben beschrieben und wechselt ebenfalls den String "WINGETPROGRAMID" aus. Zusätzlich lädt es das Paket hoch, weist es zu und setzt den Schedule.

Anwendung (easy)

  1. Lade das Script "procative-remediation-creation.ps1" herunter
  2. Führe das Script via PowerShell aus (Rechtsklick "Run with PowerShell" oder via Terminal)
  3. Fülle die angeforderten Daten ab
    1. PAR_name = Anzeige Name des Pakets
    2. winget_id = ID der gewünschten winget APP
    3. PAR_AADGroup = Gruppe, der das Paket zugewiesen wird
  4. Falls die erforderlichen PowerShell Module noch nicht installiert sind, werden diese installiert (Microsoft.Graph, AzureAD)
  5. Das Paket wird erstellt und die beiden Script zur Ablage im Ausführungsordner abgelegt.
  6. Script Paket wird hochgeladen und der angegebenen Gruppe zugewiesen.
    Währenddessen musst du dich zwei Mal anmelden. Das erste Mal ist für den Upload zum Endpoint Manager und das zweite Mal um die Gruppen ID für die Zuweisung auszulesen.

Anwendung für fortgeschrittene

Du kannst das Scrip noch via Terminal mit weiteren Parametern aufrufen, um beispielsweise eine eigene Beschreibung zu hinterlegen.
Hier sind alle möglichen Parameter:

ParameterBeschriebung
Publisherwird in der PAR-Übersicht angezeigt
PAR_nameAnzeige Name des Pakets
winget_idWinget ID, die in den beiden Scripts verwendet wird
PAR_descriptionBeschreibung des Pakets
Standard: Automatically created via PowerShell
PAR_RunAssystem (default) oder user
PAR_SchedulerDaily (default) oder Hourly
PAR_FrequencyIntervall der Ausführung, default: 1
PAR_StartTimeStartzeit für "Daily" Ausführung
PAR_RunAs32$true für Ausführung im 32bit Kontext
$false für Ausführung im 64bit Kontext (default)
PAR_AADGroupGruppe für die Zuweisung des PAR-Pakets
PAR_script_detectionPfad zum Detection Script (wird automatisch erstellt)
PAR_script_remediationPfad zum Remediation Script (wird automatisch erstellt)

Hier ein Beispiel, wie das Script aufgerufen werden kann:

call procative-remediation-creation.ps1 script

Kudos und weitere Automatisierung

Danke @Andrew Taylor für die Idee und dein Proactive Remediations Upload Script: Creating Intune Proactive Remediation via Powershell

Die Funktion Updates via winget und Proactive Remediations werde ich in einem zukünftigen Releas auch in meinem "Intune Win32 Deployer" integrieren.