直接用Restart-Service -ComputerName行不通,必须通过Invoke-Command封装Stop-Service/Start-Service并推送到启用WinRM的远程主机执行,同时确保服务名准确、账号有管理员权限、TrustedHosts配置正确。
直接用 restart-service -computername 是行不通的——powershell 的这个参数只支持本地服务管理,远程调用会静默失败或报错“access is denied”。真正可靠的做法是通过 powershell 远程会话(winrm)把操作推到目标机器上执行。
先确保远程通道通了
目标服务器必须已启用 WinRM,并且你能从本地连过去:
- 在目标机上以管理员身份运行:
Enable-PSRemoting -Force或winrm quickconfig - 检查 WinRM 是否监听:运行
winrm enumerate winrm/config/listener,看到类似http://+:5985表示正常 - 防火墙要放行 TCP 5985(HTTP)或 5986(HTTPS)端口
- 如果是工作组环境,本地需配置可信主机:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.1.100,server02" -Force - 执行脚本的账户必须在远程机上有本地管理员权限(或至少对目标服务有启动/停止权限)
服务名必须准确,不是显示名
PowerShell 识别服务只认注册表里的 Name,不是你在“服务”管理器里看到的中文或英文显示名。比如:
- IIS 的服务名是
w3svc,不是 “World Wide Web Publishing Service” - 打印服务是
spooler,不是 “Print Spooler” - DHCP 客户端是
dhcp,不是 “DHCP Client”
不确定时,先查真实名称:Invoke-Command -ComputerName Server01 -ScriptBlock { Get-Service | Where-Object {$_.DisplayName -match "web"} | Select-Object Name, DisplayName }
用 Invoke-Command 批量重启最稳妥
别用循环调 Restart-Service -ComputerName,它不支持并发、不报错、难调试。正确写法是把“停+启”逻辑封装进脚本块,用 Invoke-Command 推过去执行:
- 推荐先停再启,比直接
Restart-Service更可控:Stop-Service -Name w3svc -Force; Start-Service -Name w3svc - 加
-ErrorAction Stop和try/catch捕获具体失败原因(如服务不存在、依赖项未启动) - 并发数别太大,用
-ThrottleLimit 5防止 WinRM 资源耗尽 - 完整示例:
Invoke-Command -ComputerName Server01,Server02 -ScriptBlock { Stop-Service w3svc -Force -ErrorAction Stop; Start-Service w3svc -ErrorAction Stop } -ThrottleLimit 5
如果只想授权重启特定服务,考虑 JEA
给普通运维人员开放远程重启权限时,不建议直接给管理员账号。可用 Just Enough Administration(JEA)配置受限终结点:
- 只允许用户运行
Restart-Service,且仅限w3svc、spooler等白名单服务 - 用户用自己账号连接,但实际以虚拟临时账户执行,凭据不会留在远程机上
- 避免权限泛滥,也降低横向渗透风险


















