Windows Server 2022 : corriger l’activation KMS après mise à niveau (0xC004F074, SRV _vlmcs)

Après une mise à niveau in‑place vers Windows Server 2022, trois serveurs affichaient des erreurs KMS (0xC004F074, événement 8198) malgré un statut « Licensed ». Voici l’analyse complète, le plan d’action éprouvé et un script prêt à l’emploi pour fiabiliser l’activation.

Sommaire

Contexte et symptômes

À l’issue d’une montée de version sur place vers Windows Server 2022, l’activation devait se faire via KMS (Key Management Service) par découverte DNS. Or, sur chaque client :

  • Événement 8198 : hr=0x8007139F (enregistrement DNS introuvable ou invalide).
  • slmgr /ato : erreur 0xC004F074 (impossible de contacter un hôte KMS).
  • slmgr /dlv indiquait pourtant :
    • License Status : Licensed
    • Volume activation expiration : 137 jours
    • DNS auto‑discovery : KMS name not available

De son côté, le serveur KMS journalisait l’événement 12290 (une requête d’activation traitée). D’où la confusion : activation réellement effective ou situation fragile ?

Pourquoi « Licensed » alors que KMS semble inaccessible ?

Le mécanisme KMS repose sur un jeton d’activation de 180 jours, renouvelé automatiquement toutes les 7 jours. Si un client reçoit ce jeton (par exemple lors d’un moment où le KMS était atteignable, ou via KMS host caching), son statut passe à Licensed et un compteur de 180 jours démarre. Tant que le client réussit à recontacter un hôte KMS au moins une fois avant l’expiration, le compteur se réinitialise. Dans le cas décrit : 137 jours restants signifient que le jeton est valide mais que la découverte DNS auto (_vlmcs._tcp) échoue, empêchant les renouvellements fiables.

Lecture des erreurs et des journaux

  • 0x8007139F : « Le service ne peut pas trouver l’enregistrement SRV ». Souvent, l’entrée _vlmcs._tcp.<domaine> n’existe pas, pointe vers une machine supprimée, ou existe en double avec des hôtes incohérents.
  • 0xC004F074 : l’adresse du KMS est connue (via cache, GPO ou /skms), mais la négociation sur TCP 1688 échoue (filtrage réseau, hôte KMS non à jour, service Software Protection Platform arrêté, seuil KMS non atteint, etc.).
  • Événement 12290 (KMS) : le serveur KMS confirme qu’une requête a été traitée. Cela peut provenir d’un client ayant mémorisé un hôte valide dans son cache, donc sans recourir à la découverte DNS.

Table de correspondance des erreurs fréquentes

Code / ÉvénementSymptôme observableCauses probablesPistes de résolution
0x8007139F
(événement 8198)
« KMS name not available » en auto‑découverteSRV _vlmcs._tcp absent, obsolète ou en doublonNettoyer le DNS ; conserver uniquement l’hôte KMS actif
0xC004F074slmgr /ato échouePort 1688 bloqué, KMS non compatible WS2022, service sppsvc arrêtéOuvrir 1688/TCP, mettre à jour l’hôte KMS, relancer sppsvc
0xC004F038Activation refuséeSeuil KMS non atteint (25 workstations, 5 serveurs)Augmenter le parc activable ou utiliser MAK/ADBA
0x8007232BNom DNS introuvableNom KMS statique erroné (/skms)Corriger /skms ou restaurer l’auto‑découverte

Diagnostic rapide pas à pas

  1. État local slmgr /dlv slmgr /xpr Vérifiez License Status, la date d’expiration volume, la présence d’un Key Management Service client information avec KMS machine name et KMS port.
  2. SRV DNS _vlmcs._tcp nslookup -type=srv _vlmcs._tcp.<domaine.local> # ou Resolve-DnsName -Type SRV _vlmcs._tcp.<domaine.local> Il ne doit rester que les hôtes KMS réellement actifs.
  3. Connectivité réseau Test-NetConnection kms01.domaine.local -Port 1688 # ou tnc kms01.domaine.local -Port 1688 Le test doit réussir des clients vers le KMS et du KMS vers les clients (si inspection réciproque).
  4. Compatibilité de l’hôte KMS
    • KMS au minimum Windows Server 2019 (ou WS 2012 R2/2016/2019 avec mise à jour corrigeant la prise en charge de WS 2022).
    • Clé hôte KMS (CSVLK) adaptée à Windows Server 2022 sur le KMS.
  5. Service local Get-Service sppsvc | Select-Object Status, StartType # Démarrage si nécessaire Start-Service sppsvc
  6. Journaux
    • Sur le client : Application → Software Protection Platform Service (événements 8198/8200).
    • Sur le KMS : Journaux « Key Management Service » (12288–12290).

