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.
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.
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.
$serviceName = 'ContosoAgent' # Fictional / fictif
Get-Service -Name $serviceName -ErrorAction Stop |
Select-Object Name,DisplayName,Status,StartType2. 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.
$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,WaitHint3. 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.
$controller = Get-Service -Name $serviceName -ErrorAction Stop
$controller.ServicesDependedOn | Select-Object Name,Status
$controller.DependentServices | Select-Object Name,Status4. 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.
$since = (Get-Date).AddHours(-2)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
ProviderName = 'Service Control Manager'
StartTime = $since
} -MaxEvents 200 |
Select-Object TimeCreated,Id,LevelDisplayName,Message5. 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.
Get-WinEvent -FilterHashtable @{
LogName = 'Application'
StartTime = $since
Level = 1,2,3
} -MaxEvents 100 |
Select-Object TimeCreated,ProviderName,Id,Message6. 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.
$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,StatusMessage7. 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.
$paths = @($exePath, 'C:\ProgramData\Contoso\Agent')
foreach ($path in $paths) {
Get-Acl -LiteralPath $path -ErrorAction Stop |
Select-Object Path,Owner,AccessToString
}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.
# 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*='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.
$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
}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.
sc.exe query $serviceName
Get-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControl\Control' |
Select-Object ServicesPipeTimeoutInterpré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.
| Constat | Hypothèse à confirmer | Prochaine vérification |
|---|---|---|
| Erreur 1069 / ouverture de session | Identité, secret ou droit de connexion | Compte et groupes, stratégie effective, journaux AD |
| Erreur 1068 / dépendance | Service requis indisponible | Dépendances et leur propre erreur |
| Erreur 1053 / délai | Initialisation lente ou bloquée | Chronologie, journaux du produit, accès aux ressources |
| Erreur 2 / fichier introuvable | Chemin ou composant manquant | Binaire, DLL, configuration et version attendue |
| Processus créé puis terminé | Échec applicatif | Application Error, journaux et documentation éditeur |
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.
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.