Referenz

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.

SchalterWas er tutWo er wirkt
--queryDie Liste mit der Abfragesprache eingrenzen.list
--signaturesLesen, 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
--memoryLesen, 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-byLesen, 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-networkDas 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
--forceBei 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
--restartBei kill den Eintrag zurückbringen, sobald der Prozess weg ist, samt allem, was ihn teilte.kill
--stopBei 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
--fullBei show auch die Felder ausgeben, die wirklich leer sind. Ein Feld, das niemand lesen konnte, wird in jedem Fall ausgegeben.show
--jsonDasselbe Dokument, maschinenlesbar, auf der Standardausgabe.list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME
--noteWofür der Snapshot erstellt wurde, in der Datei aufbewahrt.snapshot create
--exit-codeMit 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
--liveDie Datei mit diesem Rechner vergleichen, wie er jetzt ist, statt mit einer zweiten Datei.snapshot diff
--timingWie 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-runDen 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
--dependentsDie Dienste, die ausfallen würden, als eigene Schritte in den Plan aufnehmen.stop, restart, kill
--timeoutWie 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
--componentsBei 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.

CodeBedeutung
0Erledigt, und alles ist dort angekommen, wohin es sollte.
1Das Werkzeug ist gescheitert - es konnte nicht tun, was verlangt wurde, aus einem Grund, der am Werkzeug liegt und nicht am Plan.
2Die Befehlszeile war falsch. Bei einem falsch geschriebenen Befehl wird der angeboten, den Sie wahrscheinlich meinten.
3Der 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.
4Jemand hat den Lauf von Hand gestoppt. Ungleich null, auch wenn jeder Schritt noch ankam, damit ein Wrapper einen abgebrochenen Lauf nicht als sauber behandelt.
5Ein 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.