Windows Server : 10 commandes pour diagnostiquer un service qui ne démarre pas

Analysez dépendances, compte de service, événements, permissions, ports et délais avec dix vérifications en lecture seule et une démarche de correction pilote.

01

Partir de l’échec exact

Un service arrêté peut avoir une cause simple : mauvais chemin, dépendance indisponible, compte verrouillé ou port occupé. Le redémarrage du serveur efface parfois le contexte sans corriger la cause. Ce guide cible un service précis; il complète le diagnostic général Windows Server déjà publié.

Notez le serveur, le nom système, l’heure et le fuseau de l’échec, le message exact, le dernier changement et l’impact métier. Les dix recettes ci-dessous ne démarrent, n’arrêtent ni ne reconfigurent aucun service. Elles comportent parfois plusieurs lectures pour rendre le résultat interprétable.

02

Prérequis et permissions

Les exemples visent une exécution locale sous Windows PowerShell 5.1 sur Windows Server 2019, 2022 ou 2025. Les cmdlets Windows sont également disponibles dans certains environnements PowerShell 7, mais vérifiez modules et paramètres avant de transposer. Aucun module payant ni licence supplémentaire n’est requis pour ces lectures; les licences Windows et applicatives restent applicables.

Commencez avec les droits de lecture délégués : interrogation du service, accès CIM, lecture des journaux et des ACL concernées. Event Log Readers peut convenir pour les journaux autorisés; certains journaux et processus exigent davantage de droits. L’export secedit nécessite une élévation locale. Une erreur Access denied est une limite de collecte, pas une preuve que le service est absent.

Remplacez ContosoAgent et les chemins fictifs. Exécutez les blocs dans l’ordre dans la même session. Aucun secret n’est nécessaire. Protégez les exports et expurgez noms de comptes, chemins sensibles et arguments avant de transmettre les preuves. En cluster, utilisez les procédures du rôle et son propriétaire; ne lancez pas un service géré par le cluster hors de celui-ci.

03

1. Confirmer le nom et l’état du service

Utilisez le nom système, pas seulement le nom affiché. Stopped peut être normal pour un service manuel ou déclenché à la demande. Comparez au fonctionnement attendu par l’éditeur.

PowerShell — collecte en lecture seule
$serviceName = 'ContosoAgent' # Fictional / fictif
Get-Service -Name $serviceName -ErrorAction Stop |
  Select-Object Name,DisplayName,Status,StartType
04

2. Lire le compte, le chemin et les codes de sortie

StartName identifie le compte configuré; il ne prouve pas que son mot de passe ou ses droits sont valides. PathName peut contenir des arguments sensibles : expurgez-les avant partage. ServiceSpecificExitCode est pertinent lorsque ExitCode vaut 1066; consultez alors la documentation du produit.

PowerShell — collecte en lecture seule
$svc = Get-CimInstance Win32_Service |
  Where-Object Name -eq $serviceName
if (-not $svc) { throw 'Service not found / Service introuvable' }
$svc | Select-Object Name,State,StartMode,StartName,PathName,
  ProcessId,ExitCode,ServiceSpecificExitCode,CheckPoint,WaitHint
05

3. Examiner les dépendances déclarées

ServicesDependedOn liste les services requis; DependentServices indique ceux qui dépendent du service ciblé. Une dépendance arrêtée est une piste. Cette liste ne couvre pas forcément SQL, DNS, certificats, partages ou API utilisés par l’application.

PowerShell — collecte en lecture seule
$controller = Get-Service -Name $serviceName -ErrorAction Stop
$controller.ServicesDependedOn | Select-Object Name,Status
$controller.DependentServices | Select-Object Name,Status
06

4. Corréler les événements Service Control Manager

Collectez autour de l’heure exacte de l’échec. Le message complet importe davantage que le seul ID : 7000 peut couvrir plusieurs causes, 7001 une dépendance et 7038 un problème d’ouverture de session. La limite de 200 événements peut tronquer une période chargée; réduisez la fenêtre ou augmentez prudemment la limite.

