Die Windows Server Update Services, kurz WSUS, sollte man von Zeit zu Zeit warten und nicht benötigte Updates entfernen. Das geht zum einen recht gut mit dem “Assistent für die Serverbereinigung”, jedoch muss man auch Hand anlegen und sollte zum Beispiel die Updates entfernen die von anderen ersetzt wurden (Superseded Updates). Und das erkläre ich nachfolgend.
WSUS aufräumen von Superseded Updates oder in deutsch die von anderen Updates ersetzt wurden
Die Frage vorweg – Warum sollte man das machen? Der Grund ist recht einfach um den Speicher auf der Festplatte des WSUS möglichst schlank zu halten und um ggf. Fehler wie “WARNING: Exceeded max server round trips: 0x80244010” auf dem Windowsclient zu vermeiden.
- WSUS Konsole starten
- in die Ansicht Updates -> Alle Updates wechseln
- Genehmigung: “Alle bis auf abgelehnte”
- Status: “Any”
- und auf “Aktualisieren” klicken
WSUS Symbole Ersatz
Da sich nun alles um die Superseded Updates dreht, erkläre ich nachfolgend kurz die Symbole:
Symbol | Erklärung | Ablehnen / Löschen |
Dieses Update ersetzt andere Updates nein !
Dieses Update ersetzt ein Update, wird aber auch von einem anderen ersetzt. Ja
Dieses Update wird von einem anderen Update ersetzt. Ja
- Weiter geht es an dieser Stelle und wir prüfen ob die Updates, die die andere Ersetzen, auch genehmigt wurden und zur Installation freigegeben sind. Dafür schaue ich unter “Zusätzliche Details” nach dem Punkt “Updates, die dieses Update ersetzen:” Dort klicke ich auf das entsprechende Update das dieses ersetzt und schaue mir von diesem Update die “Genehmigungszusammenfassung” an. Dieses sollte also zur Installation genehmigt werden.
- ist dies der Fall können alle Updates die Ersetzt wurden ablehnen
- unter “Optionen” -> auf “Assistent für die Serverbereinigung” klicken
Das Resultat
Damit wurden alle nicht mehr benötigten Windows Updates von der Festplatte gelöscht und Platz geschaffen. Auch wurden alle von Computern für diese Updates gemeldeten Ereignisse aus der Datenbank gelöscht. Dadurch müssen Clients ggf. nicht zu viele Anfragen zur Klärung des Updatestatus an den Server senden und Probleme wie den Roun Trip, werden vermieden. Wird nun ein neuer Client installiert, so wird er immer das neueste Update installieren, es hat ja eh ein altes und nun entferntes ersetzt …
Empfehlung – Automatische Genehmigung
Unter Optionen -> “Automatische Genehmigungen” und dort unter dem Reiter “Erweitert” empfehle ich die Optionen für die “Revisionen für Updates” zu aktivieren:
- Neue Revisionen von bereits genehmigten Updates automatisch genehmigen
- Updates automatisch ablehnen, wenn eine neue Revision deren Ablauf bewirkt
Aufräumen mittels Powershell
Der WSUS lässt sich auch per Powershell verwalten. So kann man mittels einfachem Befehl obiges einfach per Powershell ausführen und z.B. automatisiert in regelmäßigen Abständen durchführen. Nachfolgender Powershellbefehl führt folgendes durch:
- entfernen aller Superseeded Updates
- entfernen aller Expired Updates
- entfernen alte Computer
und los gehts:
- auf dem WSUS anmelden
- Powershell als Administrator öffnen und folgenden Befehl eingeben und ausführen:
Invoke-WsusServerCleanup -DeclineSupersededUpdates -DeclineExpiredUpdates -CleanupObsoleteComputers -CleanupObsoleteUpdates
Diesen Befehl muss man ggf. öfter hintereinander ausführen, da ansonten ein Fehler mit “..Timeout..” erfolgt, der Befehl dann aber an der Stelle wo es aufhörte, weiter macht. In meinem Fall hatte ich nach 9 maligem ausführen die Nase voll und habe diese einfache Powershell While-Schleife laufen lassen. Diese lief dann über Nacht und wurde ca. 320x ausgeführt :uff: Danach wurde mir der Erfolg angezeigt und der WSUS aufgeräumt.
#$wsus = Get-WsusServer -Name localhost -port 8530 #Extra
#$wsus.GetDatabaseConfiguration().CreateConnection() # Extra
while(!($Check))
{
$check = $true
try{
Invoke-WsusServerCleanup -DeclineSupersededUpdates -DeclineExpiredUpdates -CleanupObsoleteComputers -CleanupObsoleteUpdates
}
catch{
$check = $false
Write-Host "Timeout"
}
}
WSUS Datenbank reorganisieren
- Windows Server 2016 mit WSUS in lokaler SQLExpress Datenbank
Von Zeit zu Zeit ist es notwendig die WSUS Datenbank zu reorganisieren und damit die Indexes neuzuerstellen und fragementierte Tabellen aufzuräumen. Hierfür gibt es ein sehr gutes SQL-Script in der Microsoft Technet Gallery: https://gallery.technet.microsoft.com/scriptcenter/Optimize-and-cleanup-of-eb9d8640 das den Job übernimmt. Man kann es sehr gut z.B. monatlich als Task laufen lassen.
Voraussetzung ist die Installation der Tools für SQLCMD, steht aber auch im Artikel.
Das Script ist für Windows Server 2012 R2 und 2016 und sieht wie folgt aktuell aus, wobei ich den Schalter “SET QUOTED_IDENTIFIER ON;” bereits hinzugefügt habe:
/******************************************************************************
This sample T-SQL script performs basic maintenance tasks on SUSDB
1. Identifies indexes that are fragmented and defragments them. For certain
tables, a fill-factor is set in order to improve insert performance.
Based on MSDN sample at http://msdn2.microsoft.com/en-us/library/ms188917.aspx
and tailored for SUSDB requirements
2. Updates potentially out-of-date table statistics.
******************************************************************************/
USE SUSDB;
GO
SET NOCOUNT ON;
SET QUOTED_IDENTIFIER ON;
-- Rebuild or reorganize indexes based on their fragmentation levels
DECLARE @work_to_do TABLE (
objectid int
, indexid int
, pagedensity float
, fragmentation float
, numrows int
)
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @schemaname nvarchar(130);
DECLARE @objectname nvarchar(130);
DECLARE @indexname nvarchar(130);
DECLARE @numrows int
DECLARE @density float;
DECLARE @fragmentation float;
DECLARE @command nvarchar(4000);
DECLARE @fillfactorset bit
DECLARE @numpages int
-- Select indexes that need to be defragmented based on the following
-- * Page density is low
-- * External fragmentation is high in relation to index size
PRINT 'Estimating fragmentation: Begin. ' + convert(nvarchar, getdate(), 121)
INSERT @work_to_do
SELECT
f.object_id
, index_id
, avg_page_space_used_in_percent
, avg_fragmentation_in_percent
, record_count
FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'SAMPLED') AS f
WHERE
(f.avg_page_space_used_in_percent < 85.0 and f.avg_page_space_used_in_percent/100.0 * page_count < page_count - 1)
or (f.page_count > 50 and f.avg_fragmentation_in_percent > 15.0)
or (f.page_count > 10 and f.avg_fragmentation_in_percent > 80.0)
PRINT 'Number of indexes to rebuild: ' + cast(@@ROWCOUNT as nvarchar(20))
PRINT 'Estimating fragmentation: End. ' + convert(nvarchar, getdate(), 121)
SELECT @numpages = sum(ps.used_page_count)
FROM
@work_to_do AS fi
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
-- Declare the cursor for the list of indexes to be processed.
DECLARE curIndexes CURSOR FOR SELECT * FROM @work_to_do
-- Open the cursor.
OPEN curIndexes
-- Loop through the indexes
WHILE (1=1)
BEGIN
FETCH NEXT FROM curIndexes
INTO @objectid, @indexid, @density, @fragmentation, @numrows;
IF @@FETCH_STATUS < 0 BREAK;
SELECT
@objectname = QUOTENAME(o.name)
, @schemaname = QUOTENAME(s.name)
FROM
sys.objects AS o
INNER JOIN sys.schemas as s ON s.schema_id = o.schema_id
WHERE
o.object_id = @objectid;
SELECT
@indexname = QUOTENAME(name)
, @fillfactorset = CASE fill_factor WHEN 0 THEN 0 ELSE 1 END
FROM
sys.indexes
WHERE
object_id = @objectid AND index_id = @indexid;
IF ((@density BETWEEN 75.0 AND 85.0) AND @fillfactorset = 1) OR (@fragmentation < 30.0)
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
ELSE IF @numrows >= 5000 AND @fillfactorset = 0
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD WITH (FILLFACTOR = 90)';
ELSE
SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
PRINT convert(nvarchar, getdate(), 121) + N' Executing: ' + @command;
EXEC (@command);
PRINT convert(nvarchar, getdate(), 121) + N' Done.';
END
-- Close and deallocate the cursor.
CLOSE curIndexes;
DEALLOCATE curIndexes;
IF EXISTS (SELECT * FROM @work_to_do)
BEGIN
PRINT 'Estimated number of pages in fragmented indexes: ' + cast(@numpages as nvarchar(20))
SELECT @numpages = @numpages - sum(ps.used_page_count)
FROM
@work_to_do AS fi
INNER JOIN sys.indexes AS i ON fi.objectid = i.object_id and fi.indexid = i.index_id
INNER JOIN sys.dm_db_partition_stats AS ps on i.object_id = ps.object_id and i.index_id = ps.index_id
PRINT 'Estimated number of pages freed: ' + cast(@numpages as nvarchar(20))
END
GO
--Update all statistics
PRINT 'Updating all statistics.' + convert(nvarchar, getdate(), 121)
EXEC sp_updatestats
PRINT 'Done updating statistics.' + convert(nvarchar, getdate(), 121)
GO
Das Script wird in eine Datei gespeichert z.B. “WsusDBMaintenance.sql”, die dann später im Task aufgerufen wird. Der SQLExpress läuft unter dem “NT Service” und ohne weitere Berechtigungen, sodass ich ihn auch nicht als Administrator in der Befehlszeile ausführen konnte. Daher ein Task mit Output in ein Debug File.
Ich musste den SQLCMD Befehl aus dem obigen Artikel etwas anpassen, da er ansonsten nicht lief. Die wesentlichen Einstellungen des WSUS-Tasks:
Das Programm / Script das ausgeführt wird: # sqlcmd -S np:\.\pipe\MSSQL$SQLEXPRESS\sql\query -i <Pfad zum WsusDBMaintenance .sql Script> -o “<Pfad zur debug.txt>”
Den Task dann noch den eigenen Abläufen entsprechend anpassen und gut ist.
WSUS Datenbank verkleinern
Ein weiterer Schritt den WSUS aufzuräumen und zu optimieren ist die Datenbank zu verkleinern / shrinken. Das geht am besten mit dem MS SQL Management Studio.
Have Fun …
Interessiert in verschiedenste IT Themen, schreibe ich in diesem Blog über Software, Hardware, Smart Home, Games und vieles mehr. Ich berichte z.B. über die Installation und Konfiguration von Software als auch von Problemen mit dieser. News sind ebenso spannend, sodass ich auch über Updates, Releases und Neuigkeiten aus der IT berichte. Letztendlich nutze ich Taste-of-IT als eigene Dokumentation und Anlaufstelle bei wiederkehrenden Themen. Ich hoffe ich kann dich ebenso informieren und bei Problemen eine schnelle Lösung anbieten. Wer meinen Aufwand unterstützen möchte, kann gerne eine Tasse oder Pod Kaffe per PayPal spenden – vielen Dank.