Votre serveur de test n’affiche l’historique Windows Update que depuis juin 2024 ? Voici comment reconstituer 12 mois de preuves exploitables pour l’audit (PowerShell, journaux d’événements, PSWindowsUpdate), et comment pérenniser la collecte.
Contexte : l’historique Windows Update n’affiche que 3 mois
Sur certains serveurs, la page Paramètres › Mise à jour et sécurité › Windows Update › Afficher l’historique des mises à jour ne liste que quelques semaines ou mois de correctifs. Or un audit exige souvent la traçabilité des déploiements sur les douze derniers mois, en prouvant que chaque mise à jour a d’abord été installée sur le serveur de test avant la production.
Bonne nouvelle : même si la vue graphique est « vide », le système conserve plusieurs sources fiables : WMI (Win32_QuickFixEngineering), les journaux d’événements Windows Update, la base de maintenance (DISM), ainsi que les rapports du module PowerShell PSWindowsUpdate. Avec ces sources, vous pouvez produire un dossier de preuves complet, daté et vérifiable.
Pourquoi l’historique disparaît (ou semble tronqué)
La vue « Afficher l’historique des mises à jour » est alimentée par la base DataStore.edb
située dans %windir%\SoftwareDistribution\DataStore
. Lorsqu’un administrateur réinitialise Windows Update (par ex. en renommant SoftwareDistribution
) ou qu’une opération de maintenance majeure est effectuée, cette base peut être régénérée, ce qui efface l’historique visible dans l’interface. Cela n’efface pas pour autant :
- les enregistrements WMI des correctifs (Get‑HotFix / Win32_QuickFixEngineering),
- les événements WindowsUpdateClient dans l’Observateur d’événements,
- les informations de packages système (DISM / Get‑WindowsPackage),
- et, si vous l’utilisez, l’historique consolidé via PSWindowsUpdate.
Résultat : même après une « réinitialisation », il est possible de reconstituer l’historique complet pour l’audit.
Exigence d’audit typique
- Prouver que chaque KB a été déployé sur test avant production.
- Fournir une datation précise (date/heure système) et l’identifiant KB.
- Conserver des exports signés (hash SHA‑256) et des captures de la commande exécutée.
- Idéalement, mettre en place une collecte récurrente vers un partage sécurisé.
Plan d’action rapide (TL;DR)
- Générez tout de suite un CSV avec
Get‑HotFix
(ouGet‑WUHistory
si PSWindowsUpdate est présent) filtré sur 12 mois et signez-le avecGet‑FileHash
. - Complétez par un export des événements WindowsUpdateClient (IDs 19/20/21) en EVTX + un CSV filtré.
- Ajoutez un inventaire DISM (
Get‑WindowsPackage
oudism /online /get-packages
) pour croiser les preuves. - Archivez et horodatez le tout (ZIP + SHA‑256), puis déployez une tâche planifiée pour automatiser à l’avenir.
Réponses & solutions proposées
Piste | Commande / action | Ce que cela apporte | Preuve / export |
---|---|---|---|
Lister les correctifs via PowerShell | Get-HotFix | Select HotFixID, InstalledOn | Sort-Object InstalledOn (ou wmic qfe list si disponible) | Affiche tous les KB installés et leur date, même s’ils n’apparaissent plus dans l’interface Windows Update. | Export CSV (... | Export-Csv chemin.csv -NoTypeInformation ) à signer par Get-FileHash . |
Vue « Mises à jour installées » (Panneau de config.) | Chemin : Panneau de configuration › Programmes › Programmes et fonctionnalités › Afficher les mises à jour installées | Liste gérée par Windows Installer/Servicing, généralement sans limite à 3 mois ; utile pour recouper. | Captures d’écran, export texte via wmic / DISM pour formaliser. |
Journaux d’événements | Observateur › Journaux des applications et services › Microsoft › Windows › WindowsUpdateClient › Operational | Les événements 19/20/21 tracent succès/échec/report d’installation (et 18 signale le début). | Export EVTX (wevtutil epl ... ) + CSV filtré (Get-WinEvent ). |
Module PSWindowsUpdate | Install-Module PSWindowsUpdate puis Get-WUHistory | Historique détaillé, y compris pilotes ; idéal pour des rapports synthétiques par machine. | CSV (... | Export-Csv ) + hash SHA‑256. |
Packages système (DISM) | Get-WindowsPackage -Online ou dism /online /get-packages /format:table | Preuve complémentaire : date d’installation des packages (LCU/SSU, FOD, .NET) au niveau du servicing. | TXT/CSV + hash. |
Sauvegarder DataStore.edb | Copie de %windir%\SoftwareDistribution\DataStore\DataStore.edb avant nettoyage | Évite la perte d’historique visible lors d’une réinitialisation de Windows Update. | Copie horodatée sur partage sécurisé (option : VSS). |
Pas‑à‑pas : produire des preuves pour les 12 derniers mois
1) Liste des KB via Get‑HotFix
Exécutez PowerShell en administrateur :
$server = $env:COMPUTERNAME
$since = (Get-Date).AddMonths(-12)
Get-HotFix |
Where-Object { $_.InstalledOn -ge $since } |
Sort-Object InstalledOn |
Select-Object @{n='Serveur';e={$server}}, HotFixID, InstalledOn, Description, PSComputerName |
Export-Csv "C:\Audit\WU$($server)*HotFix*$((Get-Date).ToString('yyyyMMdd-HHmmss')).csv" -NoTypeInformation
# Calculez le hash pour signature
Get-FileHash "C:\Audit\WU*.csv" -Algorithm SHA256 | Format-Table
Remarques :
Get‑HotFix
s’appuie sur WMI (Win32_QuickFixEngineering) et couvre la majorité des KB ; certains composants (FOD, langues) se recoupent mieux via DISM.- Sur un hôte distant, utilisez :
Invoke‑Command -ComputerName MonServeurTest -ScriptBlock { Get‑HotFix ... }
ou-CimSession
. - wmic qfe est obsolète sur les versions récentes, mais reste un secours si disponible.
2) Historique détaillé via PSWindowsUpdate
Si le module est autorisé dans votre référentiel d’entreprise :
# Installation (à privilégier via un repository interne)
Install-Module -Name PSWindowsUpdate -Scope AllUsers -Force
# Historique des 12 derniers mois
$since = (Get-Date).AddMonths(-12)
Get-WUHistory |
Where-Object { $_.Date -ge $since } |
Sort-Object Date |
Select-Object ComputerName, Date, KB, Title, Result |
Export-Csv "C:\Audit\WU$env:COMPUTERNAME`*WUHistory*$((Get-Date).ToString('yyyyMMdd-HHmmss')).csv" -NoTypeInformation
Get-FileHash "C:\Audit\WU**WUHistory**.csv" -Algorithm SHA256
Astuce : Get‑WUHistory
recense aussi les pilotes et fournit des intitulés lisibles, parfaits pour un rapport destiné aux auditeurs.
3) Événements Windows Update (preuves de process)
Interrogez le journal WindowsUpdateClient/Operational pour obtenir la chronologie d’installation :
$since = (Get-Date).AddMonths(-12)
$log = 'Microsoft-Windows-WindowsUpdateClient/Operational'
# IDs clés : 18 (début), 19 (succès), 20 (échec), 21 (report/annulation selon cas)
Get-WinEvent -FilterHashtable @{ LogName=$log; StartTime=$since; Id=18,19,20,21 } |
Select-Object TimeCreated, Id, LevelDisplayName, ProviderName, Message |
Export-Csv "C:\Audit\WU$env:COMPUTERNAME`*WUEvents*$((Get-Date).ToString('yyyyMMdd-HHmmss')).csv" -NoTypeInformation
# Export binaire EVTX (journal complet) pour archive officielle
wevtutil epl "$log" "C:\Audit\WU$env:COMPUTERNAME`*WU_Operational*$((Get-Date).ToString('yyyyMMdd-HHmmss')).evtx"
ID | Catégorie | Interprétation (résumé) | Utilisation en audit |
---|---|---|---|
18 | Installation | Début de l’installation d’une mise à jour. | Montre le déclenchement sur le serveur de test. |
19 | Installation | Installation réussie de la mise à jour (KB). Message explicite. | Preuve principale de réussite (avec date/heure). |
20 | Installation | Échec d’installation avec code d’erreur. | Explique les retards ou retentatives. |
21 | Installation | Annulation/report selon le contexte. | Justifie un décalage vis‑à‑vis de la production. |
4) Packages installés (DISM / Servicing)
Le moteur de maintenance Windows (servicing) conserve la date d’installation des packages (LCU, SSU, .NET, FOD…). C’est une source robuste pour les audits.
# PowerShell (module DISM)
Get-WindowsPackage -Online |
Where-Object { $_.InstallTime -and ($_.InstallTime -ge (Get-Date).AddMonths(-12)) } |
Select-Object InstallTime, PackageName, ReleaseType, PackageState |
Sort-Object InstallTime |
Export-Csv "C:\Audit\WU\$env:COMPUTERNAME`_WindowsPackages_$((Get-Date).ToString('yyyyMMdd-HHmmss')).csv" -NoTypeInformation
# Alternative en console
dism /online /get-packages /format:table > "C:\Audit\WU%COMPUTERNAME%*dism_packages*%date:~-4%%date:~3,2%%date:~0,2%.txt"
Astuce : les LCU apparaissent souvent sous forme de Package_for_RollupFix
avec une date d’installation, que vous pouvez recouper avec l’ID KB listé par Get‑HotFix
et les événements 18/19/20.
5) Vue « Mises à jour installées » (Panneau de configuration)
Ouvrez : Panneau de configuration › Programmes › Programmes et fonctionnalités › Afficher les mises à jour installées. Cette vue est utile pour corroborer les KB et opérer des captures d’écran « lisibles » pour les auditeurs. Lorsque possible, complétez par un export CSV (Get‑HotFix) pour éviter toute discussion.
6) Sauvegarder DataStore.edb
avant un nettoyage
Pour ne plus perdre l’historique visible :
# Arrêtez les services Windows Update/BITS le temps de la copie
net stop wuauserv
net stop bits
# Sauvegarde horodatée
$dst = "D:\Sauvegardes\WU$env:COMPUTERNAME"+"_" + (Get-Date).ToString('yyyyMMdd-HHmmss')
New-Item -ItemType Directory -Path $dst -Force | Out-Null
Copy-Item "$env:windir\SoftwareDistribution\DataStore\DataStore.edb" "$dst" -Force
# Redémarrez les services
net start bits
net start wuauserv
Option avancée : utilisez une sauvegarde via cliché instantané (VSS) si vous ne pouvez pas interrompre temporairement le service.
Dossier d’audit : un exemple concret et réplicable
Composez un dossier par période (mensuel ou trimestriel) contenant :
- 01_HotFix.csv (via Get‑HotFix),
- 02_WUHistory.csv (si disponible),
- 03_WUEvents.evtx + 03_WUEvents.csv (IDs 18/19/20/21),
- 04_WindowsPackages.csv (DISM),
- 05_Hash.txt (résultats Get‑FileHash),
- 06_Commandes.txt (copie des commandes exécutées),
- 07_Captures (éventuelles captures d’écran).
Ensuite, archivez dans un ZIP, signe(z) et dépose(z) sur un partage en écriture restreinte.
Script d’export prêt à l’emploi
# > Export_WU_Evidence.ps1
param(
[string]$ShareRoot = '\\MonNAS\Audit\WU'
)
$server = $env:COMPUTERNAME
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$root = Join-Path $ShareRoot "$server`_$stamp"
New-Item -ItemType Directory -Path $root -Force | Out-Null
$since = (Get-Date).AddMonths(-12)
$log = 'Microsoft-Windows-WindowsUpdateClient/Operational'
# 1) HotFix
Get-HotFix |
Where-Object { $_.InstalledOn -ge $since } |
Sort-Object InstalledOn |
Select-Object @{n='Serveur';e={$server}}, HotFixID, InstalledOn, Description |
Export-Csv (Join-Path $root '01_HotFix.csv') -NoTypeInformation
# 2) PSWindowsUpdate (si présent)
if (Get-Module -ListAvailable -Name PSWindowsUpdate) {
Get-WUHistory |
Where-Object { $_.Date -ge $since } |
Sort-Object Date |
Select-Object ComputerName, Date, KB, Title, Result |
Export-Csv (Join-Path $root '02_WUHistory.csv') -NoTypeInformation
}
# 3a) Événements - CSV filtré
Get-WinEvent -FilterHashtable @{ LogName=$log; StartTime=$since; Id=18,19,20,21 } |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Export-Csv (Join-Path $root '03_WUEvents.csv') -NoTypeInformation
# 3b) Événements - EVTX complet
wevtutil epl "$log" (Join-Path $root '03_WUEvents.evtx')
# 4) Packages (DISM PowerShell)
if (Get-Command Get-WindowsPackage -ErrorAction SilentlyContinue) {
Get-WindowsPackage -Online |
Where-Object { $*.InstallTime -and ($*.InstallTime -ge $since) } |
Select-Object InstallTime, PackageName, ReleaseType, PackageState |
Sort-Object InstallTime |
Export-Csv (Join-Path $root '04_WindowsPackages.csv') -NoTypeInformation
} else {
dism /online /get-packages /format:table | Out-File (Join-Path $root '04_WindowsPackages.txt') -Encoding UTF8
}
# 5) Commandes exécutées (traçabilité)
@'
COMMANDES :
Get-HotFix | Where-Object { $_.InstalledOn -ge (Get-Date).AddMonths(-12) } | ...
Get-WUHistory | ...
Get-WinEvent -FilterHashtable @{ LogName="Microsoft-Windows-WindowsUpdateClient/Operational"; ... }
wevtutil epl "Microsoft-Windows-WindowsUpdateClient/Operational" ...
Get-WindowsPackage -Online | ...
dism /online /get-packages /format:table
'@ | Out-File (Join-Path $root '06_Commandes.txt') -Encoding UTF8
# 6) Hash des fichiers produits
Get-ChildItem $root -File | ForEach-Object {
Get-FileHash $_.FullName -Algorithm SHA256
} | Format-Table | Out-File (Join-Path $root '05_Hash.txt') -Encoding UTF8
# 7) Archive zip
Compress-Archive -Path (Join-Path $root '*') -DestinationPath (Join-Path $ShareRoot "$server`_$stamp.zip")
Créer la tâche planifiée mensuelle
$scriptPath = 'C:\Admin\Scripts\Export_WU_Evidence.ps1'
$share = '\\MonNAS\Audit\WU'
# (Copiez d'abord le script dans $scriptPath)
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`" -ShareRoot `"$share`""
$trigger = New-ScheduledTaskTrigger -Monthly -DaysOfMonth 2 -At 03:00
$principal= New-ScheduledTaskPrincipal -UserId 'NT AUTHORITY\SYSTEM' -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName 'Capture_Evidence_WindowsUpdate' -Action $action -Trigger $trigger -Principal $principal -Description 'Export mensuel des preuves Windows Update (12 mois)'
Bonnes pratiques pour un dossier « audit‑proof »
- Inclure le nom du serveur et l’horodatage dans chaque export (colonnes et nom de fichier).
- Calculer un hash SHA‑256 de tous les fichiers livrés (et des archives) ; conservez le 05_Hash.txt signé.
- Conserver au moins 24 rapports mensuels (test + prod) afin de démontrer la chronologie et la répétabilité.
- Documenter la procédure (qui lance, où se trouvent les exports, quel partage sécurisé, politique de rétention).
- Éviter les nettoyages destructifs sans sauvegarde préalable de
DataStore.edb
et sans archive des journaux. - Corréler les sources : Get‑HotFix (WMI), événements 19/20/21 (process), DISM (servicing). Trois angles = un dossier solide.
Erreurs courantes à éviter
- Se fier uniquement à la vue Windows Update : elle peut avoir été réinitialisée et ne couvre pas 12 mois.
- Oublier les pilotes : s’ils sont dans le périmètre, utilisez PSWindowsUpdate pour les inclure.
- N’utiliser qu’un seul serveur : l’audit demande souvent test puis prod. Préparez un export pour chaque rôle.
- Remplacer le dossier
SoftwareDistribution
sans sauvegarde : vous perdez la vue historique. - Alterer l’heure système pendant la collecte : cela décrédibilise les dates. Figez l’horloge (NTP correct) avant d’exporter.
FAQ rapide
La commande Get‑HotFix
ne liste pas un KB que je vois dans DISM ; est‑ce normal ?
Oui, certains composants (Features on Demand, packs de langue, .NET spécifiques) ressortent mieux via Get‑WindowsPackage
. D’où l’intérêt de croiser WMI + DISM + événements.
WMIC n’est pas disponible sur mon serveur ; que faire ?
Utilisez Get‑HotFix
(PowerShell) ou Get‑CimInstance -ClassName Win32_QuickFixEngineering
pour interroger WMI.
Comment démontrer la séquence test → prod ?
Conservez des exports datés par environnement. En audit, présentez test (Év. 19 avec Date T) puis prod (Év. 19 avec Date P > T), accompagnés des CSV HotFix/PSWindowsUpdate.
Le serveur est en mode Core (pas d’interface) ; des alternatives ?
Oui : toutes les commandes PowerShell et DISM fonctionnent en Core. Utilisez Get‑WinEvent
pour exporter les journaux et copiez les fichiers sur un partage.
Modèle de rapport (copier‑coller)
# > RapportRendu.txt (exemple)
Serveur : SRV-TEST-01
Période couverte : 12 derniers mois (au <YYYY‑MM‑DD HH:MM>)
Sources :
- 01_HotFix.csv (WMI)
- 02_WUHistory.csv (PSWindowsUpdate)
- 03_WUEvents.evtx + 03_WUEvents.csv (Événements 18/19/20/21)
- 04_WindowsPackages.csv (DISM)
Intégrité :
- Empreintes SHA‑256 : voir 05_Hash.txt
Observations :
- Les KB cumulatives mensuelles (LCU) apparaissent aux dates attendues.
- Les relances post‑échec sont visibles en Év. 20 → Év. 19 le lendemain.
Conclusion :
- Conformité au processus : déploiement validé sur SRV-TEST-01 avant production.
Résumé opérationnel
- Générez immédiatement un rapport via
Get‑HotFix
ouGet‑WUHistory
et signez‑le. - Exportez les événements 18/19/20/21 pour la preuve process (CSV + EVTX).
- Ajoutez l’inventaire DISM pour couvrir LCU/SSU/.NET/FOD.
- Archivez, horodatez, hashez, puis planifiez la collecte mensuelle.
Aller plus loin : robustifier le runbook
- Standardisez les chemins (
\\<NAS>\Audit\WU\<Serveur>\YYYYMM\
) et la nomenclature (Serveur_YYYYMMDD‑HHMMSS
). - Stockez les scripts dans un dépôt versionné (hash de commit dans 06_Commandes.txt).
- Faites signer numériquement les ZIP si votre PKI interne l’autorise.
- Documentez le plan de reprise : comment réexécuter la collecte sur un serveur reconstruit.
Checklist minute
Étape | OK | Commentaires |
---|---|---|
HotFix.csv généré et signé | □ | |
WUHistory.csv (si PSWindowsUpdate) | □ | |
WUEvents.evtx + WUEvents.csv | □ | |
WindowsPackages.csv / .txt | □ | |
Archive ZIP + SHA‑256 | □ | |
Tâche planifiée mise en place | □ |
Conclusion
Le fait que l’interface Windows Update n’affiche que les trois derniers mois n’empêche pas de reconstituer un historique irréfutable sur douze mois. En combinant Get‑HotFix (WMI), Get‑WUHistory (si disponible), les événements 18/19/20/21 et les packages DISM, vous produisez un dossier de preuves solide, daté, signé et prêt pour un audit. En automatisant la collecte, vous évitez toute future perte d’historique et vous professionnalisez durablement votre processus de patch management.