Wiersz poleceń
Każda komenda, każdy przełącznik i każdy kod wyjścia programu bws w wersji 0.5.0. Źródłem prawdy jest bws --help i jest dłuższy - ta strona to ta sama powierzchnia, rozłożona tak, żeby dało się ją czytać. Program mówi po angielsku, więc komendy, przełączniki i jego własne komunikaty są tu w oryginale.
Komendy
Jedenaście komend. snapshot jest rzeczownikiem i wymaga słowa po sobie. tool też jest rzeczownikiem, a sam wypisuje listę narzędzi.
bws list [--query TEXT] [--signatures] [--memory] [--required-by] [--follow-network] [--json] [--timing]
bws show NAME [--full] [--follow-network] [--json] [--timing]
bws stop|start|restart NAME [--dry-run] [--dependents] [--timeout SECONDS] [--json] [--timing]
bws kill NAME [--force] [--restart] [--dry-run] [--dependents] [--timeout SECONDS] [--json] [--timing]
bws start-type NAME automatic|delayed|manual|disabled [--stop] [--dry-run] [--json] [--timing]
bws snapshot create [FILE] [--note TEXT] [--follow-network] [--force] [--json] [--timing]
bws snapshot diff EARLIER LATER [--exit-code] [--json] [--timing]
bws snapshot diff EARLIER --live [--exit-code] [--json] [--timing]
bws history [NAME] [--json] [--timing]
bws tool
bws tool fix
bws tool fix NAME [--dry-run] [--timeout SECONDS] [--json] [--timing]
bws license [--components]
bws --help
bws --version
Literówka w czasowniku dostaje podpowiedź, o który prawdopodobnie chodziło, a przebieg kończy się kodem 2, zamiast zrobić coś zbliżonego do tego, o co prosiłeś.
$ bws lst
There is no command lst. Did you mean list?
Co robi każdy czasownik
list i show
list to cała maszyna, zawężona przez --query. show to jeden wpis ze wszystkim, co o nim wiadomo - podpis, przywileje, deskryptor bezpieczeństwa i pamięć, wszystko czytane za każdym razem, bo na jednym wpisie kosztuje to około sześćdziesięciu milisekund, a na całej maszynie sekundę. Pola naprawdę puste są pomijane, chyba że podasz --full. Pole, którego nie dało się odczytać, drukuje się i tak, bo pominięcie go wyglądałoby jak odpowiedź.
stop, start i restart
Każdy buduje plan i go wykonuje. --dry-run drukuje plan i nie zmienia niczego, --dependents wstawia do niego usługi, które przestaną działać, jako osobne kroki, a --timeout mówi, jak długo jeden krok może trwać bez postępu. Sterowniki są odmawiane, a nie próbowane, bo zatrzymanie sterownika jądra często nie jest odwracalne bez restartu.
kill - dla usługi, która nie chce się zatrzymać
Prosi usługę o zatrzymanie i kończy stojący za nią proces tylko wtedy, gdy to nie zadziała, więc wpis, który zatrzymuje się sam, nigdy nie jest ubijany. Zakończenie procesu zabiera ze sobą każdą inną usługę żyjącą w tym procesie, niezależnie od tego, czy zatrzymała się wcześniej - a podgląd wymienia je po nazwie i podaje numer procesu. --force pomija uprzejmy krok, więc podgląd pokazuje jeden krok zamiast dwóch. --restart podnosi wszystko z powrotem.
Windows nazywa ten pomysł inaczej. --force w Stop-Service znaczy „nawet jeśli coś od tego zależy", czyli to, co tutaj robi --dependents. Dlatego jest to osobny czasownik, a nie przełącznik przy stop.
start-type - ustawienie, nie ruch
Mówi, co menedżer zrobi z wpisem przy następnym starcie systemu, i bez --stop nie przesuwa niczego: wpis działający dalej działa, zatrzymany dalej stoi, i plan to mówi. Nad disabled warto się zatrzymać, bo to znaczy, że menedżer nie uruchomi wpisu w ogóle - także na żądanie, dla czegoś innego, co go potrzebuje. delayed to automatyczny, uruchamiany chwilę po pozostałych automatycznych - to samo słowo, o które pyta start:delayed w zapytaniu - a Windows odmawia go wpisowi z grupy kolejności ładowania, co plan mówi, zanim cokolwiek się stanie. Każde z czterech zapisuje też, czy wpis startuje z opóźnieniem, tak jak sc.exe. --stop, wyłącznie obok disabled, zatrzymuje wpis w tym samym planie, po zapisaniu ustawienia.
snapshot create i snapshot diff
create zawsze czyta podpisy i skróty, bo snapshot jest trzymany i porównywany później, a taki bez nich porównywałby się z takim z nimi tak, jakby maszyna się zmieniła. diff mówi, co się zmieniło w drodze z pierwszego pliku do drugiego, albo z pliku do tej maszyny przy --live. Strona o snapshotach niesie format i uzasadnienie.
history - kto to zmienił, z dziennika System
Zmiany typu startu i instalacje usług z dziennika System, od najnowszej, z kontem, które zapisał Windows. Pierwsza linia mówi, jak daleko wstecz sięga dziennik i czy był czyszczony, bo historia jest tylko tak długa jak dziennik. Z nazwą to zmiany typu startu tej jednej usługi - instalacje są wymienione tylko bez nazwy, bo Windows zapisuje instalację pod nazwą wyświetlaną, nigdy pod nazwą usługi. Konto ma nazwę tam, gdzie ta maszyna nazwie je sama, a w przeciwnym razie stoi jego SID. Typy startu są w słowach, które zapisał Windows.
tool - gotowe odpowiedzi na częste problemy
Te same narzędzia, które okno pokazuje na zakładce Tools. bws tool wypisuje je, a bws tool fix wypisuje szybkie naprawy: printer, sound, indexing i search. Każda to restart jednej usługi Windows razem z tym, co od niej zależy, wybrany dlatego, że tak radzą strony pomocy Microsoftu. bws tool fix printer to dokładnie bws restart Spooler --dependents - ten sam plan, to samo wyjście i te same kody wyjścia - i jak każda komenda, która coś zmienia, nie pyta wcześniej, więc --dry-run pozwala obejrzeć plan przed wykonaniem.
license - co jest w środku pobranego pliku
Nie czyta niczego - ani menedżera usług, ani dysku, ani sieci - i odpowiada z rejestru wkompilowanego w plik wykonywalny. --components zamienia notę w pełną listę: każdy składnik z wersją, licencją i adresem źródeł. Ten sam zestaw, który niesie spis składników publikowany obok pobrania, bo oba powstają z jednego rejestru. I stąd jego wartość: program jest jednym plikiem samowystarczalnym, więc obok niego nie ma czego czytać.
Przykłady
Plany niżej sprawdzono z --dry-run na programie, który opisuje ta strona. Komenda, która coś zmienia, nie pyta wcześniej, więc --dry-run jest sposobem, żeby zajrzeć, zanim się wykona. Spooler stoi tu za dowolną usługę - wstaw w to miejsce nazwę swojej.
Szukanie i czytanie
bws list każda usługa i sterownik na tej maszynie
bws list --query "start:auto !status:running" co powinno chodzić i nie chodzi
bws list --query "status:running" --memory ile używa proces każdego działającego wpisu
bws show Spooler wszystko, co wiadomo o jednym wpisie
bws show Spooler --full także pola, które są naprawdę puste
Najpierw podgląd, potem zmiana
bws restart Spooler --dry-run sam plan i nic więcej
bws restart Spooler --dependents restart razem z tym, co od niej zależy
bws stop Spooler --dependents --timeout 120 dwie minuty na krok bez postępu
bws start-type WSearch delayed --dry-run start chwilę po innych wpisach automatycznych
bws start-type Spooler disabled --stop wyłączenie i zatrzymanie w jednym planie
Usługa, która nie chce się zatrzymać
bws kill Spooler --dry-run proces i każda usługa, która w nim mieszka
bws kill Spooler --restart proces kończony tylko wtedy, gdy zatrzymanie zawiedzie, potem powrót wszystkiego
bws kill Spooler --force --dry-run jeden krok zamiast dwóch: proces kończony od razu
Snapshoty i dryf
bws snapshot create before.json --note "before the patch" zamrożenie maszyny, z notatką zapisaną w środku
bws snapshot diff before.json after.json dwa pliki - dwa dni albo dwie maszyny
bws snapshot diff before.json --live plik wobec tej maszyny w tej chwili
bws snapshot diff before.json --live --exit-code to samo, z kodem 5, gdy konfiguracja się rozjechała
Kto to zmienił
bws history każda zmiana typu uruchomienia i instalacja z dziennika System
bws history Spooler zmiany typu uruchomienia jednej usługi
bws history --json to samo jako dokument, z log i changes
Szybkie naprawy
bws tool jakie są narzędzia
bws tool fix szybkie naprawy i usługa stojąca za każdą
bws tool fix sound --dry-run plan restartu dwóch usług dźwięku
bws tool fix printer restart bufora wydruku razem z tym, co od niego zależy
Co jest w pliku
bws license --components każdy składnik z wersją, licencją i źródłem
bws --version wersja tego pliku wykonywalnego
W skrypcie PowerShella
# wpisy, które powinny chodzić i nie chodzą, jako obiekty
bws list --query "start:auto !status:running" --json | ConvertFrom-Json | Select-Object serviceName, displayName, status
# niepodpisane pliki do arkusza
bws list --query "signed:no" --json | ConvertFrom-Json | Select-Object serviceName, binaryPath | Export-Csv unsigned.csv -NoTypeInformation
# czego potrzebuje jedna usługa
(bws show Spooler --json | ConvertFrom-Json).dependsOn
# nocne sprawdzenie, które rozgałęzia się po kodzie wyjścia
bws snapshot diff C:\baselines\web01.json --live --exit-code > $null
switch ($LASTEXITCODE) {
0 { 'no configuration drift' }
5 { 'the configuration drifted' }
default { "no clean answer, exit code $LASTEXITCODE" }
}
W cmd i pliku wsadowym
rem druga komenda tylko wtedy, gdy pierwsza nie skończyła się czysto
bws restart Spooler || echo the restart did not end cleanly
rem w pliku wsadowym z włączonym opóźnionym rozwijaniem ! potrzebuje daszka
bws list --query "start:auto ^!status:running"
Przełączniki
Jest ich 18. Trzecia kolumna to czasowniki, do których każdy należy - przełącznik podany czasownikowi, który nie ma z niego pożytku, jest błędem z tą listą w treści, a nie flagą po cichu zignorowaną.
| Przełącznik | Co robi | Gdzie działa |
|---|---|---|
--query | Zawęża listę językiem zapytań. | list |
--signatures | Czyta, kto podpisał każdy plik i czy Windows temu podpisowi ufa. Kilka sekund na całej maszynie, więc jest wyłączone, dopóki nie poprosisz - a zapytanie o podpisy włącza to samo. | list |
--memory | Czyta, ile pamięci zajmuje proces każdego działającego wpisu. Domyślnie wyłączone, bo to pomiar, a nie ustawienie: sekundę później jest inny. | list |
--required-by | Czyta, które wpisy przestaną działać po zatrzymaniu tego - pytając Windows wprost, zamiast wyliczać to z deklaracji. Jedno wywołanie na wpis, więc wyłączone, dopóki nie poprosisz. show i snapshot create czytają to zawsze. | list |
--follow-network | Pozwala programowi sięgnąć poza tę maszynę - pod ścieżkę uruchomienia leżącą na udziale innego komputera oraz po certyfikat, którego ta maszyna jeszcze nie ma. Domyślnie wyłączone dla bezpieczeństwa: jeden nieosiągalny udział kosztuje dwadzieścia jeden sekund i uwierzytelnia się jako ten, kto uruchomił program, a pobranie certyfikatu to połączenie do obcego serwera w trakcie zwykłego listowania. Bez tego podpis jest sprawdzany wobec tego, co jest na miejscu, a wynik, który mógł wziąć się z niezajrzenia, jest zgłaszany jako nieodczytany, a nie jako werdykt. | list, show, snapshot create |
--force | Przy kill kończy proces od razu, bez uprzejmego pytania - podgląd pokazuje wtedy jeden krok zamiast dwóch. Przy snapshot create zastępuje istniejący snapshot - pliku, który snapshotem nie jest, nie zastępuje nigdy. | snapshot create, kill |
--restart | Przy kill podnosi wpis z powrotem, gdy proces zniknie, razem ze wszystkim, co ten proces dzieliło. | kill |
--stop | Przy start-type, i tylko obok disabled, zatrzymuje wpis w tym samym planie, po zapisaniu ustawienia. Typ startu zmienia następny rozruch, a nie to, co dzieje się teraz, więc bez tego działający wpis ustawiony jako wyłączony dalej działa. | start-type |
--full | Przy show drukuje także pola, które są naprawdę puste. Pole, którego nie dało się odczytać, drukuje się i tak. | show |
--json | Ten sam dokument, czytelny dla maszyny, na wyjściu standardowym. | list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME |
--note | Po co snapshot został zrobiony - zapisane w środku pliku. | snapshot create |
--exit-code | Kończy kodem 5, gdy różni się konfiguracja - wpis doszedł albo zniknął, albo jest ustawiony inaczej. Sam stan pracy się nie liczy. Domyślnie wyłączone, żeby skrypt, który chce tylko zobaczyć różnice, nie wywracał się na tym, że je znalazł. | snapshot diff |
--live | Porównuje plik z tą maszyną w jej obecnym stanie, zamiast z drugim plikiem. | snapshot diff |
--timing | Ile trwała każda część odczytu, na wyjściu błędów. | list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME |
--dry-run | Drukuje plan i nie zmienia niczego. To ten sam plan, który wykonuje się przy wykonaniu - nie ma drugiej ścieżki kodu dla wersji prawdziwej. | stop, start, restart, start-type, kill, tool fix NAME |
--dependents | Wstawia do planu, jako osobne kroki, usługi, które przestaną działać. | stop, restart, kill |
--timeout | Jak długo jeden krok może trwać bez postępu, zanim narzędzie przestanie czekać - liczone od nowa za każdym razem, gdy usługa zamelduje postęp. Sześćdziesiąt sekund, o ile nie powiesz inaczej. Usługa, która melduje postęp, jest obserwowana tak długo, jak trzeba. Wyczerpanie tego czasu jest końcem patrzenia, a nie porażką - raport mówi, w jakim stanie wpis został zostawiony. | stop, start, restart, kill, tool fix NAME |
--components | Przy license zamienia notę w pełną listę: każdy składnik wewnątrz tego pliku wykonywalnego, z wersją, licencją i adresem źródeł. Ten sam zestaw, który niesie spis składników publikowany obok pobrania, bo oba powstają z jednego rejestru. | license |
Kody wyjścia
6 zakończeń, a każde z nich jest dla skryptu czymś innym. Dane idą na wyjście standardowe, a cała reszta na wyjście błędów, więc bws list --json | jq działa, a ostrzeżenie nigdy nie ląduje w JSON-ie.
Każdy dokument JSON jest czystym ASCII: litera spoza niego idzie jako sześcioznakowa ucieczka, którą każdy czytnik JSON zamienia z powrotem na literę, więc bws list --json > file.json jest poprawnym UTF-8, a | ConvertFrom-Json czyta go dobrze przy każdej stronie kodowej konsoli. W tekście dla człowieka znak, który zamiast się wydrukować przestawiłby terminal - tabulator, koniec linii, sekwencja ucieczki, zmiana kierunku tekstu - jest pokazany jako swój numer, <U+001B>.
-- kończy przełączniki, więc usługę o nazwie zaczynającej się od łącznika da się nazwać: bws show -- -odd. Polecenia, które narzędzie podaje do skopiowania, są pisane dla PowerShella: nazwa ze spacją idzie w cudzysłowie, który cmd czyta tak samo, a nazwa, którą PowerShell rozwinąłby w cudzysłowie, na przykład MSSQL$SQLEXPRESS, w apostrofach.
| Kod | Znaczenie |
|---|---|
0 | Zrobione, i wszystko dotarło tam, gdzie miało dotrzeć. |
1 | Narzędzie zawiodło - nie zrobiło tego, o co poproszono, z powodu dotyczącego samego narzędzia, a nie planu. |
2 | Wiersz poleceń był zły. Przy literówce w komendzie program podpowiada tę, o którą prawdopodobnie chodziło. |
3 | Plan był dobry, wykonał się, a coś w nim nie dotarło tam, gdzie miało - menedżer odmówił albo sesja nie miała do tego praw. |
4 | Ktoś zatrzymał przebieg ręcznie. Niezerowy nawet wtedy, gdy każdy krok i tak dotarł, żeby skrypt nadrzędny nie potraktował przerwanego przebiegu jako czystego. |
5 | Porównanie wykonało się i znalazło dryf konfiguracji - wpis doszedł albo zniknął, albo jest ustawiony inaczej. Sam stan pracy nie jest dryfem. Tylko z --exit-code, bo dryf jest tym, czego to narzędzie szuka, a znalezienie go nie jest porażką. |
Ctrl+C ma trzy poziomy, a każdy mówi, ile kosztuje następny. Pierwszy przestaje iść naprzód i nadal oddaje to, co zabrał, drugi zostawia rzeczy jak są i nadal drukuje raport, trzeci kończy proces. Przebieg zatrzymany ręcznie kończy się kodem 4 nawet wtedy, gdy każdy krok i tak dotarł.
Zamknięcie okna konsoli liczy się jak pierwsze Ctrl+C. Windows daje programowi po nim pięć sekund, a ten w tym czasie przestaje iść naprzód i oddaje to, co zabrał. Wylogowanie i zamknięcie systemu kończą go bez ostrzeżenia, na które mógłby zareagować, a zerwana sesja zdalna może tak samo.
W zadaniu harmonogramu
Kształt, pod który ten program powstał: zamroź maszynę, gdy wiadomo, że jest dobra, a potem co noc pytaj, czy nadal jest.
# w dniu, w którym maszyna wchodzi do pracy
bws snapshot create C:\baselines\web01.json --note "after the build"
# co noc, z zadania harmonogramu
bws snapshot diff C:\baselines\web01.json --live --exit-code --json > C:\logs\drift.json
# 0 - konfiguracja się nie rozjechała
# 5 - konfiguracja się rozjechała, a drift.json mówi co
# 3 - wykonało się i nie wszystko dało się odczytać, więc odpowiedź jest częściowa
Okno jest drugą połową tego samego silnika: niesie je BetterWindowsServices-win-x64.zip, a strona pobierania mówi, co jest w którym archiwum.
Argument okna
BetterWindowsServices.exe przyjmuje jeden argument przeznaczony dla człowieka: --catalogue otwiera arkusz dla programisty, pokazujący każdy komponent okna w każdym stanie, i nie czyta niczego z Twojej maszyny. Drugi, --carry, służy oknu do przekazania tego, co pokazywało, swojej kopii uruchamianej ponownie jako administrator. Nikt go nie wpisuje, a wszystko, czego tamto okno nie mogło samo zapisać, jest odrzucane.