Bei gewissen Applikationen ist es wichtig, dass sie immer up-to-date sind. Dies kann gerade bei Fachapplikationen der Fall sein. Wenn man aber nicht die Kapazität hat, immer nach den neuen Versionen Ausschau zu halten und diese nach release zu paketieren, kann es hilfreich sein, dazu eine Automatisierung aufzubauen.
Eine solche habe ich anhand des Beispiels "LehrerOffice Desktop" aufgebaut. Hierzu greife ich über eine Remediation direkt auf die Vendor-URL der App zu und update so das Program bei Bedarf.
Table of Contents
Visualisierung
Hier habe ich dir den ganzen Ablauf einfach visualisiert. Genauso kannst du auch andere Applikationen, welche über eine statische URL verfügbar sind abbilden.
Detection
Remediation
(Proactive) Remediations Paket
Detection
In der Detection frage ich die Meatadaten der EXE ab und vergeliche diese mit dem Installationsdatum der lokalen Installation.
try{
$EXE_url = "https://cmi-bildung.ch/lo/dateien/easy/lo_desktop_windows.exe"
$EXE_meta = Invoke-WebRequest -method "Head" $EXE_url | Select Headers -ExpandProperty Headers
$EXE_onlineDT = [DateTime]::ParseExact($($EXE_meta."Last-Modified"), "ddd, dd MMM yyyy HH:mm:ss 'GMT'", [System.Globalization.CultureInfo]::InvariantCulture)
$EXE_onlineDTS = $EXE_onlineDT.ToString("yyyy-MM-dd")
$EXE_uninstall = Get-ItemProperty HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object{$_.DisplayName -eq "LehrerOffice Desktop"}
if(!$EXE_uninstall){
Write-Output "LehrerOffice not installed"
exit 1
}
$EXE_installDT = [DateTime]::ParseExact($($EXE_uninstall.InstallDate), "yyyyMMdd", $null)
$EXE_installDTS = $EXE_installDT.ToString("yyyy-MM-dd")
if($EXE_onlineDTS -gt $EXE_installDTS){
Write-Output "LehrerOffice update available"
exit 1
}else{
Write-Output "LehrerOffice is up-to-date"
exit 0
}
}catch{
Write-Error $_
}
Code language: PowerShell (powershell)
Schlägt die Detection an (Exit Code 1), wird das Remediation Script angestossen.
Remediation
In der Remediation laden ich nun die EXE von der definierten URL herunter und führe das Update mit dieser aus.
try{
$EXE_url = "https://cmi-bildung.ch/lo/dateien/easy/lo_desktop_windows.exe"
$EXE_localInstall = "$env:TEMP\LehrerOffice-installation.exe"
# Download latest EXE
(New-Object System.Net.WebClient).DownloadFile($EXE_url, $EXE_localInstall)
# install EXE
Start-Process $EXE_localInstall -ArgumentList '/VERYSILENT /NORUN /NOCANCEL /LOG="C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\LehrerOffice-EXE-install.log"' -Wait
}catch{
Write-Error $_
}
Code language: PHP (php)
Remediation Packet in Intune erstellen
Möchtest du den Updateprozess ebenfalls für LehrerOffice durchführen oder sie anpassen, findest du das die beiden Skripte hier zum Download:
Das Packet erstellst du nun in Intune:
Devices > Remediations > + Create script package
Dem Packet geben wir einen aussagekräftigen Namen und eine optionale Beschreibung.
In den Settings laden wir die beiden Skript Dateien hoch und wählen 64-bit für die PowerShell Ausführung aus.
Einen Scope musst du nur zuweisen, wenn das in deinem Intune Konzept vorgesehen ist.
Bei der Zuweisung definieren wir noch bei welcher Gruppe und wie oft die Detection ausgeführt werden soll.
In diesem Beispiel bei der Standardgruppe, täglich um 1.00 Uhr. Falls das Gerät zu diesem Zeitpunkt nicht läuft, wird die Ausführung nachgeholt.
Update in Ringen durchführen
Mit dieser art von Detection wird das Update immer am Tag des Releases ausgeführt. Möchtest du die Ausführung beispielsweise auf dem Grossteil der Geräte erst nach 7 Tagen ausführen, kannst du ein zweites Package erstellen und in diesem in der Detection folgenden Code ergänzen (Zeile 16), der prüft, ob das Update bereits seit 7 Tagen verfügbar ist.
$UpdateDelay = 7
if($EXE_onlineDTS -gt $(Get-Date).AddDays(-$UpdateDelay).ToString("yyyy-MM-dd")){
Write-Output "Update available, but not more than $UpdateDelay days"
exit 0
}
Code language: PowerShell (powershell)
Die Remediation bleibt in diesem Fall dieselbe.
Zusammenfassung
Mit diesem Remediation Paket hast du eine einfache Möglichkeit, ein Update einer App zu automatisieren. Zudem kannst du das Deployment mit dem Delay einfach in Ringe aufteilen und so ein Paket für "First", "Fast" und "Broad" erstellen. Natürlich hast du hier nicht so viel Kontrolle, wie wenn du das ganze wirklich in ein eigenes Repository wie beispielsweise DevOps packst und von dort deployst, dafür ist es wesentlich einfacher umgesetzt.
Etwas, dass es noch zu beachten gilt, falls das App sehr regelmässig Updates erhält, kann es sein, dass der Delay zu Problemen führen kann und Versionen übersprungen werden.
Have you heard of the Get-EvergreenApp Powershell Module? You might have just built a working replacement to Winget!
Not yet, but it sounds very promising.
Now I have a next project 😀 Thanks for the hint!
Nice explanantion
Super vielen Dank gute Lösung habe ich gleich implementiert und funktioniert perfekt.
Sehr cool, freut mich hat alles so schön geklappt 🙂
Instead of seperate script for each application. Using WinGet, might be a create script that which we can call required app names. suppose there are 10 application in the machine. Once we trigger the script , whatever app name mentioned in the script, only those apps only will start updating. Alos need to add days of delay. so using single script can be possible to update most of apps.
This works as well, my idea was to have the process visible for each application. With a script, the reporting just tells you that there were some updates.