搜索你的 Windows 服务,在每次更改前预览,并查看自昨天以来哪些内容发生了漂移
Better Windows Services 是为管理 Windows 计算机的人重新打造的 services.msc:窗口和命令行共用同一个引擎。不必再滚动浏览八百行,直接向计算机提问。在按下任何按钮之前,就能看到某项更改会做什么。还有 services.msc 从未具备的功能:把每个服务冻结到一个文件里,一周后再询问发生了什么变化。
- 免费开源,GPL-3.0
- 单个文件,或安装程序
- 查看时无需管理员权限
- 从不连接互联网
bws 命令行。程序使用英文界面:窗口会读取放在它旁边的语言文件,因此无需重新生成就能翻译。services.msc 自 Windows 2000 以来几乎没有变化
管理员每周都要在其中花上几个小时,一次次撞上同样的墙。
- 没有搜索。唯一的导航方式,是跳转到显示名称的首字母。
- 没有筛选。无法询问显示设为自动启动但没有运行的内容。
- 一次只能处理一行。重启十二个服务,就是十二次右键单击和十二次等待。
- 永远停在“Stopping...”,除了任务管理器和猜测进程之外别无出路。
- 没有历史记录。没人知道是谁、在何时把这个启动类型设成了 Disabled。
- 隐藏的数据。进程、触发器、特权、安全描述符、谁给可执行文件签了名,所有这些都需要凭记忆使用
sc.exe,或去翻注册表。 - 命令行能力不对等。
sc.exe的语法还停留在九十年代,而 Windows 自带的 Windows PowerShell 5.1 中的Get-Service不显示服务运行所用的账户,更不用说描述了。PowerShell 7 两者都显示,但需要单独安装。
其他工具各自只解决了一部分
Process Hacker 和 System Informer 展示信息丰富的列表,还能强制结束进程,但没有审计功能,也没有命令行。sc.exe 和 PsService 什么都能做,却什么也不告诉你。PowerShell 的 *-Service cmdlet 适合脚本,但比较浅。
没有任何一个工具同时提供可搜索的列表、每次更改前的预览,以及随时间推移的更改记录,而这份记录正是第一个下午过后仍把这个工具留在计算机上的理由。
完整对比窗口和命令行共用同一个引擎
提问,而不是滚动
start:auto !status:running 的意思是应该在运行却没有运行的内容。同一种语言既用于搜索框,也用于 bws list --query,输入时还会提示字段。
在任何操作发生前先展示计划
每一次停止、启动、重启和启动类型更改,都会连同被一并关闭的服务一起预览,而预览就是实际执行的内容。
告诉你哪些内容发生了漂移,以及是谁改的
bws snapshot create 把计算机冻结到文件中,bws snapshot diff 告诉你之后发生了哪些变化,把配置与仅仅是启动或停止区分开。bws history 从 System 日志中告诉你是谁更改了启动类型、谁安装了服务。窗口在 Audit... 下完成这三件事。
一键修复常见问题
Tools 选项卡和 bws tool fix 会重启无法打印的打印机、没了声音或卡住的搜索背后的服务,连同依赖它的内容,走的是与其他所有操作相同的计划。
停止停不下来的服务
先礼貌地请求,只有失败时才结束进程,并列出同在该进程中的每一个其他服务。
展示 services.msc 隐藏的内容
谁给可执行文件签了名、Windows 是否信任它、触发器、特权、安全描述符、进程及其内存。既以列的形式显示,也可以作为搜索条件。
无法读取时会明说
无法读取的字段会报告为未读取,绝不会显示为空。没有管理员权限时生成的快照,会在文件内部注明这一点。
融入脚本
每个命令都支持 --json,每种结束方式都有退出代码,当差异发现漂移时返回 5。
单个文件,离线运行
解压即用,或为整台计算机安装。无需安装 .NET,也从不连接互联网。读取不需要管理员权限。GPL-3.0。
自昨天以来发生了什么变化
快照是某一时刻的整台计算机:每个服务和驱动程序,包括它的启动类型、账户、启动路径、其文件的哈希和签名者、依赖关系、触发器、特权和安全描述符。它是每行一个字段的 JSON,所以可以放进代码仓库,git diff 也能读懂它。
$ bws snapshot diff before.json --live --exit-code
Changed (2):
Spooler Print Spooler
startType: Manual -> Automatic
status: Stopped -> Running (running state, not configuration)
wlidsvc Microsoft Account Sign-in Assistant
status: Stopped -> Running (running state, not configuration)
Added 0, removed 0, changed 2. Fields differing: 1 in configuration, 2 in running state.
- 配置与运行状态分开报告。相隔一天生成的两个快照,在恰好正在运行的内容上会有所不同,而其中几乎没有一项是漂移。值得阅读的是那一行:被更改的启动类型。
- 无法比较的内容会被列出,而不是被隐藏。某个快照从未读取过的字段,会显示为 not compared,因此一份写着没有任何变化的差异,表示的是在双方都能看到的范围内没有任何变化。
- 当配置不同时,
--exit-code以5结束,因此计划任务可以在部署时生成快照,并在计算机发生漂移的第一个夜晚通知相关人员。 - 两台计算机,两个文件。在暂存环境和生产环境各生成一个快照,然后在任何地方对比它们。
预览就是执行
每个会写入的操作都会先生成一份计划,这份计划既是预览,也是依赖服务的级联、在你按下任何按钮之前给出的拒绝、请求相同操作的命令行,以及事后的回退方法。
$ bws stop Winmgmt --dry-run --dependents
Plan: stop Winmgmt (2 steps)
1. stop vmms (would break otherwise)
2. stop Winmgmt (asked for)
Warnings:
- Stopping Winmgmt also stops one other entry: vmms
- Winmgmt starts automatically, so it will be back after the next restart.
- 去掉
--dry-run再运行,执行的就是这些步骤,顺序相同,旁边的原因也相同。真正执行时没有第二条代码路径。 - 一并关闭的内容都写在计划里。会受影响的服务各自是独立的步骤,如果某项计划会关掉计算机必需的东西,警告里会写明。
- 拒绝出现在按钮之前。驱动程序、服务管理器不接受停止请求的服务、系统保护的进程,都会在生成计划时连同原因一起被拒绝。窗口会把按钮置灰,并在旁边说明原因。
- 强制停止分两步,第二步是有条件的。
bws kill先请求服务停止,只有无效时才结束它的进程,并列出同在该进程中的每一个其他服务。
从命令行使用
与窗口相同的引擎,用于脚本、计划任务和 CI。数据输出到标准输出,其余所有内容输出到标准错误,因此 bws list --json | jq 可以正常工作,警告也绝不会混进你的 JSON。
bws list --query "start:auto !status:running" 应该在运行却没有运行的内容
bws list --query "file:missing" 可执行文件已丢失的服务
bws list --query "signed:no peruser:no" 未签名,不含按会话生成的副本
bws show Spooler 关于一个条目的所有已知信息
bws stop Winmgmt --dry-run --dependents 停止它会连带关闭什么
bws kill Spooler --dry-run 结束它的进程会连带带走什么
bws start-type Spooler manual --dry-run 把它从自动启动中移除会怎样
bws snapshot create before.json 在更改前冻结计算机
bws snapshot diff before.json --live --exit-code 此后的变化,配置有变化则返回 5
bws history Spooler 谁在何时更改了它的启动类型
bws tool fix printer --dry-run 快速修复卡住的打印机会做什么
每个命令、选项和退出代码
解压即用,或安装
Windows 10 1809 或 Windows Server 2019 及更高版本,64 位。压缩包不需要安装程序,也不向注册表写入任何内容,查看时不需要管理员权限。更改任何内容都需要提升权限的会话,两部分都会明说,而不是悄悄失败:窗口会提供 Restart as admin。
| 文件 | 说明 |
|---|---|
BetterWindowsServices-win-x64.zip | 窗口,一个自包含的可执行文件,无需安装 .NET |
bws-cli-win-x64.zip | 命令行,一个自包含的可执行文件,用于脚本和 CI |
BetterWindowsServices-win-x64.msi | 安装程序:为计算机上的每个账户安装这两个程序,窗口出现在开始菜单中,bws 加入 PATH |
可执行文件带有 Authenticode 签名,因此 Windows 会显示发布者名称,而不是警告来自未知发布者。


