Windows Server 2019/2022 : mises à jour installées par script absentes de l’historique Windows Update — causes, vérification et solutions

Vous installez vos mises à jour via PSWindowsUpdate ou l’API Windows Update, tout s’installe correctement… mais rien n’apparaît dans « Afficher l’historique des mises à jour ». Voici pourquoi, comment vérifier l’état réel sur Windows Server 2019/2022 et quoi adapter dans vos scripts.

Sommaire

Les mises à jour Windows installées par script n’apparaissent pas dans « Afficher l’historique des mises à jour »

Vue d’ensemble de la question

Sur des serveurs Windows Server 2019 et 2022, il est courant d’automatiser le cycle scan → download → install au moyen des API COM Microsoft.Update.Session / IUpdateInstaller ou du module PSWindowsUpdate. Les événements de réussite sont bien présents dans les journaux, les correctifs sont listés dans « Désinstaller une mise à jour », et pourtant la page Paramètres > Windows Update > Afficher l’historique des mises à jour reste partielle voire vide. Cela surprend, mais c’est normal dans plusieurs scénarios.

Réponse & solution (en bref)

Constat principal

  • L’écran « Afficher l’historique des mises à jour » reflète uniquement l’historique du client Windows Update (WUA), persistant dans %windir%\SoftwareDistribution (notamment DataStore / ReportingEvents.log).
  • Les installations réalisées via d’autres mécanismes de servicing (par ex. wusa.exe sur un .msu local, dism sur un package .cab, MSI, ou certains parcours scriptés des API WU) peuvent ne pas s’enregistrer dans cet historique — même si la mise à jour est bel et bien installée par le servicing stack.
  • Si le dossier SoftwareDistribution est purgé ou recréé (maintenance, correction de cache WU, sysprep, image clonée), l’historique affiché est remis à zéro. Cela n’enlève pas les mises à jour réellement présentes : seule la « mémoire » du client WUA disparaît.

Où se trouve la vérité ? Priorité aux sources d’autorité

Pour attester de l’état réel du système, basez-vous sur le Component-Based Servicing (CBS) et les journaux, puis utilisez l’historique WU comme un simple indicateur de parcours d’installation.

SourceCe qui est affichéEmplacement/CommandeAutoritéObservations
Historique Windows Update (Paramètres)Événements connus du client WUA%windir%\SoftwareDistribution
ReportingEvents.log
FaibleSe réinitialise si le cache WU est vidé. Peut ignorer des installations faites hors WUA.
Désinstaller une mise à jourPackages réellement présentsPanneau de config → Programmes → Mises à jour installéesÉlevéeVue CBS : reflète l’état de l’OS, utile pour l’audit.
DISM / Get-WindowsPackageInventaire complet des packagesdism /online /get-packages
Get-WindowsPackage -Online
ÉlevéeRecommandé pour les cumulatives (LCU/SSU).
Get-HotFix (WMI QFE)Correctifs de type « hotfix »Get-HotFixMoyennePartiel : ne liste pas toujours les Quality Updates cumulatives modernes.
Journaux WU/CBSDétails techniques de l’installationEvent Viewer : WindowsUpdateClient/Operational
%windir%\Logs\CBS\CBS.log
Get-WindowsUpdateLog
ÉlevéeIndispensable en cas d’enquête ou de conformité stricte.

Vérifier de manière fiable que les mises à jour sont installées

Contrôles graphiques

  • Panneau de configuration → Programmes → Programmes et fonctionnalités → Afficher les mises à jour installées : la liste provient de CBS et reflète l’état réel.
  • Observateur d’événements :
    • Journal Microsoft-Windows-WindowsUpdateClient/Operational : événements de téléchargement/installation (par ex. réussite/échec).
    • %windir%\Logs\CBS\CBS.log : déroulé du servicing stack au niveau composant.

Contrôles en ligne de commande et PowerShell

# Inventaire fiable via DISM
dism /online /get-packages /format:table

# PowerShell équivalent : filtrer les packages installés (et optionnellement par KB)

Get-WindowsPackage -Online |
Where-Object { \$*.PackageState -eq 'Installed' -and \$*.PackageName -match 'KB\d+' } |
Sort-Object -Property InstallTime |
Select-Object -Last 20 PackageName, PackageState, InstallTime