PowerShell — collecte en lecture seule
$since = (Get-Date).AddHours(-2)
Get-WinEvent -FilterHashtable @{
  LogName = 'System'
  ProviderName = 'Service Control Manager'
  StartTime = $since
} -MaxEvents 200 |
  Select-Object TimeCreated,Id,LevelDisplayName,Message
07

5. Chercher une erreur applicative au même moment

Un service peut être lancé puis quitter immédiatement. Cherchez l’erreur du produit, .NET Runtime ou Application Error, puis comparez le processus, le module fautif et l’horodatage. Une erreur voisine n’établit pas à elle seule un lien causal. Les journaux propres au produit peuvent être ailleurs.

PowerShell — collecte en lecture seule
Get-WinEvent -FilterHashtable @{
  LogName = 'Application'
  StartTime = $since
  Level = 1,2,3
} -MaxEvents 100 |
  Select-Object TimeCreated,ProviderName,Id,Message
08

6. Vérifier le binaire sans l’exécuter

Copiez uniquement le chemin de l’exécutable depuis PathName; ne découpez pas naïvement sur les espaces et n’exécutez pas cette chaîne. Pour un service hébergé par svchost, le fichier hôte ne suffit pas : identifiez le composant réel avec la documentation du rôle. Une signature absente n’est pas une preuve de malveillance, et une signature valide ne garantit pas le bon fonctionnement.

PowerShell — collecte en lecture seule
$exePath = 'C:\Program Files\Contoso\Agent\agent.exe'
Get-Item -LiteralPath $exePath -ErrorAction Stop |
  Select-Object FullName,Length,LastWriteTime,
    @{n='FileVersion';e={$_.VersionInfo.FileVersion}}
Get-AuthenticodeSignature -LiteralPath $exePath |
  Select-Object Status,StatusMessage
09

7. Lire les permissions des fichiers et dossiers nécessaires

Vérifiez binaire, configuration, données et journaux. Les ACL affichées ne calculent pas les droits effectifs du compte de service : groupes, refus explicites, partage SMB et identité réseau comptent aussi. Lire un fichier sous votre compte administrateur ne teste pas l’accès du service. Ne donnez pas Full Control à Everyone pour contourner un refus.

PowerShell — collecte en lecture seule
$paths = @($exePath, 'C:\ProgramData\Contoso\Agent')
foreach ($path in $paths) {
  Get-Acl -LiteralPath $path -ErrorAction Stop |
    Select-Object Path,Owner,AccessToString
}
10

8. Contrôler le droit d’ouverture de session comme service

Cet export écrit un fichier de diagnostic sans modifier la stratégie. Il exige une session élevée et un dossier protégé. Comparez SeServiceLogonRight et SeDenyServiceLogonRight aux SID du compte et de ses groupes : le refus prime. Pour un compte AD, vérifiez aussi verrouillage, expiration et dépendances; pour un gMSA, vérifiez les hôtes autorisés à obtenir son secret sans le réinitialiser manuellement.

PowerShell — collecte en lecture seule
# Use an existing protected folder / Dossier protégé existant
$policyFile = Join-Path 'C:\AdminReports' ('rights-' + [guid]::NewGuid() + '.inf')
secedit.exe /export /mergedpolicy /cfg $policyFile /areas USER_RIGHTS /quiet
if ($LASTEXITCODE -ne 0) { throw 'Policy export failed / Échec export' }
Select-String -LiteralPath $policyFile -Pattern '^Se(ServiceLogonRight|DenyServiceLogonRight)\s*='
11

9. Identifier un port TCP déjà occupé

Remplacez 8443 par le port configuré dans l’application. Un processus à l’écoute sur le même port n’est pas nécessairement en conflit : adresse locale, IPv4/IPv6 et partage du port changent le résultat. Le PID peut disparaître entre deux lectures. Cette commande ne vérifie ni UDP ni une réservation HTTP.sys; n’arrêtez pas le processus identifié automatiquement.

