系统学习 故障排查学习路径:从方法论到系统、网络、数据库与 K8s

windows-service-start-failed

Windows 服务无法启动、启动后退出或依赖失败的定位与修复。

现象

在服务控制台点击“启动”后报错,或执行 Start-Service、net start 返回失败。常见错误包括:1053 服务没有及时响应启动请求,1058 服务已被禁用,1067 进程意外终止,1068 依赖服务或组无法启动,1069 由于登录失败服务没有启动,以及 5 拒绝访问。也可能显示“正在启动”后一直不结束,或启动成功几秒后自动停止。

服务失败通常不是单一原因:SCM 只负责拉起进程,进程随后可能因为依赖服务、登录账户、文件权限、端口占用、配置错误或启动超时而退出。先拿到准确的错误码和事件日志,再检查依赖链、账户和二进制路径,比反复点“启动”有效得多。

快速定位

先取得服务的配置、状态和退出码:

$svc = 'MyService'
Get-CimInstance Win32_Service -Filter "Name='$svc'" |
  Format-List Name,DisplayName,State,StartMode,StartName,PathName,ExitCode,ServiceSpecificExitCode
sc.exe qc $svc
sc.exe queryex $svc
sc.exe qfailure $svc

sc.exe qc 的 DEPENDENCIES 是它依赖的服务,sc.exe enumdepend 则列出依赖它的服务;两者方向相反,不要看反:

sc.exe enumdepend $svc
Get-Service -Name <dependency-name> | Format-List Name,Status,StartType

查看 System 日志中的服务控制管理器事件,再用 net helpmsg 解码错误:

Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Service Control Manager'} -MaxEvents 50 |
  Format-Table TimeCreated,Id,LevelDisplayName,Message -Wrap
Get-WinEvent -LogName Application -MaxEvents 50 |
  Format-Table TimeCreated,ProviderName,Id,Message -Wrap
net helpmsg 1067
net helpmsg 1069

检查启动账户、服务登录权限和可执行文件权限:

Get-CimInstance Win32_Service -Filter "Name='$svc'" | Select-Object StartName,PathName
secedit /export /cfg $env:TEMP\secpol.cfg
Select-String -Path $env:TEMP\secpol.cfg -Pattern 'SeServiceLogonRight'
Test-Path 'C:\Program Files\App\service.exe'
icacls 'C:\Program Files\App'

域账户或群集环境还要确认机器信任关系和 Kerberos 票据:

Test-ComputerSecureChannel -Verbose
nltest /sc_verify:<domain>
klist

常见根因

  1. 依赖服务未启动、被禁用或启动失败,连带返回 1068。
  2. 服务账户密码错误、密码过期、账户锁定或 disabled,返回 1069;账户缺少“作为服务登录”权限也会失败。
  3. 可执行文件路径错误、路径含空格但未正确加引号、工作目录不存在,或文件被删除、隔离。
  4. 服务账户对程序目录、配置文件、日志目录或证书私钥没有权限,返回 5 或应用层拒绝访问。
  5. 应用自身启动失败:配置错误、数据库不可达、端口被占用、依赖的磁盘/共享不存在。
  6. 启动耗时超过 SCM 默认超时,返回 1053;常见于等待网络、许可证或数据库连接。
  7. 服务被设为禁用(1058)、注册信息损坏、被组策略或安全软件拦截,或服务被标记为删除。

修复

先按错误码处理。1068 查依赖,按依赖顺序启动;依赖服务应设为自动启动,而不是每次手工拉起:

Set-Service -Name <dependency-name> -StartupType Automatic
Start-Service -Name <dependency-name>

1069 检查登录账户。修改服务账户密码优先用服务控制台;在 PowerShell 中必须写 sc.exe,因为 sc 是 Set-Content 的别名,直接写 sc config 会改错对象:

sc.exe config $svc obj= "DOMAIN\svc" password= "新密码"

命令行会留下密码痕迹,也可能进入脚本历史;生产环境更推荐服务控制台、托管服务账户或 gMSA。内置账户(LocalSystem、LocalService、NetworkService)不使用普通密码,gMSA 的密码由域控管理,不应手动设置。若账户正确但仍报 1069,检查本地安全策略中的“作为服务登录”,域环境应通过 GPO 下发,而不是在单机上反复改:

secpol.msc

1067 或启动后立刻停止,通常要看应用日志和退出码。确认路径与权限后再启动;路径含空格时必须用引号包住可执行文件,并注意 binPath= 后有空格:

sc.exe config $svc binPath= '"C:\Program Files\App\service.exe" --config "C:\ProgramData\App\config.ini"'
icacls 'C:\ProgramData\App' /grant 'DOMAIN\svc:(OI)(CI)M'

授权遵循最小权限:只给服务真正需要的目录读写,不要直接授予整个盘或管理员组。若服务使用证书,在证书管理单元中给服务账户授予私钥读取权限。若应用监听固定端口,启动前确认没有冲突:

Get-NetTCPConnection -State Listen | Where-Object LocalPort -eq 8080
netstat -ano | findstr :8080

1053 表示进程没有在规定时间内向 SCM 报告已启动。先查应用日志、配置、数据库和网络依赖,确认不是卡在初始化;把 ServicesPipeTimeout 调大只能暂时掩盖问题,且会拖慢真正的故障发现,修改后需要重启。1058 则把启动类型改回自动或手动后再启动。

服务被标记为删除时,先关闭服务控制台和占用该服务的程序,再重试;仍不行则重启。只有确认服务无法修复时才删除并重装,删除前记录 PathName、StartName 和依赖关系:

sc.exe delete $svc

该命令不可逆,且不会清理程序文件、注册表配置或数据。恢复选项可用 sc.exe qfailure 查看,常见配置是失败后延迟重启;不要给会反复崩溃的服务配置无限快速重启,以免形成重启风暴。最后用 Get-Service 确认状态,并检查应用日志不再出现新的错误。

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. 错误码 1068、1069、1053 分别优先检查什么?
  2. 为什么在 PowerShell 中修改服务配置要写 sc.exe 而不是 sc?
  3. 服务账户启动失败时,除了密码,还要检查哪两类权限?
答案
  1. 1068 查依赖服务是否启动、是否被禁用;1069 查登录账户的密码、锁定状态和“作为服务登录”权限;1053 查应用初始化是否卡在配置、数据库、网络或许可证等待上,超时只是结果。
  2. PowerShell 中 sc 是 Set-Content 的别名,执行 sc config ... 会把它当成写文件,而不是调用服务控制工具。必须使用 sc.exe 才能得到预期行为。
  3. 一是账户的登录权限,即本地安全策略或 GPO 中的 SeServiceLogonRight;二是服务账户对程序目录、配置文件、日志目录以及证书私钥的文件系统权限。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令