# Rapide mais parfois incomplet pour les cumulatives récentes

Get-HotFix | Sort-Object -Property InstalledOn | Select-Object -Last 20

# Reconstituer WindowsUpdate.log (utile pour diagnostiquer le client WU)

Get-WindowsUpdateLog -LogPath "\$env\:TEMP\WindowsUpdate.log" 

Remarque : Get-HotFix (Win32_QuickFixEngineering) ne voit pas toujours les Quality Updates (LCU). Pour un audit, privilégiez DISM ou Get-WindowsPackage.

Pourquoi l’historique reste vide malgré l’installation réussie ?

  • Parcours d’installation hors WUA : une installation par wusa.exe (fichier .msu) ou dism (.cab) écrit dans CBS, mais peut ne pas alimenter la base locale de l’historique WU.
  • Cache WU réinitialisé : après net stop wuauserv puis suppression de %windir%\SoftwareDistribution, l’historique s’efface. Les mises à jour restent installées.
  • Utilisation partielle des API : si vos scripts COM ne pilotent pas l’intégralité « scan → download → install » via le Windows Update Agent, certains items ne seront pas historisés.
  • Éditions Server : interface parcellaire : selon l’édition (Core/Desktop Experience) et le contexte WSUS/Microsoft Update, l’historique Paramètres peut rester incomplet alors que CBS est correct.
  • Clonage/image : machines déployées depuis une image où SoftwareDistribution a été prépeuplé, puis purgé à la première exécution (sysprep), d’où un historique tout neuf.

Si vous tenez absolument à voir les mises à jour dans « Historique »

Conduire l’installation 100 % via WUA

Le plus sûr est d’orchestrer le scan, le téléchargement et l’installation au travers du Windows Update Agent (WUA) lui‑même, sans passer par wusa.exe/dism pour l’application finale.

Exemple avec PSWindowsUpdate (parcours WUA)

# Installer le module (si absent)
Install-Module PSWindowsUpdate -Force

# Scanne, télécharge et installe via le client WU (WSUS ou Microsoft Update selon configuration)

# -MicrosoftUpdate : facultatif (à éviter si WSUS force la source)

Get-WindowsUpdate -AcceptAll -Install -AutoReboot 

Conditions pour alimenter l’historique :

  • Service Windows Update (wuauserv) démarré (pas désactivé).
  • Ne pas purger SoftwareDistribution durant ou juste après l’installation.
  • Source conforme (WSUS ou Microsoft Update), mais initiation via WUA indispensable.

Exemple PowerShell via les API COM WUA

$session   = New-Object -ComObject 'Microsoft.Update.Session'
$searcher  = $session.CreateUpdateSearcher()
# Filtre : logiciels non installés, non masqués
$searchResult = $searcher.Search("IsInstalled=0 and Type='Software' and IsHidden=0")

if (\$searchResult.Updates.Count -gt 0) {
\$downloader = \$session.CreateUpdateDownloader()
\$downloader.Updates = \$searchResult.Updates
\$dlResult = \$downloader.Download()

```
$installer = $session.CreateUpdateInstaller()
$installer.Updates = $searchResult.Updates
$installResult = $installer.Install()

# Journalisation simple
$searchResult.Updates | ForEach-Object {
    [PSCustomObject]@{
        Title   = $_.Title
        KBs     = ($_.KBArticleIDs -join ',')
        Result  = $installResult.ResultCode
        Reboot  = $installResult.RebootRequired
    }
} | Format-Table -AutoSize
```

} else {
Write-Host "Aucune mise à jour applicable."
} 

Cet exemple laisse WUA piloter l’ensemble du workflow ; les événements associés ont alors plus de chances d’apparaître dans Historique (sous réserve de ne pas nettoyer SoftwareDistribution).

Accepter le comportement et s’appuyer sur CBS pour l’audit

Dans le monde serveur, vouloir que la page Paramètres reflète à la perfection l’historique n’est pas indispensable. Pour la conformité, l’inventaire et les preuves d’installation, DISM / Get‑WindowsPackage + journaux sont les références.