PowerShell — collecte en lecture seule
$port = 8443
$listeners = Get-NetTCPConnection -State Listen |
  Where-Object LocalPort -eq $port
$listeners | Select-Object LocalAddress,LocalPort,OwningProcess
$listeners.OwningProcess | Sort-Object -Unique | ForEach-Object {
  Get-Process -Id $_ -ErrorAction Continue |
    Select-Object Id,ProcessName,StartTime
}
12

10. Observer un démarrage en attente et le délai configuré

Exécutez cette lecture une seconde fois pendant une tentative déjà autorisée pour comparer CheckPoint et WaitHint, exprimé en millisecondes. Ils dépendent des états publiés par le service. Un délai dépassé ne prouve pas que Windows doit attendre plus longtemps : une base inaccessible ou un blocage peut être la cause. Une valeur ServicesPipeTimeout absente ne doit pas être interprétée comme zéro.

PowerShell — collecte en lecture seule
sc.exe query $serviceName
Get-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControl\Control' |
  Select-Object ServicesPipeTimeout
13

Interpréter les résultats ensemble

Un même code peut avoir plusieurs causes. Exemple fictif : ContosoAgent échoue après un changement de compte. Le binaire est présent, le port est libre et le journal mentionne un refus d’ouverture de session. L’export montre que le groupe du compte figure dans le droit de refus. Cette corrélation justifie une revue de la GPO; elle ne justifie pas de passer le service en LocalSystem.

ConstatHypothèse à confirmerProchaine vérification
Erreur 1069 / ouverture de sessionIdentité, secret ou droit de connexionCompte et groupes, stratégie effective, journaux AD
Erreur 1068 / dépendanceService requis indisponibleDépendances et leur propre erreur
Erreur 1053 / délaiInitialisation lente ou bloquéeChronologie, journaux du produit, accès aux ressources
Erreur 2 / fichier introuvableChemin ou composant manquantBinaire, DLL, configuration et version attendue
Processus créé puis terminéÉchec applicatifApplication Error, journaux et documentation éditeur
14

Valider une correction pilote et préparer le retour arrière

Microsoft documente ServicesPipeTimeout comme contournement de certains démarrages lents. Ce paramètre est global et sa modification peut exiger un redémarrage : ne l’augmentez pas par défaut. Ne désactivez pas antivirus, pare-feu ou contrôle d’accès pour faire disparaître le symptôme.

  • Conserver configuration, identité du service, ACL ou GPO concernée, version applicative et événements avant intervention.
  • Faire approuver une correction unique liée aux preuves : droit précis, chemin, compte ou configuration éditeur. Prévoir une fenêtre si le service traite des données ou a des dépendants.
  • Valider dans un environnement pilote lorsque possible. Un démarrage manuel de test est une opération distincte à autoriser; aucune commande de démarrage n’est automatisée ici.
  • Confirmer l’état Running puis une transaction métier réelle, les dépendances, l’absence de nouvelle erreur et la stabilité pendant une période représentative.
  • Revenir à la configuration documentée si le test échoue. Pour un secret de compte, coordonner la récupération avec tous les services consommateurs : ne réutilisez pas aveuglément un ancien mot de passe.
15

Conserver un dossier de diagnostic exploitable

Documentez : service et serveur, heure, symptômes, commandes exécutées, erreurs de collecte, hypothèse, preuve, propriétaire, correction proposée et test de réussite. Si les journaux ne couvrent plus l’incident, indiquez cette lacune; n’en déduisez pas que rien ne s’est produit.

Pour des blocages intermittents, une trace ou un dump peut être nécessaire avec l’éditeur. Ces opérations ont un coût et peuvent capturer des secrets; elles demandent un périmètre et un stockage appropriés. L’accompagnement infrastructure permet de relier compte de service, GPO, réseau et application. Ces dix vérifications ne remplacent pas un audit complet.