Dateien für Updates in WSUS auflisten mit PowerShell

    Feature-Updates für Windows 10 in WSUSDie WSUS-Konsole zeigt zwar viele Eigen­schaften für Updates an, aber nicht, welche Dateien zu ihnen gehören. Wenn etwa der Speicher­platz knapp wird, dann kann es even­tuell nützlich sein zu wissen, welche Updates die größten Speicher­fresser sind. Mit PowerShell lässt sich dieses Rätsel lösen.

    Von Nutzen ist eine Übersicht über den Speicher­verbrauch nicht nur für einzelne Updates. Vielmehr dürfte es von Interesse sein, wie viel Platz bestimmte Klassi­fizierungen oder Produkte in Beschlag nehmen. Diese Information kann bei der Auswahl der Updates helfen, die man abonnieren möchte.

    Nicht gedacht ist ein solches Reporting, um Update-Dateien manuell zu löschen. Für diese Aufgabe gibt es den Assistenten für die Server-Bereinigung oder das dafür vorgesehene PowerShell-Cmdlet.

    Struktur des Content-Verzeichnisses von WSUS

    Die Update-Dateien befinden sich unter dem konfigurierten Content-Verzeichnis von WSUS. Sie sind einsortiert in Ordner, deren Namen aus bloß zwei Zeichen bestehen. Diese entsprechen den beiden letzten Zeichen der Dateinamen, die darin enthalten sind.

    Updates über Suchfunktion ermitteln

    Im ersten Schritt ruft man die Liste der Updates ab, zu denen man die Dateien finden möchte. Dafür eignet sich die Methode SearchUpdates() eines UpdateServer-Objekts. Sie durchsucht den Titel und die Beschreibung nach den angegebenen Begriffen:

    (Get-WsusServer).SearchUpdates("Jubiläumsversion")

    Nach Updates suchen mit der Methode SearchUpdates()

    Dieser Aufruf findet alle Updates für Windows 10 1607, in denen es als Jubiläumsversion bezeichnet wird. In der Praxis wird man hier Namen von Produkten wie Windows 10 oder Office 2016 angeben.

    Alternative Filter

    Natürlich könnte man Updates nicht nur anhand von Such­begriffen auswählen, sondern beispiels­weise auch anhand der Klassifizierung oder verschiedener Status­informationen:

    $up = (Get-WsusServer).GetUpdates() |
    ? {$_.GetUpdateClassification().Title -eq "Upgrades"}

    Damit würde man alle Upgrades (also Feature-Updates) erhalten, während

    $up = (Get-WsusServer).GetUpdates() |? IsSuperseded -eq $true

    alle Updates danach filtert, ob sie bereits durch ein anderes ersetzt wurden.

    Pfad extrahieren

    Die gefundenen Update-Objekte verfügen über die Methode GetInstallableItems(), deren Ergebnis ein Array namens files enthält. In diesem verbergen sich die Namen der Dateien, die zu einem Update gehören, und zwar in der Eigenschaft AbsolutePath von FileUri.

    Das vorangestellte /content/ ersetzen wir durch den tatsächlichen Pfad zum WSUS-Content, der sich über die Methode GetConfiguration() ermitteln lässt.

    Das ganze Script ist dann bloß ein 4-Zeiler:

    Alle Dateien für Funktions-Updates von Windows 10 anzeigen

    Dateien über Get-ChildItem anzeigen

    Das letzte Kommando könnte man gleich so ändern, dass die Dateinamen direkt an Get-ChildItem übergeben werden:

    Get-ChildItem ($up.GetInstallableItems().files.FileUri.AbsolutePath -replace '/content', $p)

    Da längst nicht alle Dateien, die zu einem Update gehören, auch herunter­geladen wurden, kann man sich die zahlreichen Fehler­meldungen sparen, indem man Get-ChildItem mit dem Parameter ErrorAction aufruft:

    gci -ErrorAction Silent ($up.GetInstallableItems().files.FileUri.AbsolutePath -replace '/content', $p)

    Speicherplatz berechnen

    Wenn es primär darum geht, den Speicherplatz zu berechnen, den alle Dateien für bestimmte Updates verbrauchen, dann kann man den letzten Befehl so ändern:

    Auf diese Weise erhält man die gesamte Größe der Update-Dateien in GB.

    Damit könnte man zum Beispiel herausfinden, wie viel Platz überholte ("superseded") Updates belegen, wenn man den ent­sprechenden Filter anlegt, wie oben beschrieben.

    Dubletten bereinigen

    Allerdings wird man bald feststellen, dass dabei eine unrealistisch große Zahl für den verbrauchten Speicherplatz heraus­kommt. Das liegt daran, dass sich mehrere Updates eine Datei teilen können, so dass diese dann mehrfach in der Liste vorkommt.

    Daher sollte man die Liste erst von Dubletten bereinigen, bevor man Get-ChildItem aufruft:

    $f = $up.GetInstallableItems().files.FileUri.AbsolutePath -replace '/content', $p| sort -Unique

    ((Get-ChildItem -ErrorAction Silent $f | measure -Sum -Property Length).sum)/1GB

    Die sortierte Liste wird hier in der Variablen $f zwischengespeichert und dann als Parameter an Get-ChildItem übergeben.

    Keine Kommentare