Bonnes pratiques pour vos scripts d’entreprise

  • Journaliser au niveau package : titre, KB, code retour, besoin de redémarrage. Conservez un extrait de Get-WindowsPackage (top N récents) en pièce jointe ou archive de runbook.
  • Éviter de ne se fier qu’à Get-HotFix : combinez avec DISM pour couvrir les LCU/SSU modernes.
  • Choisir la bonne source :
    • WSUS : laissez WUA cibler WSUS (clé UseWUServer gérée par GPO). Évitez -MicrosoftUpdate si WSUS est imposé.
    • Microsoft Update : -MicrosoftUpdate permet d’inclure SQL/Office/VC++ Redistribuables si vous n’êtes pas sous WSUS.
  • Réduit les purges du cache WU : ne supprimez SoftwareDistribution qu’en cas de corruption avérée, sinon l’historique disparaîtra.
  • Standardiser les codes retour : mappez les HRESULT (par ex. 0x00000000, 0x00000002, etc.) à des statuts lisibles dans vos rapports.

Procédure de vérification après installation

  1. Vérifier CBS : Get-WindowsPackage -Online | ? {$_.PackageState -eq 'Installed' -and $_.PackageName -match 'KB(\\d+)'} | Sort-Object InstallTime | Select-Object -Last 10 PackageName, InstallTime
  2. Contrôler le journal WindowsUpdateClient : rechercher les derniers événements de réussite/échec (IDs de type 19/20) et corréler avec l’heure de déploiement.
  3. Regénérer WindowsUpdate.log pour lecture synthétique en cas de doute : Get-WindowsUpdateLog -LogPath "$env:TEMP\WindowsUpdate.log"
  4. Optionnel : vérifier la présence dans la vue « Désinstaller une mise à jour » du Panneau de configuration pour les KB sensibles.

Quand préférer WUSA/DISM malgré l’absence d’historique ?

  • Fenêtre de maintenance courte : installer un .msu ciblé (wusa.exe /quiet /norestart) peut être plus rapide que de laisser WUA évaluer le catalogue complet.
  • Serveur isolé (sans accès MU/WSUS) : installation depuis un dépôt interne de .msu/.cab avec dism ou wusa.
  • Correctif temporaire : pour un package spécifique exigé par un éditeur applicatif.

Dans ces cas, assumez que la page Historique peut rester muette, et documentez via CBS + journaux.

Exemples de séquences robustes

Pipeline WUA contrôlé (préconisé si vous voulez nourrir l’historique)

# 1) Pré-checks
$WU = Get-Service wuauserv
if ($WU.Status -ne 'Running') { Start-Service wuauserv }

# 2) Scan + install (WSUS ou MU selon politique)

Import-Module PSWindowsUpdate
\$result = Get-WindowsUpdate -AcceptAll -Install -IgnoreReboot

# 3) Journalisation CBS (preuve)

\$proof = Get-WindowsPackage -Online |
? {\$*.PackageState -eq 'Installed' -and \$*.PackageName -match 'KB\d+'} |
Sort-Object InstallTime | Select-Object -Last 15

\$proof | Format-Table -AutoSize

# 4) Reboot si nécessaire

if (\$result -and (Get-WURebootStatus).IsRebootRequired) { Restart-Computer -Force } 

Pipeline DISM autonome (rapide, sans historique WUA garanti)

# Installer un package .cab déjà téléchargé
dism /online /add-package /packagepath:"D:\packages\windows10.0-kbXXXXXXX-x64.cab" /quiet /norestart

# Vérifier l’état réel

dism /online /get-packages /format\:table | findstr /i "KBXXXXXXX"

# Journal CBS à corréler

Get-Content \$env\:windir\Logs\CBS\CBS.log -Tail 200 

Questions fréquentes

Peut‑on « forcer » l’écriture dans l’historique WU ?
Pas de commande officielle pour « inscrire » rétroactivement une installation DISM/WUSA dans l’historique WUA. L’historique est émis par le client WU lors d’opérations qu’il pilote lui‑même.

Après nettoyage de SoftwareDistribution, tout l’historique a disparu. Dois‑je réinstaller les patchs ?
Non. L’historique n’est qu’un journal local. Fiez‑vous à Get-WindowsPackage/DISM et au Panneau de configuration pour confirmer que les KB sont bien installées.

