Impossible de désinstaller IIS sur Windows Server 2016/2019 : erreur 0x800f0922 et « Undoing changes » — guide complet et solutions

Vous tentez de retirer IIS sur un serveur Windows et l’opération “réussit” avant de revenir au redémarrage sur “We couldn’t complete features. Undoing changes.” ou sur l’erreur 0x800f0922 ? Voici une procédure éprouvée et complète pour rétablir un état cohérent et désinstaller IIS proprement.

Sommaire

Vue d’ensemble du problème

Sur Windows Server (VM Azure comprises), la désinstallation de Web Server (IIS) via le Gestionnaire de serveur ou PowerShell peut échouer silencieusement puis être annulée au redémarrage. Le message « We couldn’t complete features. Undoing changes. » indique que le moteur de maintenance de Windows (Component-Based Servicing, CBS) a interrompu la transaction et a restauré l’état précédent. Côté PowerShell, l’échec peut s’afficher sous le code 0x800f0922. Certaines configurations ont observé le problème après l’installation d’une mise à jour cumulative (ex. KB5036896), mais la cause racine n’est pas toujours unique.

Les symptômes typiques sont : retour arrière des « features » au reboot, fichiers d’IIS verrouillés dans C:\Windows\System32\inetsrv et C:\inetpub, services W3SVC/WAS/WMSVC qui empêchent la suppression des binaires, et échec répété même en tentant une suppression « en bloc » du rôle chapeau.

Signes et causes probables

  • Actions CBS en attente (pending actions) qui empêchent l’application d’une désinstallation.
  • Magasin de composants (WinSxS/CBS) en état incohérent ou corrompu, entraînant l’erreur 0x800f0922 lors des opérations de maintenance.
  • Fonctionnalités Optionnelles liées à IIS toujours actives en dehors de l’arborescence Web-* et WAS (ex. composants « IIS* » gérés par DISM).
  • Services IIS (W3SVC, WAS, WMSVC) ou processus tiers verrouillant les fichiers.
  • Dépendances de rôles (RD Web Access/RD Gateway, WSUS, Exchange, SharePoint) qui bloquent la suppression.
  • Mises à jour récentes ayant modifié le magasin de composants, avec besoin d’un nettoyage/réparation ou d’un in‑place repair pour revenir à un état sain.

Plan d’action recommandé

  1. Faire un snapshot/backup de la VM.
  2. Recenser toutes les fonctionnalités réellement installées (IIS + WAS).
  3. Arrêter les services susceptibles de verrouiller les binaires.
  4. Désactiver d’abord les Optional Features « IIS* » s’il y en a.
  5. Retirer toutes les sous‑fonctionnalités Web-* et WAS*.
  6. Retirer le rôle « chapeau » Web-Server et redémarrer.
  7. En cas d’échec ou de 0x800f0922 : nettoyer caches de maintenance, réparer le magasin, vérifier dépendances, éventuellement réinstaller puis retirer, ou procéder via DISM de façon granulaire.

Procédure détaillée

Recenser précisément ce qui est installé

Commencez par lister les composants installés. Cela évite de « laisser passer » une sous‑feature qui ferait échouer la suppression globale.

Get-WindowsFeature | Where-Object {$_.Installed -and ($_.Name -like 'Web-*' -or $_.Name -like 'WAS*')}

Note : WAS (Windows Process Activation Service) doit aussi être retiré.

Arrêter les services qui verrouillent des fichiers

Stop-Service W3SVC,WAS -Force -ErrorAction SilentlyContinue
Stop-Service WMSVC -Force -ErrorAction SilentlyContinue   # Service de gestion IIS (si présent)

Désinstaller d’abord les fonctionnalités « Optional Features » IIS

Ces composants, gérés par DISM, ne figurent pas toujours dans l’arborescence Web-* du Gestionnaire de serveur. Les désactiver en premier débloque souvent la situation.

Get-WindowsOptionalFeature -Online | Where-Object {$_.FeatureName -like 'IIS*' -and $_.State -eq 'Enabled'} |
    ForEach-Object { Disable-WindowsOptionalFeature -Online -FeatureName $_.FeatureName -Remove -NoRestart }

Retirer toutes les sous‑fonctionnalités

Get-WindowsFeature | Where-Object {$_.Installed -and ($_.Name -like 'Web-*' -or $_.Name -like 'WAS*')} |
    ForEach-Object { Uninstall-WindowsFeature -Name $_.Name -Remove }

Retirer le rôle chapeau et redémarrer

Uninstall-WindowsFeature -Name Web-Server -Remove -Restart

Quand l’échec persiste

Si vous rencontrez encore l’erreur 0x800f0922 ou un nouvel « Undoing changes », enchaînez les mesures suivantes.

Nettoyer les caches de maintenance

