Sicherheitshinweis

Die hier bereitgestellten Skripte sind stets auf eigene Gefahr anzuwenden!
Daher immer erst mit einem nicht-kritischen System oder in einer Testumgebung ausführlich testen!


Einleitung

„Jeder kennt es, viele stöhnen darüber“,… die einen Windows Server Update Services (WSUS) betreuen. Es geht kurz um, um die WSUS-Datenbankeintrags- (Metadaten) Bereinigung einer nicht mehr benötigten „Klassifizierung“ und der dazugehörigen Updatedateien. Sprich: Die nicht mehr aktivierten und die somit nicht mehr benötigten Updatedateien, verbleiben weiterhin in der WSUS-Datenbank. Beliebtes Beispiel: Treiber und Treibersätze.

Es kann generell viel über die veraltete WSUS-Architektur bzw. -Entwicklung diskutiert werden, aber schlussendlich hilft es dem einen oder anderem Administrator nicht, der verzweifelt versucht, den WSUS-Betrieb wieder in den Griff zu bekommen!

Da ich immer wieder mit diesem Thema zu tun habe und auch im aktuellen Kundenprojekt, will ich hier meine bisherigen Erkenntnisse mit Euch teilen. Denn, es ist nicht wie so oft empfohlen, IMMER eine Re-Installation des WSUS-Dienstes notwendig, nur um die WSUS-Datenbank und / oder den WSUS-Content zu restrukturieren/verkleinern!


Kurzer Hintergrund

WSUS denkt grundsätzlich nicht daran, sich selbst zu optimieren, in dem die nicht mehr selektierten/aktivierten Datenbankeinträge (Medadaten) komplett aus der WSUS-Datenbank automatisch entfernt werden. Somit muss diesem Prozess nachgeholfen werden. Hierzu können die folgenden Codezeilen beitragen!


Vorbereitungen

  • Sich bewusst machen, welche Klassifizierungen aus der WSUS-Datenbank entfernt werden sollen.
  • Entsprechende Windows Updates müssen bereits in der WSUS-Konsole abgelehnt sein.
  • Die betreffenden PowerShell-Befehle auswählen und kopieren.
  • Die betreffenden PowerShell-Befehle müssen stets mit administrativen Berechtigungen ausgeführt werden.

Verbindungsparameter

Clear-Host
[String]$WsusServer = [System.Environment]::GetEnvironmentVariable("COMPUTERNAME")
[Boolean]$UseSSL    = $True
[Int32]$PortNumber  = 8531
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($WsusServer,$UseSSL,$PortNumber)

Verbindungsparameter ggf. anpassen, falls keine verschlüsselte Verbindung mit Eurer Umgebung aufgebaut werden sollte.

Unverschlüsselt:
[Boolean]$UseSSL = $False
[Int32]$PortNumber = 8530


Klassifizierungen auflisten

Komplette Ansicht aller verfügbaren Klassifizierungen:

(Get-WsusServer).GetUpdateClassifications() |
select Title, Description | Out-GridView

Ansicht der aktuell aktivierten Klassifizierungen:

(Get-WsusServer).GetSubscription().GetUpdateClassifications() | 
select Title, Description | Out-GridView

Klassifizierungen aus der Datenbank entfernen

Klassifizierung „Definitionsupdates“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Definitionsupdates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Definition Updates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Feature Packs“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Feature Packs"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Feature Packs"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Service Packs“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Service Packs"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Service Packs"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Sicherheitsupdates“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Sicherheitsupdates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Security Updates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Tools“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Tools"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Tools"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Treiber“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Treiber"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Drivers"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Treibersätze“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Treibersätze"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Driver Sets"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Update-Rollups“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Update-Rollups"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Update Rollups"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Updates“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Updates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Updates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Upgrades“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Upgrades"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Upgrade"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Klassifizierung „Wichtige Updates“ entfernen:

# [DE]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Wichtige Updates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "ist gelöscht."}

# [EN]
$wsus.GetUpdates() | 
Where {$_.UpdateClassificationTitle -eq "Critical Updates"} | 
ForEach-Object {$wsus.DeleteUpdate($_.Id.UpdateID);Write-Host $_.Title "is removed."}

Das Löschen der Datensätze in der WSUS-Datenbank (Metadaten), kann unter Umständen sehr lange dauern. In meinem Fall musste ich rund 74.000 Treiber- / Treibersatz- Updatedateien aus der WSUS-Datenbank entfernen und die Aktionen haben rund 5-6 Std. benötigt.

Nach dem erfolgreichen entfernen der Metadaten zur ausgewählten Klassifizierung, kann mit der Serverbereinigung auch der WSUS-Content erfolgreich entfernt werden und der WSUS gibt wieder den so dringend benötigten Festplattenplatz frei!

Vorteil an dieser Art der Bereinigung ist, dass hierfür direkt aus der PowerShell heraus, die notwendigen Aktionen durchgeführt werden können… Empfehlenswert ist jedoch immer, den Index der WSUS-Datenbank in regelmäßigen Abständen oder speziell nach solchen Aktionen sich wieder neu aufbauen zu lassen!


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.