This website was built on DorikCreate your website today

By Axel Lenz | Last Updated: 3 June 2023

NinjaOne RMM Custom Felder für das Winget Patchmanagement

NinjaOne RMM Custom Felder automatisch befüllen – Winget Updates

In der Welt der IT-Administration ist jedes Werkzeug, das Zeit spart, ein Segen. NinjaOne RMM ermöglicht die Automatisierung von Prozessen durch die Verwendung von benutzerdefinierten Feldern. In diesem Artikel zeigen wir Ihnen, wie Sie ein Skript erstellen, das die Verfügbarkeit von Winget Updates erfasst und die NinjaOne RMM Custom Felder aktualisiert. Darauf kann wieder ein Alert (Bedingung) angelegt werden, damit automatische in Ticket erstellt wird oder ein Update gestartet.

Dazu legen wir einzeilige und mehrzeilige benutzerdefinierte Felder an und verweisen auf [diese Anleitung](https://www.ninjaone.com/de/blog/erweiterte-anwendungsmoeglichkeiten-fuer-benutzerdefinierte-felder-in-ninjaone-teil1/) für weitere Informationen.

Es werden die benutzerdefinierten Felder wingetVerfuegbareUpdatesListe (Multiline) und wingetVerfuegbareUpdates (Zahl) aktualisiert. Der Code des Skripts steht oben zur Verfügung.

Funktionen des Skripts

Das Skript besteht aus mehreren Funktionen, die jeweils unterschiedliche Aufgaben erfüllen. Hier ist eine kurze Übersicht über die Hauptfunktionen:

  • Get-WingetOutput: Diese Funktion liest die Winget-Ausgabe und gibt sie als Zeichenkette zurück.
  • Install-Winget: Diese Funktion installiert Winget automatisch, falls es noch nicht auf dem System vorhanden ist.
  • CheckWinget: Diese Funktion prüft, ob Winget bereits installiert ist und gibt den Pfad zur Winget-CLI-Datei zurück.
  • Filter-Lines: Diese Funktion filtert die Winget-Ausgabe, indem sie Zeilen mit bestimmten Schlüsselwörtern entfernt. Unnötige Zeilen filtern - z.B. Microsoft und Adobe.
  • Remove-Line: Diese Funktion entfernt eine bestimmte Zeile aus der Winget-Ausgabe.
  • Extract-UpdateCount: Diese Funktion extrahiert die Anzahl der verfügbaren Updates aus der gefilterten Winget-Ausgabe.

Anwendung des Skripts

Nachdem das Skript ausgeführt wurde, werden die verfügbaren Winget-Updates extrahiert, gefiltert und an NinjaOne übermittelt. Die benutzerdefinierten Felder `wingetVerfuegbareUpdatesListe` und `wingetVerfuegbareUpdates` werden mit den entsprechenden Informationen aktualisiert, sodass Administratoren auf einen Blick die verfügbaren Updates einsehen können.

Die Automatisierung dieses Prozesses spart Zeit und ermöglicht es IT-Administratoren, sich auf wichtigere Aufgaben zu konzentrieren. Durch die Nutzung benutzerdefinierter Felder in NinjaOne RMM können Administratoren ihre Systeme effizienter verwalten und auf dem neuesten Stand halten.

# Define the functions function Get-WingetOutput { $WingetCliPath = CheckWinget $WingetResult = [string[]](cmd /c ('"{0}" upgrade --accept-source-agreements --include-unknown' -f $WingetCliPath)) return $WingetResult } function Install-Winget { function getNewestLink($match) { $uri = "https://api.github.com/repos/microsoft/winget-cli/releases/latest" $get = Invoke-RestMethod -uri $uri -Method Get -ErrorAction stop $data = $get[0].assets | Where-Object name -Match $match return $data.browser_download_url } $wingetUrl = getNewestLink("msixbundle") $wingetLicenseUrl = getNewestLink("License1.xml") function section($text) { Write-Output "###################################" Write-Output "# $text" Write-Output "###################################" } function AAP($pkg) { Add-AppxPackage $pkg -ErrorAction SilentlyContinue } section("Downloading Xaml nupkg file... (19000000ish bytes)") $url = "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.1" $nupkgFolder = "Microsoft.UI.Xaml.2.7.1.nupkg" $zipFile = "Microsoft.UI.Xaml.2.7.1.nupkg.zip" Invoke-WebRequest -Uri $url -OutFile $zipFile section("Extracting appx file from nupkg file...") Expand-Archive $zipFile if ([Environment]::Is64BitOperatingSystem) { section("64-bit OS detected") AAP("https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx") AAP("Microsoft.UI.Xaml.2.7.1.nupkg\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx") } else { section("32-bit OS detected") AAP("https://aka.ms/Microsoft.VCLibs.x86.14.00.Desktop.appx") AAP("Microsoft.UI.Xaml.2.7.1.nupkg\tools\AppX\x86\Release\Microsoft.UI.Xaml.2.7.appx") } section("Downloading winget... (21000000ish bytes)") $wingetPath = "winget.msixbundle" Invoke-WebRequest -Uri $wingetUrl -OutFile $wingetPath $wingetLicensePath = "license1.xml" Invoke-WebRequest -Uri $wingetLicenseUrl -OutFile $wingetLicensePath section("Installing winget...") Add-AppxProvisionedPackage -Online -PackagePath $wingetPath -LicensePath $wingetLicensePath -ErrorAction SilentlyContinue <#section("Adding WindowsApps directory to PATH variable for current user...") $path = [Environment]::GetEnvironmentVariable("PATH", "User") $path = $path + ";" + [IO.Path]::Combine([Environment]::GetEnvironmentVariable("LOCALAPPDATA"), "Microsoft", "WindowsApps") [Environment]::SetEnvironmentVariable("PATH", $path, "User")#> section("Adding WindowsApps directory to PATH variable for all users...") $path = [Environment]::GetEnvironmentVariable("PATH", "Machine") $path = $path + ";" + [IO.Path]::Combine([Environment]::GetEnvironmentVariable("LOCALAPPDATA"), "Microsoft", "WindowsApps") [Environment]::SetEnvironmentVariable("PATH", $path, "Machine") section("Cleaning up...") Remove-Item $zipFile Remove-Item $nupkgFolder -Recurse Remove-Item $wingetPath Remove-Item $wingetLicensePath section("Installation complete!") section("Please restart your computer to complete the installation.") } function CheckWinget { ## Finde winget-cli ### Verzeichnis finden $WingetDirectory = [string]( $( if ([System.Security.Principal.WindowsIdentity]::GetCurrent().'User'.'Value' -eq 'S-1-5-18') { (Get-Item -Path ('{0}\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe' -f $env:ProgramW6432)).'FullName' | Select-Object -First 1 } else { '{0}\Microsoft\WindowsApps' -f $env:LOCALAPPDATA } ) ) ### Dateinamen finden $WingetCliFileName = [string](SourceAgreementsMarketMessage $( [string[]]( 'AppInstallerCLI.exe', 'winget.exe' ) ).Where{ [System.IO.File]::Exists( ('{0}\{1}' -f $WingetDirectory, $_) ) } | Select-Object -First 1 ) ### Verzeichnis und Dateinamen kombinieren $WingetCliPath = [string] '{0}\{1}' -f $WingetDirectory, $WingetCliFileName # Überprüfen, ob $WingetCli vorhanden ist if (-not [System.IO.File]::Exists($WingetCliPath)) { ##Write-Output -InputObject 'Winget wurde nicht gefunden.' ##Exit 1 Install-Winget } # Winget-Ausgabe-Codierung korrigieren $null = cmd /c '' $Global:OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() return $WingetCliPath } function Filter-Lines ($output, $keywords) { $filteredLines = @() $lines = $output -split "`n" foreach($line in $lines){ $containsKeyword = $false foreach($keyword in $keywords){ if($line -match $keyword){ $containsKeyword = $true break } } if(-not $containsKeyword){ $filteredLines += $line } } return $filteredLines } function Remove-Line ($output, $lineContent) { $lines = $output -split "`n" $cleanedOutput = @($lines | Where-Object { -not ($_ -match $lineContent) }) return $cleanedOutput -join "`n" } function Extract-UpdateCount ($output) { $lines = $output -split "`n" # $updateLines = @($lines | Where-Object { $_ -match "winget" }) $updateLines = @($lines | Where-Object { $_ -match "winget|msstore" }) return $updateLines.Count } # Use the functions $output = Get-WingetOutput $filteredLines = Filter-Lines $output @('Microsoft', 'Mindestens ein Paket', 'Aktualisierungen', ' -\\| ') $filteredLines = Filter-Lines $output @('Microsoft', 'Firefox', 'Mindestens ein Paket', 'Aktualisierungen', ' -\\| ') $filteredLines = Remove-Line $filteredLines "2 upgrades available." $filteredLines = Remove-Line $filteredLines " KB /" $filteredLines = Remove-Line $filteredLines " MB /" $filteredLines = Remove-Line $filteredLines "SourceAgreementsTitle" $filteredLines = Remove-Line $filteredLines "SourceAgreementsMarketMessage" $updateCount = Extract-UpdateCount $filteredLines # Print the results Write-Output "Filtered Lines:" Write-Output $filteredLines Write-Output "Update Count: $updateCount" # Gib Resultate an NinjaOne Ninja-Property-Set wingetVerfuegbareUpdatesListe $filteredLines | Out-Null Ninja-Property-Set wingetVerfuegbareUpdates $updateCount | Out-Null

# Define the functions

function Get-WingetOutput {

$WingetCliPath = CheckWinget

$WingetResult = [string[]](cmd /c ('"{0}" upgrade --accept-source-agreements --include-unknown' -f $WingetCliPath))

return $WingetResult

}

function Install-Winget {

function getNewestLink($match) {

$uri = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"

$get = Invoke-RestMethod -uri $uri -Method Get -ErrorAction stop

$data = $get[0].assets | Where-Object name -Match $match

return $data.browser_download_url

}

$wingetUrl = getNewestLink("msixbundle")

$wingetLicenseUrl = getNewestLink("License1.xml")

function section($text) {

Write-Output "###################################"

Write-Output "# $text"

Write-Output "###################################"

}

function AAP($pkg) {

Add-AppxPackage $pkg -ErrorAction SilentlyContinue

}

section("Downloading Xaml nupkg file... (19000000ish bytes)")

$url = "https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.1"

$nupkgFolder = "Microsoft.UI.Xaml.2.7.1.nupkg"

$zipFile = "Microsoft.UI.Xaml.2.7.1.nupkg.zip"

Invoke-WebRequest -Uri $url -OutFile $zipFile

section("Extracting appx file from nupkg file...")

Expand-Archive $zipFile

if ([Environment]::Is64BitOperatingSystem) {

section("64-bit OS detected")

AAP("https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx")

AAP("Microsoft.UI.Xaml.2.7.1.nupkg\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx")

} else {

section("32-bit OS detected")

AAP("https://aka.ms/Microsoft.VCLibs.x86.14.00.Desktop.appx")

AAP("Microsoft.UI.Xaml.2.7.1.nupkg\tools\AppX\x86\Release\Microsoft.UI.Xaml.2.7.appx")

}

section("Downloading winget... (21000000ish bytes)")

$wingetPath = "winget.msixbundle"

Invoke-WebRequest -Uri $wingetUrl -OutFile $wingetPath

$wingetLicensePath = "license1.xml"

Invoke-WebRequest -Uri $wingetLicenseUrl -OutFile $wingetLicensePath

section("Installing winget...")

Add-AppxProvisionedPackage -Online -PackagePath $wingetPath -LicensePath $wingetLicensePath -ErrorAction SilentlyContinue

<#section("Adding WindowsApps directory to PATH variable for current user...")

$path = [Environment]::GetEnvironmentVariable("PATH", "User")

$path = $path + ";" + [IO.Path]::Combine([Environment]::GetEnvironmentVariable("LOCALAPPDATA"), "Microsoft", "WindowsApps")

[Environment]::SetEnvironmentVariable("PATH", $path, "User")#>

section("Adding WindowsApps directory to PATH variable for all users...")

$path = [Environment]::GetEnvironmentVariable("PATH", "Machine")

$path = $path + ";" + [IO.Path]::Combine([Environment]::GetEnvironmentVariable("LOCALAPPDATA"), "Microsoft", "WindowsApps")

[Environment]::SetEnvironmentVariable("PATH", $path, "Machine")

section("Cleaning up...")

Remove-Item $zipFile

Remove-Item $nupkgFolder -Recurse

Remove-Item $wingetPath

Remove-Item $wingetLicensePath

section("Installation complete!")

section("Please restart your computer to complete the installation.")

}

function CheckWinget {

## Finde winget-cli

### Verzeichnis finden

$WingetDirectory = [string](

$(

if ([System.Security.Principal.WindowsIdentity]::GetCurrent().'User'.'Value' -eq 'S-1-5-18') {

(Get-Item -Path ('{0}\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe' -f $env:ProgramW6432)).'FullName' | Select-Object -First 1

}

else {

'{0}\Microsoft\WindowsApps' -f $env:LOCALAPPDATA

}

)

)

### Dateinamen finden

$WingetCliFileName = [string](SourceAgreementsMarketMessage

$(

[string[]](

'AppInstallerCLI.exe',

'winget.exe'

)

).Where{

[System.IO.File]::Exists(

('{0}\{1}' -f $WingetDirectory, $_)

)

} | Select-Object -First 1

)

### Verzeichnis und Dateinamen kombinieren

$WingetCliPath = [string] '{0}\{1}' -f $WingetDirectory, $WingetCliFileName

# Überprüfen, ob $WingetCli vorhanden ist

if (-not [System.IO.File]::Exists($WingetCliPath)) {

##Write-Output -InputObject 'Winget wurde nicht gefunden.'

##Exit 1

Install-Winget

}

# Winget-Ausgabe-Codierung korrigieren

$null = cmd /c ''

$Global:OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()

return $WingetCliPath

}

function Filter-Lines ($output, $keywords) {

$filteredLines = @()

$lines = $output -split "`n"

foreach($line in $lines){

$containsKeyword = $false

foreach($keyword in $keywords){

if($line -match $keyword){

$containsKeyword = $true

break

}

}

if(-not $containsKeyword){

$filteredLines += $line

}

}

return $filteredLines

}

function Remove-Line ($output, $lineContent) {

$lines = $output -split "`n"

$cleanedOutput = @($lines | Where-Object { -not ($_ -match $lineContent) })

return $cleanedOutput -join "`n"

}

function Extract-UpdateCount ($output) {

$lines = $output -split "`n"

# $updateLines = @($lines | Where-Object { $_ -match "winget" })

$updateLines = @($lines | Where-Object { $_ -match "winget|msstore" })

return $updateLines.Count

}

# Use the functions

$output = Get-WingetOutput

$filteredLines = Filter-Lines $output @('Microsoft', 'Mindestens ein Paket', 'Aktualisierungen', ' -\\| ')

$filteredLines = Filter-Lines $output @('Microsoft', 'Firefox', 'Mindestens ein Paket', 'Aktualisierungen', ' -\\| ')

$filteredLines = Remove-Line $filteredLines "2 upgrades available."

$filteredLines = Remove-Line $filteredLines " KB /"

$filteredLines = Remove-Line $filteredLines " MB /"

$filteredLines = Remove-Line $filteredLines "SourceAgreementsTitle"

$filteredLines = Remove-Line $filteredLines "SourceAgreementsMarketMessage"

$updateCount = Extract-UpdateCount $filteredLines

# Print the results

Write-Output "Filtered Lines:"

Write-Output $filteredLines

Write-Output "Update Count: $updateCount"

# Gib Resultate an NinjaOne

Ninja-Property-Set wingetVerfuegbareUpdatesListe $filteredLines | Out-Null

Ninja-Property-Set wingetVerfuegbareUpdates $updateCount | Out-Null

More on tecnuse

Get Daily News Of Worlds Top Tech Stories