搜尋你的 Windows 服務,在每次變更前預覽,並查看自昨天以來哪些內容發生了漂移

Better Windows Services 是為管理 Windows 電腦的人重新打造的 services.msc:視窗和命令列共用同一個引擎。不必再捲動瀏覽八百列,直接向電腦提問。在按下任何按鈕之前,就能看到某項變更會做什麼。還有 services.msc 從未具備的功能:把每個服務凍結到一個檔案裡,一週後再詢問發生了什麼變化。

  • 免費開放原始碼,GPL-3.0
  • 單一檔案,或安裝程式
  • 檢視時不需要系統管理員權限
  • 從不連上網際網路
視窗中選取了五個項目,清單上方顯示啟動它們的計畫:五個步驟,一則說明其中兩個已處於該狀態,每個項目對應一行 bws start,以及 Start 5 entries 按鈕。
選取的項目、在任何動作發生之前顯示的計畫,以及要求完全相同動作的 bws 命令列。程式使用英文介面:視窗會讀取放在它旁邊的語言檔案,因此無需重新建置就能翻譯。
半分鐘體驗

實際使用是這樣的

這是在安裝了波蘭語的 Windows 上的真實工作階段:顯示名稱來自 Windows,因此是它的語言。視窗本身是英文的。

選取四個項目以及啟動它們的計畫,強制重新啟動 Local Session Manager(其計畫警告說沒有它電腦無法運作,並要求在按鈕可用之前先輸入它的名稱),空白搜尋框下方用於起步的問題,以及透過輸入名稱的一部分找到並啟動的 Print Spooler。
選取四個項目以及啟動它們的計畫、要求輸入電腦所需服務名稱的強制重新啟動、空白搜尋框下方的問題,以及透過輸入找到並啟動的 Print Spooler。
起始畫面:三張關於這台電腦的數字卡片,分別是正在執行的服務、設為自動啟動但未啟動的服務、設為自動啟動但檔案已遺失的服務,以及 Show the list 按鈕。
它從幾個關於這台電腦的數字開始。每個數字都是一個問題:按一下它,問題就會進入搜尋框。
服務清單,搜尋框上方有三個清單,搜尋框為空,篩選按鈕依狀態、啟動類型、簽章、不一致和觸發程序分列展開,下面是清單。
篩選按鈕會寫入搜尋框,所以你按下的內容就是一條可以閱讀和編輯的查詢。
為什麼需要它

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。

services.msc 從未做到的事

自昨天以來發生了什麼變化

快照是某一時刻的整台電腦:每個服務和驅動程式,包括它的啟動類型、帳戶、啟動路徑、其檔案的雜湊和簽署者、相依性、觸發程序、特殊權限和安全性描述元。它是每行一個欄位的 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 會顯示發行者名稱,而不是警告來自未知發行者。