PSWindowsUpdate alimente‑t‑il toujours l’historique ?
Lorsqu’il délègue au client WU (scan/téléchargement/installation), oui dans la plupart des cas. Mais certaines commandes ciblées (installation d’un .msu local) ne le feront pas.

Pourquoi Get-HotFix ne liste‑t‑il pas ma cumulative mensuelle ?
Parce qu’il s’appuie sur la classe WMI QFE, historiquement conçue pour les hotfixes et non pour les LCU/SSU. Utilisez Get-WindowsPackage pour les mises à jour modernes.

Checklist de diagnostic rapide

  • Le service wuauserv est‑il actif pendant l’installation ?
  • Le dossier %windir%\SoftwareDistribution n’a‑t‑il pas été purgé juste après le patching ?
  • L’installation a‑t‑elle été initiée via WUA (PSWindowsUpdate / API COM) plutôt que via wusa/dism ?
  • Le serveur pointe‑t‑il vers la bonne source : WSUS ou Microsoft Update ?
  • Les packages sont‑ils visibles dans DISM / Get‑WindowsPackage ? Les événements WU/CBS confirment‑ils la réussite ?

Modèle de log utile à intégrer dans vos scripts

$logPath = "C:\Logs\Patch-$(Get-Date -Format yyyyMMdd-HHmmss).log"

"=== PATCH RUN START \$(Get-Date) ===" | Out-File \$logPath -Encoding UTF8

# 1) Inventaire avant

"--- Before ---" | Out-File \$logPath -Append
(Get-WindowsPackage -Online | ? {\$*.PackageState -eq 'Installed' -and \$*.PackageName -match 'KB\d+'} |
Sort-Object InstallTime | Select-Object -Last 10) | Out-File \$logPath -Append

# 2) Installation via WUA

Import-Module PSWindowsUpdate
\$res = Get-WindowsUpdate -AcceptAll -Install -IgnoreReboot -Verbose 4>&1 | Tee-Object -FilePath \$logPath -Append

# 3) Inventaire après

"--- After ---" | Out-File \$logPath -Append
(Get-WindowsPackage -Online | ? {\$*.PackageState -eq 'Installed' -and \$*.PackageName -match 'KB\d+'} |
Sort-Object InstallTime | Select-Object -Last 10) | Out-File \$logPath -Append

# 4) Statut reboot

\$reboot = (Get-WURebootStatus).IsRebootRequired
"RebootRequired=\$reboot" | Out-File \$logPath -Append

"=== PATCH RUN END \$(Get-Date) ===" | Out-File \$logPath -Append 

Bonnes pratiques d’exploitation

  • Standardisez vos playbooks : un runbook WUA (qui alimente l’historique), un runbook DISM (rapide et offline), chacun avec ses preuves CBS.
  • Documentez les exceptions : quand vous utilisez wusa/dism, notez que l’historique WU peut rester vide et joignez l’extrait CBS.
  • Surveillez le taux d’échec via Event Viewer (canal WindowsUpdateClient) et alertez sur les codes d’erreur récurrents.
  • Testez sur un serveur de préproduction : certains rôles (Cluster, Hyper‑V, SQL) ont des consignes de redémarrage spécifiques.
  • Évitez les outils non documentés (UsoClient.exe) pour la production ; privilégiez WUA/PSWindowsUpdate/COM.

Conclusion

L’absence d’entrées dans « Afficher l’historique des mises à jour » n’indique pas, à elle seule, un échec d’installation. Cet écran n’est qu’une vue de l’agent Windows Update et peut être effacé ou incomplet. Pour prouver l’état réel d’un Windows Server 2019/2022, appuyez‑vous sur CBS (Get‑WindowsPackage/DISM), les journaux WindowsUpdateClient et CBS.log. Si l’objectif est de remplir l’historique, pilotez vos patchs de bout en bout via WUA (PSWindowsUpdate ou API COM) et évitez de purger SoftwareDistribution. Pour l’audit et la conformité, conservez systématiquement des extraits DISM et des traces d’événements : ce sont les seules sources d’autorité.

Sommaire