Sans danger pour le système, ce nettoyage fait repartir sur des bases propres.

net stop wuauserv
net stop bits
net stop trustedinstaller
del /q /f %windir%\Temp\* 
del /q /f %windir%\SoftwareDistribution\Download\* 
net start trustedinstaller
net start bits
net start wuauserv

Analyser et réparer le magasin de composants

DISM /Online /Cleanup-Image /ScanHealth
DISM /Online /Cleanup-Image /RestoreHealth

Consultez C:\Windows\Logs\CBS\CBS.log et C:\Windows\Logs\DISM\dism.log pour isoler un package ou une feature qui échoue. Si le serveur n’a pas accès à Internet/WSUS pour la réparation, montez l’ISO de la même version/édition et utilisez une source locale :

dism /Get-WimInfo /WimFile:D:\sources\install.wim
dism /Online /Cleanup-Image /RestoreHealth /Source:wim:D:\sources\install.wim:INDEX /LimitAccess

Remplacez INDEX par celui qui correspond à votre édition (vu via /Get-WimInfo). Un contrôle d’intégrité système peut compléter la réparation :

sfc /scannow

Réinstaller puis retirer

Si des binaires/services ont été laissés dans un état instable, réinstaller le rôle avant de le supprimer peut réaligner le magasin CBS.

Install-WindowsFeature Web-Server
Restart-Computer
Uninstall-WindowsFeature Web-Server -Remove -Restart

Désactivation granulaire via DISM

Méthode « bas niveau », utile pour contourner un blocage d’Uninstall-WindowsFeature.

dism /online /get-features /format:table | findstr /i IIS
dism /online /Disable-Feature /FeatureName:IIS-WebServerRole /Remove /NoRestart
dism /online /Disable-Feature /FeatureName:WAS /Remove /NoRestart

Vérifier les rôles dépendants

Des produits ou rôles peuvent empêcher la suppression d’IIS. Retirez d’abord ces rôles s’ils sont présents :

Get-WindowsFeature *RDS*,*UpdateServices*,Web-*,WAS* | Where-Object Installed

Mises à jour récemment installées

Plusieurs environnements ont rapporté l’apparition du problème après une mise à jour cumulative (par exemple KB5036896). La désinstallation de la mise à jour n’ayant pas toujours suffi à rétablir un magasin CBS sain, deux voies s’avèrent efficaces en maintenance : restauration d’un snapshot/backup antérieur ou réparation sur place (in‑place upgrade) vers la même version/édition, puis retrait d’IIS une fois le magasin stabilisé.

Tableau de décision rapide

Symptôme constatéAction prioritaireCommande clé
Retour « Undoing changes » au redémarrageNettoyage caches + vérifier pending actionsDISM /Online /Cleanup-Image /RestoreHealth
Erreur 0x800f0922 à la désinstallationRéparer magasin CBS, puis relancerDISM /ScanHealth puis /RestoreHealth
Fichiers IIS verrouillésArrêt W3SVC/WAS/WMSVCStop-Service W3SVC,WAS,WMSVC -Force
Fonctionnalités IIS invisibles dans Web-*Désactiver Optional FeaturesGet-WindowsOptionalFeature -Online
Dépendances de rôles détectéesRetirer le rôle dépendant d’abordGet-WindowsFeature *RDS*,*UpdateServices*
Pas d’accès Internet pour DISMMonter ISO et fournir une source locale/Source:wim:D:\sources\install.wim:INDEX

Script automatique prêt à l’emploi

Le script ci‑dessous enchaîne les opérations avec journalisation. À exécuter dans une console PowerShell élevée (Run as Administrator), après snapshot.

# Requires: PowerShell 5+ (présent sur Windows Server 2016/2019)
# Objectif: retirer proprement IIS (Web-*) et WAS, avec nettoyage et réparation CBS.

\$ErrorActionPreference = 'Stop'
\$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
\$logDir = 'C:\Temp'
\$log = Join-Path \$logDir "IIS-Remove-\$timestamp.log"
if (-not (Test-Path \$logDir)) { New-Item -ItemType Directory -Path \$logDir -Force | Out-Null }