Résolution mise en œuvre

Le problème provenait de deux enregistrements SRV _vlmcs._tcp, dont un pointant vers un ancien serveur supprimé. La résolution ronde‑robin exposait aléatoirement un hôte inexistant ; d’où les erreurs 0x8007139F et 0xC004F074 malgré des activations successives par cache.

ÉtapeActionRésultat / But
1Nettoyer les enregistrements SRV _vlmcs._tcp (ne garder que le KMS actif).Élimine 0x8007139F lié à la découverte DNS.
2Sur chaque client :
slmgr /ckms (purger le cache),
slmgr /skms kms01.domaine.local (forcer l’hôte),
slmgr /ato.
Adresse explicitement le bon serveur et renouvelle le jeton (retour à 180 jours).
3Vérifier :
slmgr /dlv ou slmgr /xpr (doit afficher « permanently activated » ou une nouvelle date d’expiration).
Confirmation post‑remédiation.
4Si l’environnement ne comptera jamais 5 serveurs/25 workstations, ou si la correction DNS/KMS n’est pas souhaitée : basculer sur une clé MAK.Activation permanente, indépendante de KMS.

Procédure complète et script d’automatisation

Pour traiter un lot de machines (ici, trois serveurs), le script PowerShell suivant nettoie le cache KMS, force l’hôte, vérifie la connectivité et consolide un rapport :

$Servers = @(
  "srv-app-01.contoso.local",
  "srv-db-02.contoso.local",
  "srv-web-03.contoso.local"
)

$KmsHost = "kms01.contoso.local"
$KmsPort = 1688

