Start with the exact failure
A stopped service may have a straightforward cause: an incorrect path, unavailable dependency, locked account, or occupied port. Rebooting can erase context without addressing the cause. This guide focuses on one service and complements the existing general Windows Server diagnostic guide.
Record the server, system service name, failure time and time zone, exact message, latest change, and business impact. The ten recipes below never start, stop, or reconfigure services. Some combine several reads to make the result interpretable.
Prerequisites and permissions
Examples target local Windows PowerShell 5.1 on Windows Server 2019, 2022, or 2025. Windows cmdlets are also available in some PowerShell 7 environments, but check modules and parameters before adapting them. No paid module or additional license is required for these reads; Windows and application licensing still applies.
Start with delegated read access: service queries, CIM, relevant logs, and ACLs. Event Log Readers may suffice for authorized logs; some logs and processes require additional privileges. The secedit export requires local elevation. Access denied is a collection limitation, not evidence that a service is missing.
Replace ContosoAgent and fictional paths. Run blocks in order in the same session. No secret is needed. Protect exports and redact account names, sensitive paths, and arguments before sharing evidence. For clustered workloads, follow role-specific procedures through their owner; do not start a cluster-managed service outside cluster management.
1. Confirm the service name and state
Use the system name, not just the display name. Stopped can be normal for a manual or trigger-start service. Compare with the vendor's expected behavior.
$serviceName = 'ContosoAgent' # Fictional / fictif
Get-Service -Name $serviceName -ErrorAction Stop |
Select-Object Name,DisplayName,Status,StartType2. Read the account, executable path, and exit codes
StartName identifies the configured account; it does not prove its password or rights are valid. PathName can contain sensitive arguments: redact them before sharing. ServiceSpecificExitCode is meaningful when ExitCode is 1066; consult the product documentation.
$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. Inspect declared dependencies
ServicesDependedOn lists required services; DependentServices lists downstream services. A stopped dependency is a lead. This list may omit SQL, DNS, certificates, shares, or APIs used by the application.
$controller = Get-Service -Name $serviceName -ErrorAction Stop
$controller.ServicesDependedOn | Select-Object Name,Status
$controller.DependentServices | Select-Object Name,Status4. Correlate Service Control Manager events
Collect around the exact failure time. The full message matters more than the ID: 7000 can cover multiple causes, 7001 a dependency, and 7038 a logon problem. The 200-event limit can truncate a busy period; narrow the window or carefully increase the limit.
$since = (Get-Date).AddHours(-2)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
ProviderName = 'Service Control Manager'
StartTime = $since
} -MaxEvents 200 |
Select-Object TimeCreated,Id,LevelDisplayName,Message5. Look for an application error at the same time
A service may launch and exit immediately. Look for the product error, .NET Runtime, or Application Error, then correlate process, faulting module, and timestamp. A nearby error alone does not prove causality. Product-specific logs may live elsewhere.
Get-WinEvent -FilterHashtable @{
LogName = 'Application'
StartTime = $since
Level = 1,2,3
} -MaxEvents 100 |
Select-Object TimeCreated,ProviderName,Id,Message6. Inspect the binary without executing it
Copy only the executable path from PathName; do not split blindly on spaces or execute that string. For an svchost-hosted service, inspecting the host is insufficient: identify the actual component through role documentation. An absent signature does not prove malware, and a valid signature does not guarantee correct operation.
$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. Read permissions on required files and folders
Inspect the binary, configuration, data, and logs. Displayed ACLs do not calculate the service account's effective rights: groups, explicit denies, SMB share permissions, and network identity also matter. Reading a file as your administrator account does not test service access. Do not grant Everyone Full Control to bypass a denial.
$paths = @($exePath, 'C:\ProgramData\Contoso\Agent')
foreach ($path in $paths) {
Get-Acl -LiteralPath $path -ErrorAction Stop |
Select-Object Path,Owner,AccessToString
}8. Check the log-on-as-a-service right
This export writes a diagnostic file without changing policy. It requires elevation and a protected folder. Compare SeServiceLogonRight and SeDenyServiceLogonRight with the account and group SIDs: deny takes precedence. For AD accounts, also check lockout, expiry, and dependencies; for a gMSA, check hosts authorized to retrieve its password without manually resetting it.
# 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. Identify an occupied TCP port
Replace 8443 with the application's configured port. A listener on the same port is not necessarily a conflict: local address, IPv4/IPv6, and port sharing affect the result. The PID may disappear between reads. This command checks neither UDP nor HTTP.sys reservations; do not automatically stop the identified process.
$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. Observe a pending start and configured timeout
Repeat this read during an already approved start attempt to compare CheckPoint and WaitHint, expressed in milliseconds. They depend on status reported by the service. A timeout does not prove Windows should wait longer: an unreachable database or a deadlock may be responsible. A missing ServicesPipeTimeout value must not be interpreted as zero.
sc.exe query $serviceName
Get-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControl\Control' |
Select-Object ServicesPipeTimeoutInterpret the findings together
One code can have several causes. Fictional example: ContosoAgent fails after an account change. The binary exists, the port is free, and the log reports a service-logon denial. The policy export lists the account's group in the deny right. Together, these findings justify reviewing the GPO; they do not justify changing the service to LocalSystem.
| Finding | Hypothesis to confirm | Next check |
|---|---|---|
| Error 1069 / logon failure | Identity, secret, or logon right | Account and groups, effective policy, AD logs |
| Error 1068 / dependency | Required service unavailable | Dependencies and their own errors |
| Error 1053 / timeout | Slow or blocked initialization | Timeline, product logs, resource access |
| Error 2 / file not found | Missing path or component | Binary, DLL, configuration, expected version |
| Process created then exits | Application failure | Application Error, product logs and documentation |
Validate a pilot correction and prepare rollback
Microsoft documents ServicesPipeTimeout as a workaround for certain slow starts. It is global and changing it may require a reboot; do not increase it by default. Do not disable antivirus, firewall, or access controls to hide the symptom.
- Capture configuration, service identity, relevant ACL or GPO, application version, and events before intervention.
- Approve one evidence-based correction: a specific right, path, account, or vendor setting. Schedule a window if the service handles data or has dependents.
- Validate in a pilot environment where possible. A manual test start is a separate operation requiring authorization; no start command is automated here.
- Confirm Running state and a real business transaction, dependencies, absence of new errors, and stability over a representative period.
- Restore the documented configuration if the test fails. For account secrets, coordinate recovery with every consuming service; do not blindly reuse an old password.
Keep an actionable diagnostic record
Document the service and server, time, symptoms, commands, collection errors, hypothesis, evidence, owner, proposed correction, and success test. If logs no longer cover the incident, record that gap rather than assuming nothing happened.
Intermittent hangs may require a vendor-assisted trace or dump. These operations have overhead and can capture secrets, so they need appropriate scope and storage. Infrastructure consulting connects service identity, Group Policy, network, and application findings. These ten checks do not replace a complete assessment.