Module 4 : Maintenance & Dépannage - Garder WSUS en Vie
Objectifs du module
- 🌱 Comprendre le cycle de vie des mises à jour (supersedence)
- 🧹 Maîtriser le Cleanup Wizard via PowerShell
- 🔧 Optimiser la base de données WSUS (re-indexing)
- 🚨 Diagnostiquer les problèmes clients (logs, agent reset)
- 📅 Automatiser la maintenance mensuelle
- ✅ Créer un script de health check complet
📘 Concept : Cycle de Vie des Mises à Jour
🌱 A WSUS server is like a garden; without weeding, it becomes a jungle
Scénario réel (Infrastructure de 500 serveurs) :
Mois 1 : WSUS synchronise 1200 KB. Base de données WID : 15 GB. Console s'ouvre en 5 secondes.
Mois 6 : WSUS a synchronisé 7200 KB cumulées. Base WID : 45 GB. Console s'ouvre en 30 secondes.
Mois 12 : 14 400 KB cumulées. Base WID : 80 GB. Console plante (timeout 60s). Les clients ne peuvent plus contacter WSUS.
Cause : 80% des KB sont superseded (obsolètes), mais jamais nettoyées. La base est devenue un cimetière de KB.
La leçon : La maintenance WSUS est obligatoire, pas optionnelle.
🔄 Supersedence : Le remplacement des mises à jour
Principe : Microsoft publie des KB cumulatives qui remplacent les anciennes.
flowchart LR
KB1[KB5034120<br/>Janvier 2025<br/>Security Update<br/>87 MB]
KB2[KB5035200<br/>Février 2025<br/>Cumulative Update<br/>523 MB<br/>Inclut KB5034120]
KB3[KB5036500<br/>Mars 2025<br/>Cumulative Update<br/>530 MB<br/>Inclut KB5035200]
KB1 -->|superseded by| KB2
KB2 -->|superseded by| KB3
style KB1 fill:#999,color:#fff,stroke-dasharray: 5 5
style KB2 fill:#FF9800800800,color:#000,stroke-dasharray: 5 5
style KB3 fill:#4CAF50,color:#fff
Définitions :
| Terme | Description | Exemple |
|---|---|---|
| Superseded | KB remplacée par une version plus récente | KB5034120 (jan) → Superseded par KB5035200 (fév) |
| Superseding | KB qui remplace une ancienne | KB5035200 supersedes KB5034120 |
| Cumulative | KB qui contient toutes les corrections précédentes | KB5036500 (mars) contient jan + fév + mars |
💡 Pourquoi les KB superseded restent dans WSUS ?
Par défaut, WSUS conserve les anciennes KB pour permettre le rollback en cas de régression. Mais après 3-6 mois, elles deviennent inutiles :
- ❌ Espace disque gaspillé : 10 KB superseded × 50 MB = 500 MB inutiles
- ❌ Base de données gonflée : Métadonnées de 10 000+ KB obsolètes
- ❌ Performance dégradée : Requêtes SQL lentes (scan de millions de lignes)
- ❌ Sync lente : WSUS doit traiter les métadonnées de toutes les KB
Solution : Nettoyer régulièrement avec le Cleanup Wizard.
⚠️ Symptômes d'un WSUS malade
| Symptôme | Cause probable | Solution |
|---|---|---|
| Console lente (>30s au démarrage) | Base de données fragmentée, trop de KB | Cleanup + Re-indexing |
| Clients en timeout (erreur 0x8024401C) | Base WID saturée (CPU 100%) | Cleanup + Migration SQL |
| Sync échoue (erreur 0x80244022) | Espace disque insuffisant | Cleanup + Étendre volume |
| Disk full (D:\WSUS à 100%) | Binaires superseded non supprimés | Cleanup (UnneededContentFiles) |
| Clients non visibles dans la console | SelfUpdate pas appliqué | Approuver "Windows Server Update Services" |
| KB approved mais pas installées | Clients mal ciblés (mauvais groupe) | Vérifier GPO Client-Side Targeting |
💻 Pratique : Maintenance Serveur
🧹 Cleanup Wizard (PowerShell)
Le Cleanup Wizard est l'outil principal pour nettoyer WSUS. Accessible via GUI ou PowerShell.
Commande de base
# Récupérer le serveur WSUS
$WSUSServer = Get-WsusServer
# Lancer le cleanup (toutes les options)
Invoke-WsusServerCleanup -CleanupObsoleteComputers `
-CleanupObsoleteUpdates `
-CleanupUnneededContentFiles `
-CompressUpdates `
-DeclineExpiredUpdates `
-DeclineSupersededUpdates
Options disponibles :
| Option | Description | Impact | Durée |
|---|---|---|---|
| DeclineSupersededUpdates | Refuse les KB remplacées (superseded) | ⚠️ Moyen | ~10 min |
| DeclineExpiredUpdates | Refuse les KB expirées par Microsoft | ✅ Faible | ~2 min |
| CleanupObsoleteUpdates | Supprime les métadonnées des KB refusées | ✅ Moyen | ~5 min |
| CleanupObsoleteComputers | Supprime les clients non contactés depuis 30j | ✅ Faible | ~1 min |
| CleanupUnneededContentFiles | Supprime les binaires (.cab, .msu) des KB refusées | ✅ Fort | ~15 min |
| CompressUpdates | Compresse les révisions de KB (n'est plus utilisé) | ✅ Nul | ~1 min |
Option 1 : DeclineSupersededUpdates
Objectif : Refuser automatiquement les KB remplacées.
# Refuser les KB superseded
Invoke-WsusServerCleanup -DeclineSupersededUpdates
# Output attendu :
# Declining superseded updates...
# Declined 1247 superseded updates.
Impact sur le rollback
Une fois une KB superseded refusée, vous ne pouvez plus la désinstaller pour revenir à la version précédente.
Recommandation : Attendre 3 mois avant de refuser les KB superseded (laisser le temps de détecter les régressions).
Exemple :
- Mars 2025 : KB5036500 est publiée et remplace KB5035200 (février)
- Avril-Mai : Période de test (detection de régressions éventuelles)
- Juin 2025 : Exécuter DeclineSupersededUpdates pour refuser KB5035200
Option 2 : CleanupUnneededContentFiles
Objectif : Supprimer les binaires (.cab, .msu) des KB refusées.
# Supprimer les fichiers inutiles
Invoke-WsusServerCleanup -CleanupUnneededContentFiles
# Output attendu :
# Deleting unused update files...
# Deleted 45.7 GB of unused update files.
💡 Gain d'espace typique : - Petit WSUS (<1000 clients) : 10-20 GB - Moyen WSUS (1000-5000 clients) : 50-100 GB - Grand WSUS (>5000 clients) : 200-500 GB
Option 3 : CleanupObsoleteComputers
Objectif : Supprimer les clients qui n'ont pas contacté WSUS depuis 30 jours.
# Supprimer les ordinateurs obsolètes
Invoke-WsusServerCleanup -CleanupObsoleteComputers
# Output attendu :
# Deleting obsolete computers...
# Deleted 23 obsolete computers.
Cas d'usage : - Serveurs décommissionnés mais jamais supprimés de WSUS - VM temporaires (CI/CD) qui contactent WSUS puis sont détruites
Script de cleanup complet
# Cleanup-WSUS.ps1
# Maintenance mensuelle automatisée
#Requires -RunAsAdministrator
Write-Host "`n🧹 WSUS Cleanup - $(Get-Date -Format 'dd/MM/yyyy HH:mm')" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
# Connexion WSUS
$WSUSServer = Get-WsusServer
Write-Host "✅ Connecté à : $($WSUSServer.Name):$($WSUSServer.PortNumber)" -ForegroundColor Green
# Mesurer l'espace disque AVANT
$ContentPath = "D:\WSUS"
$SizeBefore = (Get-ChildItem -Path $ContentPath -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum / 1GB
Write-Host "`n📊 Espace utilisé AVANT : $([math]::Round($SizeBefore, 2)) GB" -ForegroundColor White
# ÉTAPE 1 : Refuser les KB superseded
Write-Host "`n[1/5] Refus des KB superseded..." -ForegroundColor Cyan
$Result1 = Invoke-WsusServerCleanup -DeclineSupersededUpdates
Write-Host "✅ $($Result1.SupersededUpdatesDeclined) KB superseded refusées" -ForegroundColor Green
# ÉTAPE 2 : Refuser les KB expirées
Write-Host "`n[2/5] Refus des KB expirées..." -ForegroundColor Cyan
$Result2 = Invoke-WsusServerCleanup -DeclineExpiredUpdates
Write-Host "✅ $($Result2.ExpiredUpdatesDeclined) KB expirées refusées" -ForegroundColor Green
# ÉTAPE 3 : Nettoyer les métadonnées obsolètes
Write-Host "`n[3/5] Nettoyage des métadonnées..." -ForegroundColor Cyan
$Result3 = Invoke-WsusServerCleanup -CleanupObsoleteUpdates
Write-Host "✅ $($Result3.ObsoleteUpdatesDeleted) métadonnées supprimées" -ForegroundColor Green
# ÉTAPE 4 : Supprimer les binaires inutiles
Write-Host "`n[4/5] Suppression des binaires inutiles..." -ForegroundColor Cyan
$Result4 = Invoke-WsusServerCleanup -CleanupUnneededContentFiles
Write-Host "✅ Binaires supprimés" -ForegroundColor Green
# ÉTAPE 5 : Nettoyer les ordinateurs obsolètes
Write-Host "`n[5/5] Suppression des ordinateurs obsolètes..." -ForegroundColor Cyan
$Result5 = Invoke-WsusServerCleanup -CleanupObsoleteComputers
Write-Host "✅ $($Result5.ObsoleteComputersDeleted) ordinateurs supprimés" -ForegroundColor Green
# Mesurer l'espace disque APRÈS
$SizeAfter = (Get-ChildItem -Path $ContentPath -Recurse -ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum).Sum / 1GB
$Saved = $SizeBefore - $SizeAfter
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "📊 RÉSUMÉ" -ForegroundColor Cyan
Write-Host "========================================`n" -ForegroundColor Cyan
Write-Host "Espace AVANT : $([math]::Round($SizeBefore, 2)) GB" -ForegroundColor White
Write-Host "Espace APRÈS : $([math]::Round($SizeAfter, 2)) GB" -ForegroundColor White
Write-Host "Espace libéré : $([math]::Round($Saved, 2)) GB" -ForegroundColor Green
🗄️ Optimisation de la base de données
WID (Windows Internal Database)
Problème : Après plusieurs mois, la base WID se fragmente, ralentissant les requêtes.
Solution 1 : Re-indexing via WsusUtil.exe
# Réindexer la base WSUS
$WSUSUtil = "C:\Program Files\Update Services\Tools\wsusutil.exe"
Write-Host "🔧 Re-indexing de la base WSUS..." -ForegroundColor Cyan
& $WSUSUtil postinstall /servicing
# Output attendu :
# Post-install has successfully completed.
# Database re-indexing completed.
Durée : 10-60 minutes selon la taille de la base.
Maintenance Window requise
Pendant le re-indexing, WSUS est indisponible. Planifiez cette opération hors heures de production (ex: dimanche 02:00).
Solution 2 : Reset complet (dernier recours)
# ATTENTION : Supprime TOUTES les approbations et configurations !
# À utiliser UNIQUEMENT si la base est corrompue
& $WSUSUtil reset
# Output :
# This will reset the WSUS database. All approvals and settings will be lost.
# Are you sure? (Y/N)
Point de non-retour
wsusutil reset détruit toutes les approbations, groupes, et configurations. Utilisez uniquement si la base est irréparable.
SQL Server
Si vous utilisez SQL Server au lieu de WID :
-- Re-indexer toutes les tables WSUS
USE SUSDB;
GO
EXEC sp_MSforeachtable @command1="DBCC DBREINDEX('?')";
GO
-- Mettre à jour les statistiques
EXEC sp_updatestats;
GO
Fréquence recommandée : 1×/mois pour WID, 1×/trimestre pour SQL Server.
🚨 Pratique : Dépannage Client
🔍 Diagnostiquer les problèmes clients
Scénario 1 : Le client ne contacte pas WSUS
Symptômes :
- Le serveur n'apparaît pas dans la console WSUS
- Event Log : 0x8024401C (Cannot connect to server)
Diagnostic :
# Vérifier la configuration WSUS (clés de registre GPO)
Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate" |
Select-Object WUServer, WUStatusServer, TargetGroup
# Vérifier la connectivité réseau
Test-NetConnection -ComputerName wsus.corp.local -Port 8530
# Forcer la détection
wuauclt /detectnow
# Consulter les Event Logs
Get-WinEvent -LogName System -MaxEvents 20 |
Where-Object {$_.ProviderName -eq "Microsoft-Windows-WindowsUpdateClient"}
Solutions :
1. ✅ Vérifier que la GPO est bien appliquée (gpresult /h gpresult.html)
2. ✅ Vérifier le DNS (résolution de wsus.corp.local)
3. ✅ Vérifier le firewall (port 8530 ouvert)
Scénario 2 : Les KB sont détectées mais pas installées
Symptômes : - WSUS affiche "Needed: 5 updates" - Mais le client ne les installe pas
Diagnostic :
# Vérifier les updates en attente
Get-WindowsUpdate
# Vérifier le mode d'installation (doit être 4 = Auto)
Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU" |
Select-Object AUOptions, ScheduledInstallDay, ScheduledInstallTime
# Forcer l'installation manuelle (test)
Install-WindowsUpdate -AcceptAll -AutoReboot
Solutions :
1. ✅ Vérifier AUOptions = 4 (Auto download and schedule)
2. ✅ Vérifier que la fenêtre de maintenance est correcte (ex: dimanche 03:00)
3. ✅ Forcer l'installation avec wuauclt /install
☢️ The "Nuclear Option" : Reset du client Windows Update
Quand l'utiliser : - Le client est complètement bloqué (erreur 0x80070002, 0x80244019) - Les logs montrent une corruption du cache - Toutes les autres solutions ont échoué
Procédure :
# Reset-WindowsUpdateAgent.ps1
# ATTENTION : Supprime tout l'historique local des updates !
#Requires -RunAsAdministrator
Write-Host "☢️ RESET Windows Update Agent - OPÉRATION DESTRUCTIVE" -ForegroundColor Red
Write-Host "Ceci va supprimer tout le cache et l'historique local.`n" -ForegroundColor Yellow
$Confirm = Read-Host "Êtes-vous sûr ? (O/N)"
if ($Confirm -ne "O") {
Write-Host "Opération annulée." -ForegroundColor Gray
exit 0
}
# ÉTAPE 1 : Arrêter les services Windows Update
Write-Host "`n[1/5] Arrêt des services..." -ForegroundColor Cyan
Stop-Service -Name wuauserv -Force
Stop-Service -Name cryptSvc -Force
Stop-Service -Name bits -Force
Stop-Service -Name msiserver -Force
Write-Host "✅ Services arrêtés" -ForegroundColor Green
# ÉTAPE 2 : Renommer le dossier SoftwareDistribution
Write-Host "`n[2/5] Renommage du cache..." -ForegroundColor Cyan
$OldPath = "C:\Windows\SoftwareDistribution"
$NewPath = "C:\Windows\SoftwareDistribution.old"
if (Test-Path $NewPath) {
Remove-Item -Path $NewPath -Recurse -Force
}
Rename-Item -Path $OldPath -NewName "SoftwareDistribution.old"
Write-Host "✅ Cache renommé : $NewPath" -ForegroundColor Green
# ÉTAPE 3 : Renommer le dossier Catroot2 (Catalogue de signatures)
Write-Host "`n[3/5] Renommage du catalogue..." -ForegroundColor Cyan
$OldCatroot = "C:\Windows\System32\catroot2"
$NewCatroot = "C:\Windows\System32\catroot2.old"
if (Test-Path $NewCatroot) {
Remove-Item -Path $NewCatroot -Recurse -Force
}
Rename-Item -Path $OldCatroot -NewName "catroot2.old"
Write-Host "✅ Catalogue renommé : $NewCatroot" -ForegroundColor Green
# ÉTAPE 4 : Redémarrer les services
Write-Host "`n[4/5] Redémarrage des services..." -ForegroundColor Cyan
Start-Service -Name wuauserv
Start-Service -Name cryptSvc
Start-Service -Name bits
Start-Service -Name msiserver
Write-Host "✅ Services redémarrés" -ForegroundColor Green
# ÉTAPE 5 : Forcer la détection WSUS
Write-Host "`n[5/5] Détection WSUS..." -ForegroundColor Cyan
wuauclt /resetauthorization /detectnow
Write-Host "`n✅ Reset terminé !" -ForegroundColor Green
Write-Host "`nAttendez 10-15 minutes puis vérifiez :" -ForegroundColor White
Write-Host " • Console WSUS : Le serveur doit réapparaître" -ForegroundColor Gray
Write-Host " • Event Viewer : System > Windows Update Client`n" -ForegroundColor Gray
⚠️ Effets secondaires : - Tout l'historique local des updates est perdu - Le client doit re-télécharger les métadonnées depuis WSUS (~100 MB) - Le reporting WSUS sera vide pendant 24h (temps de re-synchronisation)
📄 Analyser les logs Windows Update
Méthode 1 : Get-WindowsUpdateLog (Windows 10+)
# Décoder les logs ETL en fichier texte
Get-WindowsUpdateLog -LogPath "C:\Temp\WindowsUpdate.log"
# Output :
# Successfully created C:\Temp\WindowsUpdate.log
# Analyser le fichier
Get-Content "C:\Temp\WindowsUpdate.log" | Select-String -Pattern "Error|Failed"
# Exemples d'erreurs courantes :
# 0x8024401C : Cannot connect to WSUS server (réseau/firewall)
# 0x80244019 : WSUS server URL incorrect (GPO mal configurée)
# 0x80070002 : File not found (corruption cache, nécessite reset)
Méthode 2 : Event Viewer
# Lister les 20 derniers événements Windows Update
Get-WinEvent -LogName System -MaxEvents 20 |
Where-Object {$_.ProviderName -eq "Microsoft-Windows-WindowsUpdateClient"} |
Select-Object TimeCreated, Id, Message |
Format-Table -AutoSize
# Event IDs importants :
# 19 : Installation started
# 20 : Installation succeeded
# 25 : Installation failed
# 44 : Connected to WSUS server
🎓 Exercice : "Le Script de Maintenance"
📋 Contexte
Votre WSUS gère 500 serveurs depuis 18 mois sans aucune maintenance. La base WID fait 120 GB et la console met 2 minutes à s'ouvrir.
Votre mission : Créer un script de maintenance mensuel automatisé.
Contraintes :
- Exécution le 1er dimanche du mois à 02:00 (via Scheduled Task)
- Génération d'un rapport avec statistiques (espace libéré, KB refusées, etc.)
- Envoi du rapport par email à l'équipe IT
- Logging dans un fichier C:\Scripts\Logs\WSUS-Maintenance-YYYY-MM.log
🎯 Objectifs
Créez un script Maintain-WSUS.ps1 qui :
- ✅ Se connecte au serveur WSUS
- ✅ Mesure l'espace disque AVANT cleanup
- ✅ Refuse les KB superseded (> 3 mois)
- ✅ Refuse les KB expirées
- ✅ Nettoie les métadonnées obsolètes
- ✅ Supprime les binaires inutiles
- ✅ Supprime les ordinateurs obsolètes (non contactés depuis 60 jours)
- ✅ Mesure l'espace disque APRÈS cleanup
- ✅ Génère un rapport HTML avec statistiques
- ✅ Sauvegarde le rapport dans
C:\Scripts\Reports\ - ✅ (Optionnel) Envoie le rapport par email via
Send-MailMessage
📝 Travail à réaliser
# Maintain-WSUS.ps1
# Auteur : Votre nom
# Date : 22/11/2025
# Description : Maintenance mensuelle automatisée de WSUS
#Requires -RunAsAdministrator
# TODO 1 : Configuration (chemins, email, etc.)
# TODO 2 : Fonction de logging (Write-Log)
# TODO 3 : Connexion WSUS + mesure espace AVANT
# TODO 4 : Refus KB superseded (publiées > 90 jours)
# TODO 5 : Cleanup Wizard (5 étapes)
# TODO 6 : Mesure espace APRÈS
# TODO 7 : Génération rapport HTML
# TODO 8 : Sauvegarde rapport
# TODO 9 : (Optionnel) Envoi email
✅ Critères de validation
| Critère | Vérification |
|---|---|
| Cleanup exécuté | Base WSUS réduite de 30-50% |
| Rapport HTML généré | Fichier présent dans C:\Scripts\Reports\ |
| Logging fonctionnel | Fichier log créé avec timestamp |
| Gestion d'erreurs | Script ne plante pas si WSUS inaccessible |
| Idempotence | Peut être exécuté plusieurs fois sans erreur |
💡 Solution complète
Cliquez pour révéler la solution
```powershell
Maintain-WSUS.ps1
Maintenance mensuelle automatisée de WSUS
Auteur : ShellBook Training
Date : 22/11/2025
Requires -RunAsAdministrator
============================================
CONFIGURATION
============================================
$ContentPath = "D:\WSUS" $LogPath = "C:\Scripts\Logs" $ReportPath = "C:\Scripts\Reports" $LogFile = Join-Path $LogPath "WSUS-Maintenance-$(Get-Date -Format 'yyyy-MM').log" $ReportFile = Join-Path $ReportPath "WSUS-Maintenance-$(Get-Date -Format 'yyyy-MM-dd').html"
Email (optionnel)
$SendEmail = $false # Mettre à $true pour activer l'envoi $SmtpServer = "smtp.corp.local" $EmailFrom = "wsus@corp.local" $EmailTo = "it-team@corp.local"
============================================
FONCTION DE LOGGING
============================================
function Write-Log { param( [string]$Message, [string]$Level = "INFO" )
$Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$LogMessage = "[$Timestamp] [$Level] $Message"
# Créer le répertoire de logs si nécessaire
if (-not (Test-Path $LogPath)) {
New-Item -Path $LogPath -ItemType Directory -Force | Out-Null
}
# Écrire dans le fichier
Add-Content -Path $LogFile -Value $LogMessage
# Afficher dans la console avec couleur
$Color = switch ($Level) {
"ERROR" { "Red" }
"WARN" { "Yellow" }
"SUCCESS" { "Green" }
default { "White" }
}
Write-Host $LogMessage -ForegroundColor $Color
}
============================================
DÉBUT DU SCRIPT
============================================
Write-Log "========================================" "INFO" Write-Log " WSUS MAINTENANCE - $(Get-Date -Format 'dd/MM/yyyy')" "INFO" Write-Log "========================================" "INFO"
============================================
ÉTAPE 1 : CONNEXION AU SERVEUR WSUS
============================================
Write-Log "Connexion au serveur WSUS..." "INFO"
try { $WSUSServer = Get-WsusServer Write-Log "Connecté à : $($WSUSServer.Name):$($WSUSServer.PortNumber)" "SUCCESS" } catch { Write-Log "ERREUR : Impossible de se connecter à WSUS - $_" "ERROR" exit 1 }
============================================
ÉTAPE 2 : MESURE ESPACE DISQUE AVANT
============================================
Write-Log "Mesure de l'espace disque..." "INFO"
if (Test-Path $ContentPath) { $SizeBefore = (Get-ChildItem -Path $ContentPath -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1GB Write-Log "Espace utilisé AVANT : $([math]::Round($SizeBefore, 2)) GB" "INFO" } else { Write-Log "ATTENTION : Chemin $ContentPath introuvable" "WARN" $SizeBefore = 0 }
============================================
ÉTAPE 3 : STATISTIQUES AVANT CLEANUP
============================================
Write-Log "Collecte des statistiques..." "INFO"
Compter les KB superseded
$SupersededCount = (Get-WsusUpdate -Approval AnyExceptDeclined -Status Any | Where-Object {$_.IsSuperseded -eq $true}).Count Write-Log "KB superseded détectées : $SupersededCount" "INFO"
Compter les ordinateurs
$ComputersCount = ($WSUSServer.GetComputerTargets()).Count Write-Log "Ordinateurs enregistrés : $ComputersCount" "INFO"
============================================
ÉTAPE 4 : CLEANUP - SUPERSEDED UPDATES
============================================
Write-Log "Refus des KB superseded..." "INFO"
try { $Result1 = Invoke-WsusServerCleanup -DeclineSupersededUpdates Write-Log "KB superseded refusées : $($Result1.SupersededUpdatesDeclined)" "SUCCESS" } catch { Write-Log "ERREUR lors du refus des KB superseded : $_" "ERROR" $Result1 = @{SupersededUpdatesDeclined = 0} }
============================================
ÉTAPE 5 : CLEANUP - EXPIRED UPDATES
============================================
Write-Log "Refus des KB expirées..." "INFO"
try { $Result2 = Invoke-WsusServerCleanup -DeclineExpiredUpdates Write-Log "KB expirées refusées : $($Result2.ExpiredUpdatesDeclined)" "SUCCESS" } catch { Write-Log "ERREUR lors du refus des KB expirées : $_" "ERROR" $Result2 = @{ExpiredUpdatesDeclined = 0} }
============================================
ÉTAPE 6 : CLEANUP - OBSOLETE UPDATES
============================================
Write-Log "Nettoyage des métadonnées obsolètes..." "INFO"
try { $Result3 = Invoke-WsusServerCleanup -CleanupObsoleteUpdates Write-Log "Métadonnées supprimées : $($Result3.ObsoleteUpdatesDeleted)" "SUCCESS" } catch { Write-Log "ERREUR lors du nettoyage des métadonnées : $_" "ERROR" $Result3 = @{ObsoleteUpdatesDeleted = 0} }
============================================
ÉTAPE 7 : CLEANUP - UNNEEDED CONTENT FILES
============================================
Write-Log "Suppression des binaires inutiles..." "INFO"
try { $Result4 = Invoke-WsusServerCleanup -CleanupUnneededContentFiles Write-Log "Binaires supprimés avec succès" "SUCCESS" } catch { Write-Log "ERREUR lors de la suppression des binaires : $_" "ERROR" }
============================================
ÉTAPE 8 : CLEANUP - OBSOLETE COMPUTERS
============================================
Write-Log "Suppression des ordinateurs obsolètes (>60 jours)..." "INFO"
try { $Result5 = Invoke-WsusServerCleanup -CleanupObsoleteComputers Write-Log "Ordinateurs supprimés : $($Result5.ObsoleteComputersDeleted)" "SUCCESS" } catch { Write-Log "ERREUR lors de la suppression des ordinateurs : $_" "ERROR" $Result5 = @{ObsoleteComputersDeleted = 0} }
============================================
ÉTAPE 9 : MESURE ESPACE DISQUE APRÈS
============================================
Write-Log "Mesure de l'espace disque après cleanup..." "INFO"
if (Test-Path $ContentPath) { $SizeAfter = (Get-ChildItem -Path $ContentPath -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1GB $Saved = $SizeBefore - $SizeAfter Write-Log "Espace utilisé APRÈS : $([math]::Round($SizeAfter, 2)) GB" "INFO" Write-Log "Espace libéré : $([math]::Round($Saved, 2)) GB" "SUCCESS" } else { $SizeAfter = 0 $Saved = 0 }
============================================
ÉTAPE 10 : GÉNÉRATION RAPPORT HTML
============================================
Write-Log "Génération du rapport HTML..." "INFO"
Créer le répertoire de rapports si nécessaire
if (-not (Test-Path $ReportPath)) { New-Item -Path $ReportPath -ItemType Directory -Force | Out-Null }
$HtmlReport = @" <!DOCTYPE html>
WSUS Maintenance Report
Date d'exécution : $(Get-Date -Format 'dd/MM/yyyy HHss')
Serveur WSUS : $($WSUSServer.Name):$($WSUSServer.PortNumber)
<h2>Résumé Espace Disque</h2>
<table>
<tr><th>Métrique</th><th>Valeur</th></tr>
<tr><td>Espace AVANT cleanup</td><td>$([math]::Round($SizeBefore, 2)) GB</td></tr>
<tr><td>Espace APRÈS cleanup</td><td>$([math]::Round($SizeAfter, 2)) GB</td></tr>
<tr><td class="success">Espace libéré</td><td class="success">$([math]::Round($Saved, 2)) GB</td></tr>
</table>
<h2>Statistiques de Nettoyage</h2>
<table>
<tr><th>Opération</th><th>Résultat</th></tr>
<tr><td>KB superseded refusées</td><td>$($Result1.SupersededUpdatesDeclined)</td></tr>
<tr><td>KB expirées refusées</td><td>$($Result2.ExpiredUpdatesDeclined)</td></tr>
<tr><td>Métadonnées supprimées</td><td>$($Result3.ObsoleteUpdatesDeleted)</td></tr>
<tr><td>Ordinateurs supprimés</td><td>$($Result5.ObsoleteComputersDeleted)</td></tr>
</table>
<h2>État Serveur</h2>
<table>
<tr><th>Métrique</th><th>Valeur</th></tr>
<tr><td>KB superseded restantes</td><td>$SupersededCount</td></tr>
<tr><td>Ordinateurs enregistrés</td><td>$ComputersCount</td></tr>
</table>
<h2>Recommandations</h2>
<ul>
"@
# Ajouter des recommandations basées sur les résultats
if ($Saved -lt 5) {
$HtmlReport += "<li class='warning'>Peu d'espace libéré (< 5 GB). Vérifier la fréquence de maintenance.</li>"
}
if ($SupersededCount -gt 500) {
$HtmlReport += "<li class='warning'>$SupersededCount KB superseded restantes. Envisager un cleanup plus agressif.</li>"
}
if ($SizeAfter -gt 100) {
$HtmlReport += "<li class='warning'>Base WSUS volumineuse ($([math]::Round($SizeAfter, 2)) GB). Envisager migration vers SQL Server.</li>"
}
$HtmlReport += @"
</ul>
<hr>
<p><small>Rapport généré automatiquement par Maintain-WSUS.ps1</small></p>
</body>
</html>
"@
# Sauvegarder le rapport
$HtmlReport | Out-File -FilePath $ReportFile -Encoding UTF8
Write-Log "Rapport sauvegardé : $ReportFile" "SUCCESS"
# ============================================
# ÉTAPE 11 : ENVOI EMAIL (OPTIONNEL)
# ============================================
if ($SendEmail) {
Write-Log "Envoi du rapport par email..." "INFO"
try {
Send-MailMessage -From $EmailFrom `
-To $EmailTo `
-Subject "WSUS Maintenance Report - $(Get-Date -Format 'dd/MM/yyyy')" `
-Body "Veuillez consulter le rapport ci-joint." `
-Attachments $ReportFile `
-SmtpServer $SmtpServer
Write-Log "Email envoyé à : $EmailTo" "SUCCESS"
} catch {
Write-Log "ERREUR lors de l'envoi de l'email : $_" "ERROR"
}
}
# ============================================
# FIN DU SCRIPT
# ============================================
Write-Log "========================================" "INFO"
Write-Log "Maintenance terminée avec succès !" "SUCCESS"
Write-Log "========================================" "INFO"
# Afficher le chemin du rapport
Write-Host "`n📄 Rapport disponible : $ReportFile" -ForegroundColor Cyan
Write-Host "📄 Log disponible : $LogFile`n" -ForegroundColor Cyan
```
**Configuration de la tâche planifiée** :
```powershell
# Créer la tâche planifiée (1er dimanche du mois à 02:00)
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-ExecutionPolicy Bypass -File C:\Scripts\Maintain-WSUS.ps1"
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 02:00 -WeeksInterval 4
$Principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "WSUS Monthly Maintenance" `
-Action $Action `
-Trigger $Trigger `
-Principal $Principal `
-Description "Maintenance mensuelle automatisée de WSUS (cleanup + rapport)"
```
**Output attendu** :
```text
[2025-11-22 02:00:15] [INFO] ========================================
[2025-11-22 02:00:15] [INFO] WSUS MAINTENANCE - 22/11/2025
[2025-11-22 02:00:15] [INFO] ========================================
[2025-11-22 02:00:16] [INFO] Connexion au serveur WSUS...
[2025-11-22 02:00:17] [SUCCESS] Connecté à : WSUS.corp.local:8530
[2025-11-22 02:00:17] [INFO] Mesure de l'espace disque...
[2025-11-22 02:00:22] [INFO] Espace utilisé AVANT : 87.34 GB
[2025-11-22 02:00:22] [INFO] Collecte des statistiques...
[2025-11-22 02:00:45] [INFO] KB superseded détectées : 1247
[2025-11-22 02:00:46] [INFO] Ordinateurs enregistrés : 523
[2025-11-22 02:00:46] [INFO] Refus des KB superseded...
[2025-11-22 02:12:34] [SUCCESS] KB superseded refusées : 1247
[2025-11-22 02:12:34] [INFO] Refus des KB expirées...
[2025-11-22 02:14:12] [SUCCESS] KB expirées refusées : 34
[2025-11-22 02:14:12] [INFO] Nettoyage des métadonnées obsolètes...
[2025-11-22 02:18:56] [SUCCESS] Métadonnées supprimées : 1281
[2025-11-22 02:18:56] [INFO] Suppression des binaires inutiles...
[2025-11-22 02:45:23] [SUCCESS] Binaires supprimés avec succès
[2025-11-22 02:45:23] [INFO] Suppression des ordinateurs obsolètes (>60 jours)...
[2025-11-22 02:46:01] [SUCCESS] Ordinateurs supprimés : 12
[2025-11-22 02:46:01] [INFO] Mesure de l'espace disque après cleanup...
[2025-11-22 02:46:15] [INFO] Espace utilisé APRÈS : 42.17 GB
[2025-11-22 02:46:15] [SUCCESS] Espace libéré : 45.17 GB
[2025-11-22 02:46:15] [INFO] Génération du rapport HTML...
[2025-11-22 02:46:16] [SUCCESS] Rapport sauvegardé : C:\Scripts\Reports\WSUS-Maintenance-2025-11-22.html
[2025-11-22 02:46:16] [INFO] ========================================
[2025-11-22 02:46:16] [SUCCESS] Maintenance terminée avec succès !
[2025-11-22 02:46:16] [INFO] ========================================
📄 Rapport disponible : C:\Scripts\Reports\WSUS-Maintenance-2025-11-22.html
📄 Log disponible : C:\Scripts\Logs\WSUS-Maintenance-2025-11.log
```
🎯 Points clés à retenir
Checklist Module 4
- ✅ Maintenance obligatoire : WSUS sans cleanup = performance dégradée en 6-12 mois
- ✅ Supersedence : KB cumulatives remplacent les anciennes (Cumulative Update)
- ✅ Cleanup Wizard : 6 options (DeclineSuperseded, CleanupContent, etc.)
- ✅ Fréquence : 1×/mois minimum pour éviter le bloat
- ✅ Re-indexing :
wsusutil postinstall /servicingpour optimiser la base WID - ✅ Reset client : Dernier recours (rename SoftwareDistribution + catroot2)
- ✅ Logs :
Get-WindowsUpdateLogpour décoder les ETL + Event Viewer - ✅ Automatisation : Scheduled Task mensuelle avec rapport HTML
- ✅ Espace libéré : Attendez-vous à 30-50% de gain après le premier cleanup
🔗 Ressources complémentaires
- Microsoft Learn : WSUS Maintenance
- PowerShell : Invoke-WsusServerCleanup
- Troubleshooting Windows Update
➡️ Prochaine étape
Rendez-vous au Module 5 : TP Final - Infrastructure Multi-Sites pour : - Déployer une architecture WSUS Upstream/Downstream - Configurer un WSUS en mode Replica pour une filiale - Créer une stratégie de déploiement complète (6 groupes, 3 GPO) - Valider avec un script de conformité automatisé
Citation du formateur
"Un WSUS bien entretenu est invisible. Un WSUS mal entretenu devient le sujet de toutes les réunions d'incident." — ShellBook Training
Navigation
| ← Module 3 : Configuration Clients - GP... | Module 5 : TP Final - L'Usine de Mise... → |