Referenz der Befehlszeile
Jeder Befehl, jeder Schalter und jeder Exit-Code von bws, Version 0.5.0. bws --help ist die maßgebliche Quelle und ist länger - diese Seite zeigt dieselbe Oberfläche, so angeordnet, dass man sie lesen kann.
Die Befehle
Elf Befehle. snapshot ist ein Substantiv und nimmt ein Wort danach. tool ist ebenfalls ein Substantiv und listet für sich allein die Tools auf.
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
Bei einem falsch geschriebenen Befehl wird der angeboten, den Sie wahrscheinlich meinten, und der Lauf endet mit Code 2, statt etwas Ähnliches zu tun, als Sie verlangt haben.
$ bws lst
There is no command lst. Did you mean list?
Was jeder Befehl tut
list und show
list ist der ganze Rechner, eingegrenzt durch --query. show ist ein Eintrag mit allem, was darüber bekannt ist - Signatur, Privilegien, Sicherheitsdeskriptor und Speicher, alles bei jedem Aufruf gelesen, weil das bei einem einzelnen Eintrag etwa sechzig Millisekunden kostet, über den ganzen Rechner dagegen eine Sekunde. Felder, die wirklich leer sind, werden weggelassen, es sei denn, Sie übergeben --full. Ein Feld, das niemand lesen konnte, wird in jedem Fall ausgegeben, weil es wegzulassen wie eine Antwort aussähe.
stop, start und restart
Jeder baut einen Plan und führt ihn aus. --dry-run gibt den Plan aus und ändert nichts, --dependents nimmt die Dienste, die ausfallen würden, als eigene Schritte hinein, und --timeout sagt, wie lange ein Schritt ohne Fortschritt dauern darf. Treiber werden abgelehnt und nicht versucht, weil das Beenden eines Kerneltreibers ohne Neustart oft nicht umkehrbar ist.
kill - für einen Dienst, der sich nicht beenden lässt
Es bittet den Dienst, sich zu beenden, und beendet den Prozess dahinter nur, wenn das nicht klappt, sodass ein Eintrag, der von selbst anhält, nie beendet wird. Das Beenden eines Prozesses reißt jeden anderen Dienst, der in diesem Prozess lebt, mit, ob er zuvor angehalten hat oder nicht, und die Vorschau nennt sie und nennt den Prozess mit seiner Nummer. --force überspringt den höflichen Schritt, und die Vorschau zeigt dann einen Schritt statt zwei. --restart bringt danach alles zurück.
Windows schreibt diese Idee anders. --force bei Stop-Service bedeutet "auch wenn etwas davon abhängt", was hier --dependents tut. Deshalb ist dies ein eigener Befehl und kein Schalter bei stop.
start-type - eine Einstellung, kein Zug
Er sagt, was der Manager beim nächsten Start mit einem Eintrag tut, und ohne --stop bewegt er nichts: Ein Eintrag, der läuft, läuft weiter, einer, der angehalten ist, bleibt angehalten, und der Plan sagt das. disabled verdient ein Innehalten, weil es den Manager daran hindert, den Eintrag überhaupt zu starten, auch auf Anforderung für etwas anderes, das ihn braucht. delayed ist automatisch, etwas nach den anderen automatischen Einträgen gestartet - das Wort, nach dem start:delayed in einer Abfrage fragt - und Windows lehnt es für einen Eintrag in einer Ladereihenfolgegruppe ab, was der Plan sagt, bevor etwas geschieht. Jeder der vier schreibt, ob der Eintrag verzögert startet, wie es sc.exe tut. --stop, nur neben disabled, hält den Eintrag im selben Plan an, sobald die Einstellung geschrieben ist.
snapshot create und snapshot diff
create liest immer Signaturen und Hashes, weil ein Snapshot aufbewahrt und später verglichen wird und einer ohne sie gegen einen mit ihnen so verglichen würde, als hätte sich der Rechner verändert. diff sagt, was sich beim Übergang von der ersten Datei zur zweiten geändert hat, oder mit --live von einer Datei zu diesem Rechner. Die Snapshot-Seite hat das Format und die Begründung.
history - wer es geändert hat, aus dem Systemprotokoll
Änderungen des Starttyps und Installationen aus dem Systemprotokoll, die neuesten zuerst, mit dem Konto, das Windows festgehalten hat. Die erste Zeile sagt, wie weit das Protokoll zurückreicht und ob es gelöscht wurde, denn ein Verlauf ist nur so lang wie das Protokoll. Mit einem Namen sind es die Änderungen des Starttyps dieses Dienstes - Installationen werden nur ohne Namen aufgelistet, weil Windows eine Installation unter dem Anzeigenamen und nie unter dem Dienstnamen festhält. Ein Konto wird genannt, wo dieser Rechner es selbst benennen kann, und sonst als seine SID gezeigt, und Starttypen erscheinen in den Worten, die Windows geschrieben hat.
tool - fertige Antworten auf häufige Probleme
Dieselben Tools, die das Fenster auf seinem Reiter Tools zeigt. bws tool listet sie auf, und bws tool fix listet die Schnellreparaturen auf: printer, sound, indexing und search, jeweils ein Neustart eines Windows-Dienstes samt dem, was davon abhängt, ausgewählt, weil die Fehlerbehebungsseiten von Microsoft selbst ihn vorschlagen. bws tool fix printer ist genau bws restart Spooler --dependents - derselbe Plan, dieselbe Ausgabe und dieselben Exit-Codes - und wie jeder Befehl hier, der etwas ändert, fragt es nicht vorher, daher ist --dry-run der Weg, vor der Ausführung nachzusehen.
license - was in der heruntergeladenen Datei steckt
Es liest überhaupt nichts - keinen Dienstmanager, keinen Datenträger, kein Netzwerk - und antwortet aus einem Register, das in die ausführbare Datei einkompiliert ist. --components macht aus dem Hinweis jede Komponente mit Version, Lizenz und Herkunft. Dieselbe Menge, die die neben dem Download veröffentlichte Stückliste trägt, weil beide aus einem Register erzeugt werden, und der Grund, warum sich das lohnt: Das Programm ist eine eigenständige Datei, daneben gibt es also nichts, was ein Scanner lesen könnte.
Beispiele
Die folgenden Pläne wurden mit --dry-run gegen das Programm geprüft, das diese Seite beschreibt. Ein Befehl, der etwas ändert, fragt nicht vorher, daher ist --dry-run der Weg, vor der Ausführung nachzusehen. Spooler steht für irgendeinen Dienst - setzen Sie den Namen Ihres eigenen ein.
Finden und lesen
bws list jeder Dienst und Treiber auf diesem Rechner
bws list --query "start:auto !status:running" was laufen sollte und nicht läuft
bws list --query "status:running" --memory was der Prozess jedes laufenden Eintrags verbraucht
bws show Spooler alles, was über einen Eintrag bekannt ist
bws show Spooler --full auch die Felder, die wirklich leer sind
Erst ansehen, dann ändern
bws restart Spooler --dry-run der Plan und sonst nichts
bws restart Spooler --dependents zusammen mit dem neu starten, was davon abhängt
bws stop Spooler --dependents --timeout 120 zwei Minuten pro Schritt ohne Fortschritt erlauben
bws start-type WSearch delayed --dry-run etwas nach den anderen automatischen Einträgen starten
bws start-type Spooler disabled --stop deaktivieren und in einem Plan anhalten
Ein Dienst, der sich nicht beenden lässt
bws kill Spooler --dry-run der Prozess und jeder Dienst, der in ihm lebt
bws kill Spooler --restart den Prozess nur beenden, wenn ein Stopp scheitert, dann alles zurückbringen
bws kill Spooler --force --dry-run ein Schritt statt zwei: der Prozess sofort beendet
Snapshots und Drift
bws snapshot create before.json --note "before the patch" den Rechner einfrieren, mit einer Notiz in der Datei
bws snapshot diff before.json after.json zwei Dateien - zwei Tage oder zwei Rechner
bws snapshot diff before.json --live die Datei gegen diesen Rechner, wie er jetzt ist
bws snapshot diff before.json --live --exit-code dasselbe, endet mit 5, wenn die Konfiguration abgedriftet ist
Wer es geändert hat
bws history jede Änderung des Starttyps und jede Installation, die das Systemprotokoll enthält
bws history Spooler die Änderungen des Starttyps eines Dienstes
bws history --json dasselbe als Dokument, mit Protokoll und Änderungen
Schnellreparaturen
bws tool die vorhandenen Tools
bws tool fix die Schnellreparaturen und der Dienst hinter jeder
bws tool fix sound --dry-run der Plan für den Neustart der beiden Audiodienste
bws tool fix printer den Druckerspooler samt dem, was davon abhängt, neu starten
Was in der Datei steckt
bws license --components jede Komponente, ihre Version, ihre Lizenz und ihre Herkunft
bws --version die Version dieser ausführbaren Datei
In einem PowerShell-Skript
# die Einträge, die laufen sollten und nicht laufen, als Objekte
bws list --query "start:auto !status:running" --json | ConvertFrom-Json | Select-Object serviceName, displayName, status
# die unsignierten Dateien, in eine Tabelle
bws list --query "signed:no" --json | ConvertFrom-Json | Select-Object serviceName, binaryPath | Export-Csv unsigned.csv -NoTypeInformation
# was ein Dienst braucht
(bws show Spooler --json | ConvertFrom-Json).dependsOn
# eine nächtliche Prüfung, die nach dem Exit-Code verzweigt
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" }
}
In cmd und einer Batchdatei
rem ein zweiter Befehl nur, wenn der erste nicht sauber endete
bws restart Spooler || echo the restart did not end cleanly
rem in einer Batchdatei mit eingeschalteter verzögerter Erweiterung braucht das ! einen Zirkumflex
bws list --query "start:auto ^!status:running"
Schalter
18 davon. Die dritte Spalte nennt die Befehle, zu denen jeder gehört - ein Schalter, der an einen Befehl übergeben wird, der damit nichts anfangen kann, ist ein Fehler mit dieser Liste darin, statt einer stillschweigend ignorierten Option.
| Schalter | Was er tut | Wo er wirkt |
|---|---|---|
--query | Die Liste mit der Abfragesprache eingrenzen. | list |
--signatures | Lesen, wer jede Programmdatei signiert hat und ob Windows ihr vertraut. Über einen ganzen Rechner mehrere Sekunden, daher aus, solange nicht danach gefragt wird - und eine Abfrage zu Signaturen schaltet es von selbst ein. | list |
--memory | Lesen, was der Prozess jedes laufenden Eintrags verbraucht. Standardmäßig aus, weil es eine Messung und keine Einstellung ist: Eine Sekunde später ist sie anders. | list |
--required-by | Lesen, welche Einträge ausfallen, wenn einer angehalten wird, direkt von Windows erfragt und nicht aus dem abgeleitet, was alle angeben. Ein Aufruf pro Eintrag, daher aus, solange nicht danach gefragt wird. show und snapshot create lesen es jedes Mal. | list |
--follow-network | Das Werkzeug überhaupt über diesen Rechner hinaus greifen lassen - ein Startpfad auf der Freigabe von jemand anderem und ein Zertifikat, das dieser Rechner noch nicht hat. Aus Sicherheitsgründen standardmäßig aus: Eine nicht erreichbare Freigabe kostet einundzwanzig Sekunden und authentifiziert sich als der, der es ausgeführt hat, und ein Zertifikat zu holen ist eine Verbindung zu einem Dritten mitten in einer gewöhnlichen Auflistung. Ohne es wird eine Signatur gegen das geprüft, was hier ist, und ein Ergebnis, das durch Nichtnachsehen entstanden sein könnte, wird als ungelesen gemeldet und nicht als Urteil. | list, show, snapshot create |
--force | Bei kill den Prozess sofort beenden, ohne höflich zu fragen - die Vorschau zeigt dann einen Schritt statt zwei. Bei snapshot create einen bereits vorhandenen Snapshot ersetzen - eine Datei, die kein Snapshot ist, wird nie ersetzt. | snapshot create, kill |
--restart | Bei kill den Eintrag zurückbringen, sobald der Prozess weg ist, samt allem, was ihn teilte. | kill |
--stop | Bei start-type und nur neben disabled den Eintrag im selben Plan anhalten, sobald die Einstellung geschrieben ist. Ein Starttyp ändert den nächsten Start und jetzt nichts, daher läuft ein laufender Eintrag, der auf deaktiviert gesetzt wird, ohne ihn weiter. | start-type |
--full | Bei show auch die Felder ausgeben, die wirklich leer sind. Ein Feld, das niemand lesen konnte, wird in jedem Fall ausgegeben. | show |
--json | Dasselbe Dokument, maschinenlesbar, auf der Standardausgabe. | list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME |
--note | Wofür der Snapshot erstellt wurde, in der Datei aufbewahrt. | snapshot create |
--exit-code | Mit Code 5 enden, wenn sich die Konfiguration unterscheidet - ein Eintrag hinzugefügt oder entfernt, oder einer anders eingerichtet. Der Laufzustand allein zählt nicht. Standardmäßig aus, damit ein Skript, das nur die Unterschiede ausgegeben haben will, nicht darüber stolpert, welche zu finden. | snapshot diff |
--live | Die Datei mit diesem Rechner vergleichen, wie er jetzt ist, statt mit einer zweiten Datei. | snapshot diff |
--timing | Wie lange jeder Teil des Lesens gedauert hat, auf der Standardfehlerausgabe. | list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME |
--dry-run | Den Plan ausgeben und nichts ändern. Es ist derselbe Plan, den eine Ausführung abarbeitet - es gibt keinen zweiten Codepfad für den Ernstfall. | stop, start, restart, start-type, kill, tool fix NAME |
--dependents | Die Dienste, die ausfallen würden, als eigene Schritte in den Plan aufnehmen. | stop, restart, kill |
--timeout | Wie lange ein Schritt ohne Fortschritt dauern darf, bevor er aufgegeben wird, jedes Mal neu gezählt, wenn der Dienst Fortschritt meldet. Sechzig Sekunden, sofern Sie nichts anderes sagen. Ein Dienst, der weiter Fortschritt meldet, wird beobachtet, so lange es dauert. Das Ablaufen ist das Ende des Beobachtens und kein Fehler, und der Bericht sagt, wo der Eintrag zurückgelassen wurde. | stop, start, restart, kill, tool fix NAME |
--components | Bei license aus dem Hinweis jede Komponente in dieser ausführbaren Datei machen, mit Version, Lizenz und Herkunft. Dieselbe Menge, die die neben dem Download veröffentlichte Stückliste trägt, weil beide aus einem Register erzeugt werden. | license |
Exit-Codes
6 Enden, und jedes davon ist für ein Skript etwas anderes zu tun. Daten gehen auf die Standardausgabe und alles andere auf die Standardfehlerausgabe, sodass bws list --json | jq funktioniert und eine Warnung nie in Ihrem JSON landet.
Jedes JSON-Dokument ist reines ASCII: Ein Buchstabe außerhalb davon wird als sechszeichige Escape-Sequenz geschrieben, die jeder JSON-Leser wieder in den Buchstaben zurückverwandelt, sodass bws list --json > file.json gültiges UTF-8 ist und | ConvertFrom-Json es richtig liest, welche Codepage die Konsole auch hat. Im Text, den ein Mensch liest, wird ein Zeichen, das das Terminal bewegen statt etwas drucken würde - ein Tabulator, ein Zeilenumbruch, eine Escape-Sequenz, eine Richtungsüberschreibung - als sein Codepunkt gezeigt, <U+001B>.
-- beendet die Schalter, sodass auch ein Dienst, dessen Name mit einem Bindestrich beginnt, benannt werden kann: bws show -- -odd. Die Befehlszeilen, die Ihnen das Werkzeug reicht, sind für PowerShell geschrieben: Ein Name mit Leerzeichen kommt in doppelte Anführungszeichen, die cmd genauso liest, und ein Name, den PowerShell darin erweitern würde, wie MSSQL$SQLEXPRESS, kommt in einfache Anführungszeichen.
| Code | Bedeutung |
|---|---|
0 | Erledigt, und alles ist dort angekommen, wohin es sollte. |
1 | Das Werkzeug ist gescheitert - es konnte nicht tun, was verlangt wurde, aus einem Grund, der am Werkzeug liegt und nicht am Plan. |
2 | Die Befehlszeile war falsch. Bei einem falsch geschriebenen Befehl wird der angeboten, den Sie wahrscheinlich meinten. |
3 | Der Plan war gut, er lief, und etwas darin ist nicht dort angekommen, wohin es sollte - der Manager hat abgelehnt, oder die Sitzung hatte keine Rechte dafür. |
4 | Jemand hat den Lauf von Hand gestoppt. Ungleich null, auch wenn jeder Schritt noch ankam, damit ein Wrapper einen abgebrochenen Lauf nicht als sauber behandelt. |
5 | Ein Vergleich lief und fand die Konfiguration abgedriftet - ein Eintrag hinzugefügt oder entfernt, oder einer anders eingerichtet. Der Laufzustand allein ist keine Drift. Nur mit --exit-code, denn Drift zu finden ist wofür dieses Werkzeug da ist, und sie zu finden ist kein Fehler. |
Strg+C hat drei Stufen, und jede sagt, was die nächste kostet. Die erste hört auf, vorwärts zu gehen, und stellt trotzdem wieder her, was genommen wurde, die zweite lässt die Dinge, wie sie sind, und gibt trotzdem den Bericht aus, die dritte beendet den Prozess. Ein von Hand gestoppter Lauf endet mit 4, auch wenn jeder Schritt noch ankam.
Das Schließen des Konsolenfensters zählt als erstes Strg+C. Windows gibt einem Programm danach fünf Sekunden, und in ihnen hört dieses auf, vorwärts zu gehen, und stellt wieder her, was es heruntergefahren hat. Abmelden und Herunterfahren beenden es ohne jede Warnung, auf die es reagieren könnte, und eine abgebrochene Remotesitzung kann das auch.
In einer geplanten Aufgabe
Die Form, für die dieses Werkzeug gebaut wurde: den Rechner einfrieren, wenn er als gut bekannt ist, und dann jede Nacht fragen, ob er es noch ist.
# der Tag, an dem der Rechner in Betrieb geht
bws snapshot create C:\baselines\web01.json --note "after the build"
# jede Nacht, aus einer geplanten Aufgabe
bws snapshot diff C:\baselines\web01.json --live --exit-code --json > C:\logs\drift.json
# 0 - keine Konfigurationsdrift
# 5 - die Konfiguration ist abgedriftet, und drift.json sagt, was
# 3 - es lief und konnte nicht alles lesen, die Antwort ist also unvollständig
Das Fenster ist die andere Hälfte derselben Engine: BetterWindowsServices-win-x64.zip enthält es, und die Download-Seite sagt, was jedes Archiv ist.
Das Argument des Fensters
BetterWindowsServices.exe nimmt ein Argument, das für einen Menschen gedacht ist: --catalogue öffnet ein Entwicklerblatt, das jede Komponente des Fensters in jedem Zustand zeigt und nichts von Ihrem Rechner liest. Ein zweites, --carry, ist die Art, wie ein Fenster das, was es zeigte, an die Kopie von sich übergibt, als die es sich als Administrator neu startet. Niemand tippt es, und alles darin, was dieses Fenster nicht hätte schreiben können, wird abgelehnt.