try {
Start-Transcript -Path \$log | Out-Null

```
Write-Host "== Arrêt des services IIS ==" 
foreach ($svc in 'W3SVC','WAS','WMSVC') {
    $s = Get-Service -Name $svc -ErrorAction SilentlyContinue
    if ($s -and $s.Status -ne 'Stopped') {
        Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
    }
}

Write-Host "== Désactivation des Optional Features IIS =="
$opt = Get-WindowsOptionalFeature -Online |
       Where-Object { $_.FeatureName -like 'IIS*' -and $_.State -eq 'Enabled' }
foreach ($f in $opt) {
    Disable-WindowsOptionalFeature -Online -FeatureName $f.FeatureName -Remove -NoRestart | Out-Null
}

Write-Host "== Suppression des sous-fonctionnalités Web-* et WAS* =="
$features = Get-WindowsFeature | Where-Object { $_.Installed -and ($_.Name -like 'Web-*' -or $_.Name -like 'WAS*') }
foreach ($f in $features) {
    Uninstall-WindowsFeature -Name $f.Name -Remove | Out-Null
}

Write-Host "== Suppression du rôle chapeau Web-Server si présent =="
$web = Get-WindowsFeature -Name Web-Server
if ($web -and $web.Installed) {
    Uninstall-WindowsFeature -Name Web-Server -Remove | Out-Null
}

Write-Host "== Nettoyage caches de maintenance =="
cmd /c "net stop wuauserv"
cmd /c "net stop bits"
cmd /c "net stop trustedinstaller"
Remove-Item -Force -Recurse -ErrorAction SilentlyContinue "$env:windir\Temp\*"
Remove-Item -Force -Recurse -ErrorAction SilentlyContinue "$env:windir\SoftwareDistribution\Download\*"
cmd /c "net start trustedinstaller"
cmd /c "net start bits"
cmd /c "net start wuauserv"

Write-Host "== Réparation du magasin CBS =="
cmd /c "dism /Online /Cleanup-Image /RestoreHealth"

Write-Host "== Contrôle post-opération =="
Get-WindowsFeature Web-*,WAS* | Where-Object Installed

Write-Host "== Redémarrage dans 10 secondes =="
Start-Sleep -Seconds 10
Restart-Computer
```

}
catch {
Write-Error $\_.Exception.Message
}
finally {
Stop-Transcript | Out-Null
Write-Host "Journal détaillé: \$log"
} 

Vérifications post‑désinstallation

Après redémarrage, validez que tout est propre :

VérificationCommandeRésultat attendu
Aucune feature IIS/WAS installéeGet-WindowsFeature Web-*,WAS* | Where-Object InstalledSortie vide
Services supprimés ou arrêtéssc.exe query W3SVC / sc.exe query WASÉtat STOPPED ou service introuvable
Ports 80/443 non utilisés par IISnetstat -ano | findstr ":80" / :443Aucun PID lié à IIS
Event Logs propresObservateur d’événements > Setup / SystemPas d’échecs CBS/DISM récents
Dossiers résiduelsExplorer ou PowerShellSupprimer non verrouillés (C:\inetpub, journaux)

Mode de récupération en cas de boucle de restauration

Si le serveur redémarre systématiquement avec un « revert » des actions en attente, intervenez en environnement de récupération (mode sans échec ou Environnement de Récupération) pour forcer l’annulation des actions CBS en file d’attente :

dism /image:C:\ /cleanup-image /revertpendingactions

Sur des VM Azure, la Console Série du portail permet d’exécuter ces commandes hors du système principal lorsque l’OS ne démarre plus correctement.

Bonnes pratiques et garde‑fous

  • Toujours prendre un snapshot/backup avant toute opération de maintenance de rôles.
  • Évitez de supprimer manuellement C:\Windows\System32\inetsrv et C:\inetpub tant que la suppression du rôle n’est pas terminée, au risque d’un magasin CBS incohérent.
  • Si vous aviez activé la suppression du payload (-Remove) lors d’installations précédentes, des réinstallations ultérieures exigeront une source (ISO, partage) pour restaurer les binaires manquants.
  • Les produits s’appuyant sur IIS (RD Web Access, WSUS, Exchange, SharePoint) doivent être gérés selon leur procédure de désinstallation avant de retirer IIS.
  • Sur des environnements contrôlés, vérifiez que les stratégies de sécurité n’entravent pas le service Windows Modules Installer (TrustedInstaller).

Questions fréquentes

Que signifie concrètement 0x800f0922 ?
C’est un échec d’opération de maintenance d’un composant Windows (installation/désinstallation/réparation). Dans notre contexte, CBS n’a pas pu finaliser la suppression d’une feature ou d’un package, d’où l’annulation au reboot.

Pourquoi la désinstallation « tout‑en‑un » échoue alors que la suppression granulaire fonctionne ?
Parce qu’un sous‑composant reste actif/verrouillé ou qu’une dépendance non gérée renverse la transaction complète. En retirant d’abord les Optional Features puis les sous‑features, on réduit le périmètre de la transaction et on évite l’échec global.

Peut‑on tout réparer avec DISM uniquement ?
Souvent oui (scan + restore). Toutefois, si le magasin CBS est fortement endommagé ou si une mise à jour récente a cassé une dépendance, un in‑place repair avec la même build/édition est la voie la plus rapide pour repartir d’un état sain.

