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
Ein WSUS muss nicht zwingend re-installiert werden und wird auch seitens Microsoft generell nicht empfohlen. Daher bietet sich eher eine Zurücksetzung sämtlicher Updatedateien in der Datenbank (Metadaten) an. Denn über die Jahre haben sich in den meisten WSUS-Umgebungen Unmengen an Metadaten angesammelt, die durch den „Assistent für die Serverbereinigung“ nicht automatisch mit bereinigt bzw. entfernt werden.
Anwendungsbeispiel:
Im Normalfall werden nur die entsprechenden Produkte oder Klassifizierungen de-selektiert und man denkt, dass die Metadaten und schlussendlich auch der Content sich regelmäßig von den Altlasten befreien werden...
Dem ist aber nicht so und so verbleiben die unnötigen Metadaten in der WSUS-Datenbank und schlussendlich auch die Contentdaten auf dem WSUS-Server gespeichert. Aufgrund eines 1,1 TB großen WSUS-Contents und einer aufgeblähten Datenbank (> 7 GB) bei einem Kunden, entwickelte ich ein Skript zur Zurücksetzung aller Updateinformationen. Aus Online-Recherchen, in Zusammenarbeit mit dem Kunden und vielen Tests vor Ort, ist nun das folgende Skript entstanden.
Was tut das Skript
Das Skript verbindet sich unter PowerShell mit der WSUS-Datenbank, setzt ALLE Updatedateien auf ABGELEHNT, ENTFERNT ALLE Updatedateien aus der Datenbank, exportiert die aktiv gesetzten Produkte und Klassifizierungen, deaktiviert die aktiv gesetzten Produkte und Klassifizierungen, um schlussendlich diese wieder zu aktivieren, durch einen erneuten Import. Ohne den zuletzt genannten Schritt, ist zwar die Datenbank und der Content am Ende des Skripts leer, aber die WSUS-Konsole blieb fest der Überzeugung, dass es bei einer neuen, initialen Synchronisierung, bereits auf dem aktuellsten Stand sei. Sprich, leere Datenbank (0 Einträge), aktiv gesetzte Produkte und dennoch 0 neue Updatedateien zum herunterladen gefunden. Deswegen das deaktivieren und aktivieren der Produkte und Klassifizierungen.
Damit die Downstream-, Upstream- und Replikatserver gleichermaßen das Skript anwenden können, werden durch das Skript die Updatequellserverinformationen auf „Microsoft“ zurückgesetzt, um die Produkte und Kategorien bearbeiten zu können. Zuvor werden eventuell vorhandene, abweichende Einstellungen zu den Updatequellserverinformationen (z.B. interne Updateserverpfade und weitere aktiv gesetzte Optionen) eingesammelt und gespeichert, um nach Abschluss aller Maßnahmen, die Updatequellserverinformationen wiederherzustellen.
Nach dem entfernen aller Updatedateiinformationen aus der Datenbank, empfiehlt es sich, den Datenbankindex zu aktualisieren, die Serverbereinigung zu starten und die Datenbankgröße zu verkleinern. All diese Maßnahmen habe ich in einer separaten Windows-Aufgabe hinterlegt und führe die Aufgabe 1x täglich aus! Deshalb wird hier im Skript die hinterlegte Windows-Aufgabe „WSUS-Cleanup“ außer der Reihe aufgerufen und gestartet. Diese weiterführenden Maßnahmen habe ich hier im BLOG bereits in anderen Beiträgen beschrieben und diese können gerne übernommen werden. Das Ergebnis ist eine kleine, aber bereinigte Datenbank (~400 MB) und eine Contentspeichergröße von 0 Byte.
Zum Abschluss initialisiert das Skript die WSUS-Synchronisation, damit anhand der aktiv gesetzten Produkte- und Klassifizierungen, die zutreffenden Updatedateien erkannt und neu heruntergeladen werden können.
Ziel
Das Ziel soll es sein, hier einen Weg aufzuzeigen, wie ohne einer Re-Installation der WSUS-Rolle, die Datenbank und schlussendlich der Content erfolgreich auf NULL zurückgesetzt werden können.
Hinweis:
Das Skript erstellt ein entsprechendes LOG-Verzeichnis und hinterlegt dort alle Informationen zu den Vorgängen der Zurücksetzung.
Vorbereitungen
- lokale Sitzung auf dem WSUS-Server
- administrativ geöffnete PowerShell ISE
- PowerShell-Skript-Beispiel kopieren und einfügen
- Skript-Anpassung: $LogPath
- Skript-Anpassung: $TaskPath
- Skript-Anpassung: $TaskName
- ggf. Skript-Anpassung: [Boolean]$UseSSL = $True oder $False
- ggf. Skript-Anpassung: [Int32]$PortNumber = 8531 oder 8530
Skript ausführen
Bevor das Skript gestartet werden kann, ist jetzt die Chance, die aktiv gesetzten Produkte und Klassifizierungen an die neuen Gegebenheiten anzupassen! Da sonst die alten Werte übernommen werden und dadurch wieder die falschen Updatedateien durch die WSUS-Synchronisierung geladen werden…
PowerShell-Skript-Beispiel:
<# .SYNOPSIS WSUS-RESET, set Updatefiles in WID-Database and Contentstorage to NULL. .DESCRIPTION The script reset the WSUS-Database and Content to NULL. All Update informations are removed, after to proceed this script. .COMPONENT Requires Module UpdateServices .OUTPUTS Live output on screen. Log- and Configfiles under $LogPath. Empty WID-Database and Content. .NOTES Version: 1.0 Author: André Stuhr Creation Date: 11/01/2021 Purpose/Change: First initial script development #> Clear-Host #---------------------------------------- # Load Timestamp Function function Get-TimeStamp { return "[{0:yyyy-MM-dd} {0:HH:mm:ss}]" -f (Get-Date) } #---------------------------------------- # Variables $LogPath = "X:\_LOG\WSUSReset" $TaskPath = "\WSUS\" $TaskName = "WSUS-Cleanup" $WsusResetLog = "$LogPath\WsusResetLog.log" $WsusDenyLog = "$LogPath\WsusDenyLog.log" $WsusDeleteLog = "$LogPath\WsusDeleteLog.log" $expProd = "$LogPath\products.csv" $expCat = "$LogPath\categories.csv" #---------------------------------------- # Check Log-Path, and if not exist, then create new Directory If (!(Test-Path $LogPath)) { New-Item -ItemType Directory -Force -Path $LogPath | Out-Null Write-Host "LOG-VERZEICHNIS: Erstellt" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) LOG-VERZEICHNIS: $LogPath erstellt" | Out-File $WsusResetLog -Append } #---------------------------------------- # Connection informationen [String]$WsusServer = [System.Net.Dns]::GetHostByName($env:computerName).HostName [Boolean]$UseSSL = $True [Int32]$PortNumber = 8531 #---------------------------------------- # Load .NET assembly [void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") #---------------------------------------- # Connect to WSUS Server $IPAddress = (Get-NetIPAddress -CimSession $WsusServer -AddressFamily IPv4 | where {$_.InterfaceAlias -notmatch 'Loopback'}).IPAddress $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($WsusServer,$UseSSL,$PortNumber) Write-Host "Verbindung zum $WsusServer ($IPAddress) hergestellt" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) Verbindung zum $WsusServer ($IPAddress) hergestellt" | Out-File $WsusResetLog -Append #---------------------------------------- # Get Synchronization Process $SyncStatus = $wsus.GetSubscription().GetSynchronizationStatus() if ($SyncStatus -eq 'Running') { # Stop the WSUS-Synchronization process $wsus.GetSubscription().StopSynchronization() Write-Host "SYNCHRONISATION: Prozess gestoppt" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) SYNCHRONISATION: Prozess gestoppt" | Out-File $WsusResetLog -Append } else { Write-Host "SYNCHRONISATION: Prozess inaktiv" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) SYNCHRONISATION: Prozess inaktiv" | Out-File $WsusResetLog -Append } #---------------------------------------- # Set to Microsoft Update Server $ReadUpdateServer = $wsus.GetConfiguration().SyncFromMicrosoftUpdate if ($ReadUpdateServer -eq $False) { # Read current Values [String]$UpstreamWsusServerName = $wsus.GetConfiguration().UpstreamWsusServerName [Int32]$UpstreamWsusServerPortNumber = $wsus.GetConfiguration().UpstreamWsusServerPortNumber [Boolean]$UpstreamWsusServerUseSsl = $wsus.GetConfiguration().UpstreamWsusServerUseSsl [Boolean]$IsReplicaServer = $wsus.GetConfiguration().IsReplicaServer # Set to Microsoft Update Server $wsus | Set-WsusServerSynchronization -SyncFromMU | Out-Null Write-Host "UPDATEQUELLE: nach Microsoft geändert" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) UPDATEQUELLE: nach Microsoft geändert" | Out-File $WsusResetLog -Append } else { Write-Host "UPDATEQUELLE ÄNDERN: Keine Änderung erforderlich!" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) UPDATEQUELLE ÄNDERN: Keine Änderung erforderlich!" | Out-File $WsusResetLog -Append } #---------------------------------------- # Define Windows Update Scope $updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope $u=$wsus.GetUpdates($updatescope) Write-Host "UPDATEDATEIEN ABLEHNEN: Gestartet" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) UPDATEDATEIEN ABLEHNEN: Gestartet" | Out-File $WsusResetLog -Append # Process for each Windows Updatefile, which is not Declined foreach ($u1 in $u) { if (-not $u1.IsDeclined -eq $true) { Write-Host ABGELEHNT: $u1.Title Write-Output $(Get-TimeStamp) ABGELEHNT: $u1.Title | Out-File $WsusDenyLog -Append $u1.Decline() } } Write-Host "UPDATEDATEIEN ABGELEHNT: Abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) UPDATEDATEIEN ABGELEHNT: Abgeschlossen" | Out-File $WsusResetLog -Append #---------------------------------------- # Delete the Updatefiles of all Categories Write-Host "UPDATEDATEIEN ENTFERNEN: Gestartet" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) UPDATEDATEIEN ENTFERNEN: Gestartet" | Out-File $WsusResetLog -Append $wsus.GetUpdates() | Where {$_.UpdateClassificationTitle -like "*"} | ForEach-Object ` { $wsus.DeleteUpdate($_.Id.UpdateID);Write-Host ENTFERNT: $_.Title Write-Output $(Get-TimeStamp) ENTFERNT: $_.Title | Out-File $WsusDeleteLog -Append } Write-Host "UPDATEDATEIEN ENTFERNT: Abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) UPDATEDATEIEN ENTFERNT: Abgeschlossen" | Out-File $WsusResetLog -Append #---------------------------------------- # Export all current and selected Products $wsus.GetSubscription().GetUpdateCategories() | select Title, ID | Export-Csv $expProd -Encoding UTF8 -UseCulture -NoTypeInformation Write-Host "PRODUKT-EXPORT: Abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) PRODUKT-EXPORT: $expProd" | Out-File $WsusResetLog -Append #---------------------------------------- # Disable all un- and selected Products $wsus | Get-WsusProduct | where {$_.TitleIncludes -like "*"} | Set-WsusProduct -Disable Write-Host "PRODUKTE-DEAKTIVIERT: Abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) PRODUKTE-DEAKTIVIERT: Abgeschlossen" | Out-File $WsusResetLog -Append #---------------------------------------- # Import/Enable all exported, selected Products Write-Host "WIEDERHERSTELLUNG: Produkt-Import gestartet" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Produkt-Import gestartet" | Out-File $WsusResetLog -Append $csvProduct = Import-Csv -Path $expProd -UseCulture $csvData = foreach($product in $csvProduct) { $wsus | Get-WsusProduct | Where-Object {$_.Product.Id -eq $product.Id} | Set-WsusProduct Write-Host WIEDERHERSTELLUNG: $product.Title Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: $product.Title" | Out-File $WsusResetLog -Append } Write-Host "WIEDERHERSTELLUNG: Produkt-Import abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Produkt-Import abgeschlossen" | Out-File $WsusResetLog -Append #---------------------------------------- # Get new selected Products $wsus.GetSubscription().GetUpdateCategories() | select Title, Id | Out-GridView #---------------------------------------- # Export all current and selected Categories $wsus.GetSubscription().GetUpdateClassifications() | select Title, Id | Export-Csv $expCat -Encoding UTF8 -UseCulture -NoTypeInformation Write-Host "Kategorien-EXPORT: Abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) Kategorien-EXPORT: $expCat" | Out-File $WsusResetLog -Append #---------------------------------------- # Disable all un- and selected Categories $wsus | Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Title -like "*"} | Set-WsusClassification -Disable Write-Host "Kategorien-DEAKTIVIERT: Abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) Kategorien-DEAKTIVIERT: Abgeschlossen" | Out-File $WsusResetLog -Append #---------------------------------------- # Import/Enable all exported, selected Categories Write-Host "WIEDERHERSTELLUNG: Kategorien-Import gestartet" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Kategorien-Import gestartet" | Out-File $WsusResetLog -Append $csvCategories = Import-Csv -Path $expCat -UseCulture $csvData = foreach($category in $csvCategories) { $wsus | Get-WsusClassification | Where-Object -FilterScript {$_.Classification.Id -eq $category.Id} | Set-WsusClassification Write-Host WIEDERHERSTELLUNG: $category.Title Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: $category.Title" | Out-File $WsusResetLog -Append } Write-Host "WIEDERHERSTELLUNG: Kategorien-Import abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Kategorien-Import abgeschlossen" | Out-File $WsusResetLog -Append #---------------------------------------- # Get new selected Categories $wsus.GetSubscription().GetUpdateClassifications() | select Title, Id | Out-GridView #---------------------------------------- # Restore Upstreamsource Settings $UpdateServerConfig = @{UssServerName=$UpstreamWsusServerName;PortNumber=$UpstreamWsusServerPortNumber} if ($ReadUpdateServer -eq $True) { Write-Host "WIEDERHERSTELLUNG: Updatequelle Microsoft (ursprüngliche Konfiguration)" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updatequelle Microsoft (ursprüngliche Konfiguration)" | Out-File $WsusResetLog -Append } elseif ($UpstreamWsusServerUseSsl -eq $true -and $IsReplicaServer -eq $true) { $wsus | Set-WsusServerSynchronization @UpdateServerConfig -UseSsl -Replica | Out-Null Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" -ForegroundColor "Yellow" Write-Host "WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" Write-Host "WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" Write-Host "WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" Write-Host "WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" | Out-File $WsusResetLog -Append } elseif ($UpstreamWsusServerUseSsl -eq $true -and $IsReplicaServer -eq $false) { $wsus | Set-WsusServerSynchronization @UpdateServerConfig -UseSsl | Out-Null Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" -ForegroundColor "Yellow" Write-Host "WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" Write-Host "WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" Write-Host "WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" Write-Host "WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" | Out-File $WsusResetLog -Append } elseif ($UpstreamWsusServerUseSsl -eq $false -and $IsReplicaServer -eq $true) { $wsus | Set-WsusServerSynchronization @UpdateServerConfig -Replica | Out-Null Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" -ForegroundColor "Yellow" Write-Host "WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" Write-Host "WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" Write-Host "WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" Write-Host "WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" | Out-File $WsusResetLog -Append } else { $wsus | Set-WsusServerSynchronization @UpdateServerConfig | Out-Null Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" -ForegroundColor "Yellow" Write-Host "WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" Write-Host "WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" Write-Host "WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" Write-Host "WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" Write-Host "WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen gestartet" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SERVERNAME: $UpstreamWsusServerName" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-PORT: $UpstreamWsusServerPortNumber" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-SSL: $UpstreamWsusServerUseSsl" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG-REPLIKAT: $IsReplicaServer" | Out-File $WsusResetLog -Append Write-Output "$(Get-TimeStamp) WIEDERHERSTELLUNG: Updateserver Synchronisationseinstellungen abgeschlossen" | Out-File $WsusResetLog -Append } #---------------------------------------- # Start the WSUS-Cleanup ScheduleTask Start-ScheduledTask -CimSession $WsusServer -TaskPath $TaskPath -TaskName $TaskName Write-Host "WSUS-BEREINIGUNGSPROZESS: Wsus-Cleanup gestartet (Aufgabenplanung)" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) WSUS-BEREINIGUNGSPROZESS: Wsus-Cleanup gestartet (Aufgabenplanung)" | Out-File $WsusResetLog -Append #---------------------------------------- # Check TaskSchedule State before go further while (Get-ScheduledTask -CimSession $WsusServer -TaskPath $TaskPath -TaskName $TaskName | where {$_.State -ne "Ready"}) { Write-Host (Get-Date) -ForegroundColor "Cyan" Write-Host "STATUS: Bereinigungsprozess..." -ForegroundColor "Cyan" Write-Host "STATUS: Aktualisierung in 20 Sekunden" -ForegroundColor "Cyan" Start-Sleep -Seconds 20 cls } Write-Host "WSUS-BEREINIGUNGSPROZESS: abgeschlossen!" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) WSUS-BEREINIGUNGSPROZESS: abgeschlossen!" | Out-File $WsusResetLog -Append #---------------------------------------- # Start the initial WSUS-Synchronization process $wsus.GetSubscription().StartSynchronization() Write-Host "INITIAL-SYNCHRONISATION: gestartet!" -ForegroundColor "Yellow" Write-Output "$(Get-TimeStamp) INITIAL-SYNCHRONISATION: gestartet!" | Out-File $WsusResetLog -Append #---------------------------------------- # Check, if the initiale Synchronisation is Done while ($wsus.GetSubscription().GetSynchronizationStatus() -ne "NotProcessing") { Write-Host (Get-Date) -ForegroundColor "Cyan" Write-Host "STATUS: Initial-Synchronisation aktuell in Prozess..." -ForegroundColor "Cyan" Write-Host "STATUS: Aktualisierung in 5 Minuten" -ForegroundColor "Cyan" Start-Sleep -Seconds 300 cls } Write-Host "INITIAL-SYNCHRONISATION: abgeschlossen!" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) INITIAL-SYNCHRONISATION: abgeschlossen!" | Out-File $WsusResetLog -Append #---------------------------------------- Write-Host "ENDE: WSUS Komplettbereinigung" -ForegroundColor "Green" Write-Output "$(Get-TimeStamp) ENDE: WSUS Komplettbereinigung" | Out-File $WsusResetLog -Append
Skriptausgabe
Das Skriptbeispiel gibt in der Ausführung den aktuellen Bearbeitungsstand und die entsprechenden Informationen in Echtzeit aus (siehe die folgenden Screenshots).
Bereinigungsprozess starten
Achtung:
Handelt es sich um einen WSUS-Server, der nicht direkt die Windows Updates von Microsoft bezieht, dann kann es unter ganz bestimmten Umständen dazu kommen, dass die erneute, initiale Synchronisierung kurz nach dem Start mit einer Erfolgsmeldung den Vorgang beendet. Sprich, das zurückgesetzte WSUS-System ist der Meinung, dass es keine neuen, verfügbaren Windows Updates herunterzuladen gibt!
Lösung:
Auf dem übergeordnetem WSUS-System unter "Downstreamserver", dass zurückgesetzte WSUS-System manuell auswählen und löschen! Anschließend den Synchronisationsvorgang auf dem zurückgesetzten WSUS-System manuell anstoßen und durchlaufen lassen.
Das Erarbeiten und die Entwicklung dieses Skripts hat sehr viel Zeit in Anspruch genommen und war nicht immer ganz leicht. Vor allem, da die gut gemeinten Befehle aus dem TechNet, nicht immer funktionierten bzw. funktionieren. Daher freue ich mich stets über eine Rückmeldung, ob das Skript nun auch in anderen Umgebungen erfolgreich zum Einsatz gekommen ist oder ob es hier noch weitere Stolpersteine zu geben scheint… Das Skript ist eigentlich so entwickelt, dass es generell überall eingesetzt werden kann, bis auf ein paar wenige Änderungen, wie eingangs unter den Vorbereitungen erwähnt. Gerne nehme ich auch weitere, sinnvolle Codezeilen mit auf, sollten diese mir genannt und von mir erneut validiert worden sein!
Hallo. Ich probiere dieses Script um unseren WSUS zu bereinigen. Allerdings läuft es nun seit 24h und es sind bisher allein ca. 22.000 „Nvidia Driver …“ entfernt worden. Das Delete-Log selbst umfasst inzwischen 150.000 Zeilen. Also ca. 30.000 Einträge. Erscheint mir dann doch unplausibel.
Ja, wir hatten „Treiber“ mal für ein paar Tage eingeschaltet, aber wieder deaktiviert.
Dennoch ist die Anzahl sehr hoch, hingegen die Dateianzahl im WSUS Content allerdings nicht weniger wird. Würde mich über einen Hinweis freuen. Herzlichen Gruß.
Moin Simon,
initial kann das Skript tatsächlich sehr lange benötigen. Je nachdem, wie viel Treiber Informationen aufgelaufen sind über die Jahre oder halt auch nur bei einem initialen Sync. Der WSUS schmeißt nichts selber weg und muss daher dazu gezwungen werden!
Bei einem Kunden musste ich einst 1,3 TB Treiber Dateien ablehnen und entfernen. Das hat 1,5 Tage gedauert… daher ist deine aktuelle Dauer noch im Zeitrahmen. 😉
Bitte beachte noch die ähnlichen Beiträge zum Schluss des Artikels!
Die lasse ich alle wie hier im Skript zu sehen ist, in der Aufgabenplanung ablaufen:
Prio 1 – https://www.sit-administration.de/wsus-synchronisierungen-entfernen-susdb/ (wsus_sync.cmd)
Prio 2 – https://www.sit-administration.de/wsus-serverbereinigung/ (wsus_cleanup.ps1)
Prio 3 – https://www.sit-administration.de/wsus-datenbankindex-neu-erstellen-defragmentieren-susdb/ (wsus_index.cmd)
Prio 4 – https://www.sit-administration.de/wsus-datenbankgroesse-susdb-verkleinern/ (wsus_dbshrink.cmd)
Das Skript hier ist aus einem Projekt heraus entstanden und nutzt daher die hier verwendeten Bausteine, um einen kompletten WSUS-RESET durchführen zu können.
Ich hoffe das hilft, ansonsten melde Dich! 🙂
Grüße, André
Hallo André,
danke erstmal für das umfängliche Script. Da ich mich nächstest Wochenende dran setzen will, den WSUS bei uns zu resetten, hab ich nur eine kurze Frage:
$TaskPath = „\WSUS\“ – ist hier das Installationsverzeichnis des WSUS gemeint oder der Speicherort des WSUSContent
Wir haben den WSUSContent Ordner auf eine andere Festplatte verschoben gehab, da dieser zu groß geworden ist.
Über eine kurze Rückmeldung wäre ich Dir dankbar.
Viele Grüße,
Ines
Grüß Dich Ines,
$TaskPath betrifft das folgende Code-Schnipsel:
# Start the WSUS-Cleanup ScheduleTask
Start-ScheduledTask -CimSession $WsusServer -TaskPath $TaskPath -TaskName $TaskName
Write-Host „WSUS-BEREINIGUNGSPROZESS: Wsus-Cleanup gestartet (Aufgabenplanung)“ -ForegroundColor „Yellow“
Write-Output „$(Get-TimeStamp) WSUS-BEREINIGUNGSPROZESS: Wsus-Cleanup gestartet (Aufgabenplanung)“ | Out-File $WsusResetLog -Append
#—————————————-
# Check TaskSchedule State before go further
while (Get-ScheduledTask -CimSession $WsusServer -TaskPath $TaskPath -TaskName $TaskName | where {$_.State -ne „Ready“})
{
Write-Host (Get-Date) -ForegroundColor „Cyan“
Write-Host „STATUS: Bereinigungsprozess…“ -ForegroundColor „Cyan“
Write-Host „STATUS: Aktualisierung in 20 Sekunden“ -ForegroundColor „Cyan“
Start-Sleep -Seconds 20
cls
}
Write-Host „WSUS-BEREINIGUNGSPROZESS: abgeschlossen!“ -ForegroundColor „Green“
Write-Output „$(Get-TimeStamp) WSUS-BEREINIGUNGSPROZESS: abgeschlossen!“ | Out-File $WsusResetLog -Append
Ich habe andere „Aktionen der Serveroptimierung“ in den folgenden Artikeln beschrieben und das alles in einer einzigen Aufgabe zusammengefasst (Wsus-Cleanup):
Prio 1 – https://www.sit-administration.de/wsus-synchronisierungen-entfernen-susdb/ (wsus_sync.cmd)
Prio 2 – https://www.sit-administration.de/wsus-serverbereinigung/ (wsus_cleanup.ps1)
Prio 3 – https://www.sit-administration.de/wsus-datenbankindex-neu-erstellen-defragmentieren-susdb/ (wsus_index.cmd)
Prio 4 – https://www.sit-administration.de/wsus-datenbankgroesse-susdb-verkleinern/ (wsus_dbshrink.cmd)
$TaskPath = „\WSUS\“ (manuell erstellter Ordner in der Windows-Aufgabenplanung)
$TaskName = „WSUS-Cleanup“ (manuell erstellte Aufgabe)
Alternativ musst Du den WSUS-Cleanup Vorgang im gesamten Skript ausklammern. Die Prio 2 ist eigentlich für das Zurücksetzen entscheidend und kann alleine als Aufgabe ausgeführt werden (oder direkt über wsus_cleanup.ps1 im Code hinterlegen).
Die anderen Prios können auch manuell im Nachgang gestartet werden. Aber die Empfehlung ist tatsächlich, eine Aufgabe auf dem WSUS Server anzulegen, dass alle vier Prios entsprechend beinhaltet und abarbeitet.
Ich hoffe, damit ist es nun ein wenig klarer geworden?!
Ansonsten kannst Du mich auch gerne hierzu direkt kontaktieren (E-Mail oder Telefon).
Viele Grüße,
André
Hallo André,
danke, dass hilft mir schon weiter.
Viele Grüße,
Ines