Function Invoke-Activation {
param([string]$ComputerName)

$session = New-PSSession -ComputerName $ComputerName -ErrorAction Stop
try {
Invoke-Command -Session $session -ScriptBlock {
param($HostName, $Port)

```
  # 1) Vérifier le service sppsvc
  $svc = Get-Service -Name sppsvc -ErrorAction SilentlyContinue
  if (-not $svc -or $svc.Status -ne 'Running') { Start-Service sppsvc }

  # 2) Purger le cache KMS et définir l'hôte
  cscript.exe "$env:windir\system32\slmgr.vbs" /ckms | Out-Null
  cscript.exe "$env:windir\system32\slmgr.vbs" /skms "$($HostName):$($Port)" | Out-Null

  # 3) Test réseau
  $net = Test-NetConnection -ComputerName $HostName -Port $Port
  if (-not $net.TcpTestSucceeded) {
    return [PSCustomObject]@{
      Computer    = $env:COMPUTERNAME
      Reachable   = $false
      KmsHost     = $HostName
      Port1688    = $false
      Status      = "Échec connectivité TCP 1688"
      DaysLeft    = $null
      Licensed    = $null
    }
  }

  # 4) Activation
  cscript.exe "$env:windir\system32\slmgr.vbs" /ato | Out-Null
  Start-Sleep -Seconds 3

  # 5) Lecture /dlv minimal via WMI/CIM
  $prod = Get-CimInstance -ClassName SoftwareLicensingProduct `
    -Filter "PartialProductKey is not null and ApplicationID='55c92734-d682-4d71-983e-d6ec3f16059f'"
  $lic = $prod | Where-Object { $_.LicenseStatus -ne $null } | Select-Object -First 1

  # Convertit la grâce en jours si disponible
  $days = $null
  if ($lic.GracePeriodRemaining) { $days = [math]::Round($lic.GracePeriodRemaining/1440, 0) }

  [PSCustomObject]@{
    Computer    = $env:COMPUTERNAME
    Reachable   = $true
    KmsHost     = $HostName
    Port1688    = $true
    Status      = if($lic.LicenseStatus -eq 1){"Licensed"}else{"Non-Licensed"}
    DaysLeft    = $days
    Licensed    = $lic.LicenseStatus
  }
} -ArgumentList $KmsHost, $KmsPort
```

}
catch {
[PSCustomObject]@{
Computer    = $ComputerName
Reachable   = $false
KmsHost     = $KmsHost
Port1688    = $false
Status      = "Erreur de session distante: $($_.Exception.Message)"
DaysLeft    = $null
Licensed    = $null
}
}
finally {
if ($session) { Remove-PSSession $session }
}
}

$report = foreach($s in $Servers){ Invoke-Activation -ComputerName $s }
$report | Format-Table -AutoSize

# Export CSV si besoin

$report | Export-Csv -NoTypeInformation -Path "$env:TEMP\kms-report.csv" 

Remarques :

  • Le filtre ApplicationID='55c9…' correspond à l’activation Windows (il exclut Office, etc.).
  • Adaptez $Servers et $KmsHost à votre environnement. Ouvrez WinRM si nécessaire (Enable-PSRemoting).
  • En cas d’utilisation d’une clé MAK, remplacez la séquence /skms//ato par slmgr /ipk <clé‑MAK> puis slmgr /ato (ou /ato offline via téléphone si réseau coupé).

Vérifications côté serveur KMS

  • Compatibilité : l’hôte KMS doit prendre en charge Windows Server 2022 (hôte sous WS 2019+ ou WS 2012 R2/2016/2019 avec mise à jour correspondante) et disposer d’une clé CSVLK adaptée.
  • Services : sppsvc en cours d’exécution, port TCP 1688 accessible depuis les clients (pare‑feu/ACL).
  • DNS SRV : un seul enregistrement _vlmcs._tcp par hôte KMS actif, TTL cohérent, pas de reliquat pointant vers un serveur retiré.
  • Journaux : événement 12290 lors d’une activation réussie ; surveillez également les éventuels 12288/12289.
  • Seuils : 5 activations minimum pour Windows Server (25 pour poste client). En‑dessous, retour 0xC004F038.

Cas d’usage, choix d’architecture et alternatives

KMS « classique » via SRV DNS

Idéal lorsque le parc répond aux seuils et qu’un ou plusieurs KMS sont disponibles et hautement accessibles. La découverte DNS rend le déploiement simple, mais impose de rigoureuses hygiènes DNS.

KMS avec hôte spécifié

Pour fiabiliser les clients, vous pouvez pousser via GPO un FQDN et un port KMS (KeyManagementServiceName et KeyManagementServicePort sont configurés par slmgr /skms). Avantages : pas de dépendance à l’enregistrement SRV ; inconvénient : gestion du changement d’hôte et du basculement.

ADBA (Activation basée sur AD)

Alternative qui exploite AD pour distribuer l’activation sans SRV DNS ni exposition du port 1688 vers tous les segments. Pertinent dans des environnements 100 % joints au domaine. Nécessite la publication d’objets d’activation dans AD et des contrôleurs de domaine compatibles.

MAK

Choix pragmatique lorsque :

  • Le seuil KMS ne sera jamais atteint (petit parc de serveurs).
  • Les contraintes réseau (sites isolés, DMZ strictes) compliquent l’accès au KMS.
  • On souhaite découpler totalement l’activation du fonctionnement du service KMS.

Inconvénients : gestion des activations unitaires, suivi des compteurs MAK, procédure offline si besoin. Avantage : activation permanente sans renouvellement périodique.

Bonnes pratiques et prévention

  • Gouvernance DNS : tout retrait d’un serveur KMS doit s’accompagner de la suppression immédiate de l’entrée SRV correspondante.
  • Supervision : alertez sur l’absence d’événements 12290 pendant X jours ou sur une baisse anormale du taux de renouvellement.
  • Résilience : si vous opérez plusieurs KMS, documentez la répartition SRV (priorité/poids) et validez régulièrement la résolution depuis chaque site.
  • MCO du KMS : maintenez l’hôte KMS à jour (compatibilité WS 2022), conservez sa clé CSVLK, surveillez sppsvc.
  • Durées de grâce : intégrez dans vos runbooks un contrôle mensuel (slmgr /xpr) pour éviter toute expiration simultanée.
  • GPO : pour les segments isolés, définissez un KMS explicite (/skms) via stratégie, puis basculez vers la découverte DNS une fois le DNS assaini.

Vérifications détaillées : commandes utiles

# Côté client
slmgr /dli                        # vue rapide
slmgr /dlv                        # vue détaillée
slmgr /xpr                        # expiration
slmgr /ckms                       # purge du cache KMS
slmgr /skms kms01.domaine.local   # forcer l'hôte KMS (avec :1688 si non standard)
slmgr /ato                        # tentative d'activation

# PowerShell - état licence

Get-CimInstance -Class SoftwareLicensingProduct `
-Filter "PartialProductKey is not null and ApplicationID='55c92734-d682-4d71-983e-d6ec3f16059f'" |
Select-Object Name, LicenseStatus, GracePeriodRemaining

# DNS SRV

nslookup -type=srv _vlmcs._tcp.domaine.local
Resolve-DnsName -Type SRV _vlmcs._tcp.domaine.local

# Réseau

Test-NetConnection kms01.domaine.local -Port 1688

# Côté KMS (exemples)

slmgr /dlv                        # vérifier la clé CSVLK et le support des OS
Get-Service sppsvc
Get-EventLog -LogName Application -Newest 50 | ? {$_.Source -match "Key Management Service"} 

Que signifient vraiment les états d’activation ?

ÉtatCodeSignificationAction recommandée
Licensed1Jeton KMS actif. Renouvellement toutes les 7 jours.Assurer la joignabilité du KMS pour réinitialiser le compteur à 180 jours.
Out‑of‑Box/Out‑of‑Tolerance Grace2 / 3Période de grâce (post‑déploiement / horloge incohérente).Corriger l’heure/NTP, contacter le KMS.
Notification5Jeton expiré ; rappels visibles.Restaurer l’accès au KMS ou basculer MAK.
Extended Grace6Extension temporaire spéciale.Traiter la cause racine rapidement.

Pièges fréquents et points d’attention

  • Horloge/NTP : un décalage excessif casse la négociation.
  • Multi‑homing : des enregistrements SRV créés automatiquement sur une interface non joignable induisent des échecs partiels.
  • Filtrage Est‑Ouest : certaines micro‑segmentation/ACL bloquent ponctuellement 1688/TCP ; vérifier sur chaque segment.
  • Images masterisées : attention aux résidus de /skms codés en dur dans les sysprep, qui contournent la découverte DNS.
  • Migration d’hôte KMS : planifiez la bascule (SRV priorité/poids), conservez une période de recouvrement, puis retirez l’ancien SRV.

Exemple d’assainissement DNS

Sur un contrôleur DNS Windows (module DnsServer) :

# Lister les SRV _vlmcs._tcp
Get-DnsServerResourceRecord -ZoneName "domaine.local" -RRType SRV |
  Where-Object { $_.RecordData.DomainName -like "*_vlmcs*" -or $_.HostName -eq "_vlmcs._tcp" }

# Supprimer un SRV obsolète (exemple)

Remove-DnsServerResourceRecord -ZoneName "domaine.local" `
-RRType SRV -Name "_vlmcs._tcp" -RecordData "kms-decommissioned.domaine.local" -Force

# Ajouter/valider le SRV pour kms01

Add-DnsServerResourceRecord -ZoneName "domaine.local" -Srv `
-Name "_vlmcs._tcp" -DomainName "kms01.domaine.local" -Priority 0 -Weight 100 -Port 1688 

Quand choisir MAK plutôt que KMS ?

Si vos sites ne peuvent pas atteindre 1688/TCP de façon fiable, si vous avez moins de 5 serveurs Windows à activer, ou si vous souhaitez éviter toute dépendance à un service central, la clé MAK est souvent la plus adaptée. Procédure :

slmgr /ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
slmgr /ato
# (ou activation téléphonique si nécessaire)

Conservez un inventaire des activations par machine. Pour revenir à KMS, remplacez la clé par la GVLK correspondant à l’édition, supprimez l’hôte /ckms et réactivez.

FAQ express

Q : « Mon client est Licensed mais affiche 0xC004F074 à chaque /ato ; est‑ce grave ? »
R : Oui à moyen terme. Le jeton actuel expira au bout des 180 jours si aucun renouvellement n’aboutit. Corrigez la résolution DNS et/ou la connectivité 1688.

Q : « Le KMS enregistre 12290 ; puis‑je ignorer les erreurs côté client ? »
R : Non, car ces succès peuvent reposer sur le cache KMS et ne pas refléter l’état du DNS. Un SRV pollué crée des pannes aléatoires et du bruit opérationnel.

Q : « Faut‑il un seul SRV _vlmcs._tcp ? »
R : Un SRV par hôte KMS actif. Si vous avez deux KMS, vous aurez deux SRV, mais uniquement pour des hôtes réellement joignables.

Q : « Comment valider que le KMS supporte WS 2022 ? »
R : Vérifiez la version de l’hôte et la clé CSVLK installée. Un hôte non compatible renverra typiquement 0xC004F074 ou refusera des clients WS 2022.

Conclusion

Dans ce cas réel, les serveurs étaient bien activés à court terme, car ils détenaient déjà un jeton KMS valide. En revanche, la découverte DNS cassée (_vlmcs._tcp en doublon) menaçait le renouvellement périodique et conduisait à des erreurs 0x8007139F/0xC004F074. La remédiation propre consiste à corriger le DNS, purger le cache client, forcer temporairement l’hôte (/skms), puis relancer l’activation. Faute de temps, la bascule MAK est un palliatif acceptable, mais elle sort la machine du modèle KMS. En appliquant les contrôles, scripts et bonnes pratiques ci‑dessus, vous fiabilisez durablement l’activation de vos serveurs Windows Server 2022 après mise à niveau.


Sommaire