Quand supprimer les dossiers inetpub et autres artefacts ?
Uniquement une fois les features retirées et après redémarrage. Ne forcez pas la suppression de fichiers verrouillés : c’est le signe qu’un service n’est pas encore retiré/arrêté.

Référentiel utile des fonctionnalités IIS courantes

Nom de la featureRôle/ComposantQuand la retirerCommande type
Web-ServerRôle chapeauAprès retrait des sous‑featuresUninstall-WindowsFeature -Name Web-Server -Remove
WASService d’activationAvec/avant le rôle chapeauUninstall-WindowsFeature -Name WAS -Remove
Web-WebServerServices Web de baseToujours si IIS non requisUninstall-WindowsFeature -Name Web-WebServer -Remove
Web-Common-HttpFonctions HTTPSi pas d’hébergement HTTPUninstall-WindowsFeature -Name Web-Common-Http -Remove
Web-Http-LoggingJournalisationAvec le reste d’IISUninstall-WindowsFeature -Name Web-Http-Logging -Remove
Web-Asp-Net45ASP.NETSi aucun site .NETUninstall-WindowsFeature -Name Web-Asp-Net45 -Remove
Web-WebSocketsWebSocketsSi non utiliséUninstall-WindowsFeature -Name Web-WebSockets -Remove
Web-Mgmt-ServiceWMSVCArrêter avant retraitStop-Service WMSVC puis Uninstall-WindowsFeature
IIS-ManagementConsoleOptional FeatureRetirer en premier si activéeDisable-WindowsOptionalFeature -Online -FeatureName IIS-ManagementConsole -Remove
IIS-WebServerRoleFeature DISMRetirer si listée via DISMdism /online /Disable-Feature /FeatureName:IIS-WebServerRole /Remove

Spécificités pour des VM Azure

  • Avant toute manipulation, déclenchez un instantané ou une sauvegarde application-consistent.
  • En cas d’échec bloquant au démarrage, servez‑vous de la Console Série pour exécuter DISM en mode hors ligne et annuler les actions en attente.
  • Vérifiez qu’aucune extension d’automatisation ne réinstalle IIS après suppression (scripts d’agent, Desired State Configuration, etc.).

Checklist compacte

  • Snapshot effectué, fenêtre de maintenance validée.
  • Recensement Get-WindowsFeature et Get-WindowsOptionalFeature.
  • Arrêt W3SVC/WAS/WMSVC.
  • Désactivation des Optional Features « IIS* ».
  • Suppression des sous‑features Web-* et WAS*.
  • Suppression du rôle Web-Server, redémarrage.
  • En cas d’échec : nettoyage caches, DISM/SFC, vérification des dépendances, désactivation DISM granulaire, ou réinstallation puis retrait.
  • Contrôles post‑désinstallation et nettoyage des dossiers non verrouillés.

Commandes essentielles récapitulées

# Inventaire
Get-WindowsFeature | Where-Object {$_.Installed -and ($_.Name -like 'Web-*' -or $_.Name -like 'WAS*')}
Get-WindowsOptionalFeature -Online | Where-Object {$_.FeatureName -like 'IIS*' -and $_.State -eq 'Enabled'}

# Arrêt services

Stop-Service W3SVC,WAS,WMSVC -Force -ErrorAction SilentlyContinue

# Optional Features

Get-WindowsOptionalFeature -Online | Where-Object {\$*.FeatureName -like 'IIS\*' -and \$*.State -eq 'Enabled'} |
ForEach-Object { Disable-WindowsOptionalFeature -Online -FeatureName $\_.FeatureName -Remove -NoRestart }

# Sous-features

Get-WindowsFeature | Where-Object {\$*.Installed -and (\$*.Name -like 'Web-*' -or $\_.Name -like 'WAS*')} |
ForEach-Object { Uninstall-WindowsFeature -Name $\_.Name -Remove }

# Rôle chapeau

Uninstall-WindowsFeature -Name Web-Server -Remove -Restart

# Si échec

DISM /Online /Cleanup-Image /ScanHealth
DISM /Online /Cleanup-Image /RestoreHealth
dism /online /get-features /format\:table | findstr /i IIS
dism /online /Disable-Feature /FeatureName\:IIS-WebServerRole /Remove /NoRestart
dism /online /Disable-Feature /FeatureName\:WAS /Remove /NoRestart

# Dépendances

Get-WindowsFeature *RDS*,*UpdateServices*,Web-*,WAS* | Where-Object Installed

# Revert pending actions (WinRE)

dism /image\:C:\ /cleanup-image /revertpendingactions 

En appliquant ce parcours, vous remettez le magasin de composants dans un état cohérent, neutralisez toutes les dépendances, puis retirez proprement IIS. Le résultat attendu : plus de « Undoing changes » au redémarrage, pas de 0x800f0922, et un serveur assaini, prêt à être sécurisé et sauvegardé à nouveau.

Sommaire