Referencia de la línea de comandos
Cada comando, cada opción y cada código de salida de bws, versión 0.5.0. bws --help es la referencia autorizada y es más larga: esta página es la misma superficie, dispuesta para leerse.
Los comandos
Once comandos. snapshot es un sustantivo y admite una palabra después. tool también lo es y, por sí solo, lista las herramientas.
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
A un comando mal escrito se le ofrece el que probablemente quería, y la ejecución termina con el código 2 en lugar de hacer algo parecido a lo que pidió.
$ bws lst
There is no command lst. Did you mean list?
Qué hace cada comando
list y show
list es todo el equipo, acotado por --query. show es una entrada con todo lo que se sabe de ella: la firma, los privilegios, el descriptor de seguridad y la memoria, todo leído cada vez, porque sobre una sola entrada eso cuesta unos sesenta milisegundos mientras que sobre todo el equipo cuesta un segundo. Los campos realmente vacíos se omiten salvo que pase --full. Un campo que nadie pudo leer se imprime en cualquier caso, porque omitirlo parecería una respuesta.
stop, start y restart
Cada uno construye un plan y lo ejecuta. --dry-run imprime el plan y no cambia nada, --dependents pone en él los servicios que dejarían de funcionar como pasos propios, y --timeout dice cuánto puede durar un paso sin progreso. Los controladores se rechazan en lugar de intentarse, porque detener un controlador del núcleo a menudo no es reversible sin reiniciar.
kill: para un servicio que no se detiene
Pide al servicio que se detenga y termina el proceso que hay detrás solo si eso no funciona, de modo que una entrada que se detiene por sí sola nunca se termina. Terminar un proceso se lleva consigo a todo otro servicio que vive en él, se hubiera detenido antes o no, y la vista previa los nombra y nombra el proceso por su número. --force omite el paso cortés y la vista previa muestra entonces un paso en lugar de dos. --restart lo devuelve todo a su sitio después.
Windows escribe esta idea de otra manera. --force en Stop-Service significa "aunque algo dependa de él", que es lo que aquí hace --dependents. Por eso este es un comando propio y no una opción de stop.
start-type: un ajuste, no un movimiento
Dice qué hará el administrador con una entrada en el próximo arranque, y sin --stop no mueve nada: una entrada que se está ejecutando sigue ejecutándose, una detenida sigue detenida, y el plan lo dice. disabled es el que merece una pausa, porque impide que el administrador inicie la entrada en absoluto, incluso a petición de otra cosa que la necesite. delayed es automático, iniciado un poco después de las demás entradas automáticas (la palabra por la que pregunta start:delayed en una consulta), y Windows lo rechaza para una entrada de un grupo de orden de carga, lo que el plan dice antes de que ocurra nada. Cada uno de los cuatro escribe si la entrada se inicia tarde, como hace sc.exe. --stop, solo junto a disabled, detiene la entrada en el mismo plan una vez escrito el ajuste.
snapshot create y snapshot diff
create lee siempre las firmas y los hashes, porque una instantánea se conserva y se compara más tarde, y una sin ellos comparada con una que los tiene se trataría como si el equipo hubiera cambiado. diff dice qué cambió al pasar del primer archivo al segundo, o de un archivo a este equipo con --live. La página de instantáneas tiene el formato y el razonamiento.
history: quién lo cambió, a partir del registro del sistema
Cambios de tipo de inicio e instalaciones del registro del sistema, los más recientes primero, con la cuenta que registró Windows. La primera línea dice hasta dónde llega el registro y si se borró, porque un historial es tan largo como el registro. Con un nombre son los cambios de tipo de inicio de ese servicio: las instalaciones se listan solo sin nombre, porque Windows registra una instalación bajo el nombre para mostrar y nunca bajo el nombre del servicio. Una cuenta se nombra donde este equipo puede nombrarla por sí mismo y se muestra como su SID en caso contrario, y los tipos de inicio vienen con las palabras que escribió Windows.
tool: respuestas ya hechas a problemas comunes
Las mismas herramientas que la ventana muestra en su pestaña Tools. bws tool las lista y bws tool fix lista las reparaciones rápidas: printer, sound, indexing y search, cada una un reinicio de un servicio de Windows junto con lo que depende de él, elegidas porque las propias páginas de solución de problemas de Microsoft lo sugieren. bws tool fix printer es exactamente bws restart Spooler --dependents: el mismo plan, la misma salida y los mismos códigos de salida, y como todo comando aquí que cambia algo no pregunta antes, así que --dry-run es la forma de mirar antes de que se ejecute.
license: qué hay dentro del archivo que descargó
No lee nada en absoluto (ni administrador de servicios, ni disco, ni red) y responde desde un registro compilado en el ejecutable. --components convierte el aviso en cada componente con su versión, su licencia y su procedencia. El mismo conjunto que lleva la lista de materiales publicada junto a la descarga, porque ambos se generan desde un único registro, y la razón por la que merece la pena: el programa es un archivo autónomo, así que no hay nada a su lado que un escáner pueda leer.
Ejemplos
Los planes de abajo se comprobaron con --dry-run contra el programa que describe esta página. Un comando que cambia algo no pregunta antes, así que --dry-run es la forma de mirar antes de que se ejecute. Spooler representa cualquier servicio: ponga en su lugar el nombre del suyo.
Buscar y leer
bws list cada servicio y controlador de este equipo
bws list --query "start:auto !status:running" lo que debería estar en marcha y no lo está
bws list --query "status:running" --memory lo que usa el proceso de cada entrada en ejecución
bws show Spooler todo lo que se sabe de una entrada
bws show Spooler --full también los campos realmente vacíos
Mirar primero, cambiar después
bws restart Spooler --dry-run el plan, y nada más
bws restart Spooler --dependents reiniciarlo junto con lo que depende de él
bws stop Spooler --dependents --timeout 120 permitir dos minutos por paso sin progreso
bws start-type WSearch delayed --dry-run iniciarlo un poco después de las demás entradas automáticas
bws start-type Spooler disabled --stop deshabilitarlo y detenerlo en un solo plan
Un servicio que no se detiene
bws kill Spooler --dry-run el proceso, y cada servicio que vive en él
bws kill Spooler --restart terminar el proceso solo si falla una detención, y luego devolverlo todo a su sitio
bws kill Spooler --force --dry-run un paso en lugar de dos: el proceso terminado de inmediato
Instantáneas y deriva
bws snapshot create before.json --note "before the patch" congelar el equipo, con una nota guardada dentro
bws snapshot diff before.json after.json dos archivos: dos días, o dos equipos
bws snapshot diff before.json --live el archivo frente a este equipo tal como está ahora
bws snapshot diff before.json --live --exit-code lo mismo, terminando con 5 si la configuración se desvió
Quién lo cambió
bws history cada cambio de tipo de inicio e instalación que contiene el registro del sistema
bws history Spooler los cambios de tipo de inicio de un servicio
bws history --json lo mismo como documento, con registro y cambios
Reparaciones rápidas
bws tool las herramientas que hay
bws tool fix las reparaciones rápidas, y el servicio que hay detrás de cada una
bws tool fix sound --dry-run el plan para reiniciar los dos servicios de audio
bws tool fix printer reiniciar el Print Spooler con lo que depende de él
Qué hay dentro del archivo
bws license --components cada componente, su versión, su licencia y su procedencia
bws --version la versión de este ejecutable
En un script de PowerShell
# las entradas que deberían estar en marcha y no lo están, como objetos
bws list --query "start:auto !status:running" --json | ConvertFrom-Json | Select-Object serviceName, displayName, status
# los archivos sin firmar, a una hoja de cálculo
bws list --query "signed:no" --json | ConvertFrom-Json | Select-Object serviceName, binaryPath | Export-Csv unsigned.csv -NoTypeInformation
# lo que necesita un servicio
(bws show Spooler --json | ConvertFrom-Json).dependsOn
# una comprobación nocturna que se bifurca según el código de salida
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" }
}
En cmd y en un archivo por lotes
rem un segundo comando solo cuando el primero no terminó limpiamente
bws restart Spooler || echo the restart did not end cleanly
rem en un archivo por lotes con la expansión retardada activada, el ! necesita un acento circunflejo
bws list --query "start:auto ^!status:running"
Opciones
18 en total. La tercera columna son los comandos a los que pertenece cada una: una opción pasada a un comando que no la usa es un error con esa lista dentro, en lugar de un indicador ignorado en silencio.
| Opción | Qué hace | Dónde actúa |
|---|---|---|
--query | Acotar el listado con el lenguaje de consulta. | list |
--signatures | Leer quién firmó cada ejecutable y si Windows confía en él. Varios segundos en todo un equipo, así que está desactivado salvo que se pida, y una consulta sobre firmas lo activa por sí sola. | list |
--memory | Leer lo que usa el proceso de cada entrada en ejecución. Desactivado por defecto porque es una medición y no un ajuste: un segundo después es distinta. | list |
--required-by | Leer qué entradas dejan de funcionar si una se detiene, preguntado directamente a Windows en lugar de deducido de lo que declara cada una. Una llamada por entrada, así que está desactivado salvo que se pida. show y snapshot create lo leen siempre. | list |
--follow-network | Dejar que la herramienta salga de este equipo, sea como sea: una ruta de lanzamiento que vive en el recurso compartido de otra persona, y un certificado que este equipo aún no tiene. Desactivado por defecto por seguridad: un recurso compartido inalcanzable cuesta veintiún segundos y se autentica como quien lo ejecutó, y obtener un certificado es una conexión con un tercero en medio de un listado corriente. Sin él, una firma se comprueba contra lo que hay aquí, y un resultado que pudo deberse a no mirar se informa como no leído y no como un veredicto. | list, show, snapshot create |
--force | En kill, terminar el proceso de inmediato sin pedirlo con cortesía: la vista previa muestra entonces un paso en lugar de dos. En snapshot create, sustituir una instantánea que ya existe; un archivo que no es una instantánea nunca se sustituye. | snapshot create, kill |
--restart | En kill, devolver la entrada a su sitio una vez desaparecido el proceso, junto con todo lo que lo compartía. | kill |
--stop | En start-type, y solo junto a disabled, detener la entrada en el mismo plan una vez escrito el ajuste. Un tipo de inicio cambia el próximo arranque y nada ahora, así que sin esta opción una entrada en ejecución configurada como deshabilitada sigue ejecutándose. | start-type |
--full | En show, imprimir también los campos realmente vacíos. Un campo que nadie pudo leer se imprime en cualquier caso. | show |
--json | El mismo documento, legible por máquina, por la salida estándar. | list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME |
--note | Para qué se tomó la instantánea, guardado dentro del archivo. | snapshot create |
--exit-code | Terminar con el código 5 cuando la configuración difiere: una entrada añadida o eliminada, o una configurada de otro modo. El estado de ejecución por sí solo no cuenta. Desactivado por defecto, para que un script que solo quiere imprimir las diferencias no tropiece por encontrar alguna. | snapshot diff |
--live | Comparar el archivo con este equipo tal como está ahora, en lugar de con un segundo archivo. | snapshot diff |
--timing | Cuánto tardó cada parte de la lectura, por el error estándar. | list, show, stop, start, restart, start-type, snapshot create, snapshot diff, kill, history, tool fix NAME |
--dry-run | Imprimir el plan y no cambiar nada. Es el mismo plan que ejecuta una ejecución: no hay un segundo camino de código para la ejecución real. | stop, start, restart, start-type, kill, tool fix NAME |
--dependents | Poner en el plan, como pasos propios, los servicios que dejarían de funcionar. | stop, restart, kill |
--timeout | Cuánto puede durar un paso sin progreso antes de abandonarlo, contado de nuevo cada vez que el servicio informa de progreso. Sesenta segundos salvo que diga otra cosa. Un servicio que sigue informando de progreso se vigila todo el tiempo que haga falta. Agotarse es el final de la vigilancia y no un fallo, y el informe dice dónde quedó la entrada. | stop, start, restart, kill, tool fix NAME |
--components | En license, convertir el aviso en cada componente de este ejecutable con su versión, su licencia y su procedencia. El mismo conjunto que lleva la lista de materiales publicada junto a la descarga, porque ambos se generan desde un único registro. | license |
Códigos de salida
6 finales, y cada uno es algo distinto que un script debe hacer. Los datos van a la salida estándar y todo lo demás al error estándar, de modo que bws list --json | jq funciona y una advertencia nunca acaba en su JSON.
Todo documento JSON es ASCII puro: una letra fuera de él se escribe como una secuencia de escape de seis caracteres que todo lector de JSON vuelve a convertir en la letra, de modo que bws list --json > file.json es UTF-8 válido y | ConvertFrom-Json lo lee bien sea cual sea la página de códigos de la consola. En el texto que lee una persona, un carácter que movería el terminal en lugar de imprimirse (un tabulador, un salto de línea, una secuencia de escape, una anulación de dirección) se muestra como su punto de código, <U+001B>.
-- termina las opciones, de modo que un servicio cuyo nombre empieza por un guion aún puede nombrarse: bws show -- -odd. Las líneas de comandos que la herramienta le entrega están escritas para PowerShell: un nombre con espacio va entre comillas dobles, que cmd lee igual, y un nombre que PowerShell expandiría dentro, como MSSQL$SQLEXPRESS, va entre comillas simples.
| Código | Significado |
|---|---|
0 | Hecho, y todo llegó adonde iba. |
1 | La herramienta falló: no pudo hacer lo que se le pidió, por una razón que tiene que ver con la herramienta y no con el plan. |
2 | La línea de comandos era incorrecta. A un comando mal escrito se le ofrece el que probablemente quería. |
3 | El plan era bueno, se ejecutó, y algo de él no llegó adonde iba: el administrador rechazó, o la sesión no tenía derechos sobre ello. |
4 | Alguien detuvo la ejecución a mano. Distinto de cero aunque cada paso hubiera llegado, para que un script envolvente no trate una ejecución interrumpida como limpia. |
5 | Se ejecutó una comparación y encontró la configuración desviada: una entrada añadida o eliminada, o una configurada de otro modo. El estado de ejecución por sí solo no es deriva. Solo con --exit-code, porque encontrar deriva es para lo que sirve esta herramienta, y encontrarla no es un fallo. |
Ctrl+C tiene tres niveles, y cada uno dice lo que cuesta el siguiente. El primero deja de avanzar y aun así devuelve lo que se había tomado, el segundo deja las cosas como están y aun así imprime el informe, el tercero termina el proceso. Una ejecución detenida a mano termina con 4 aunque cada paso hubiera llegado.
Cerrar la ventana de la consola cuenta como el primer Ctrl+C. Windows concede cinco segundos a un programa después de eso, y en ellos este deja de avanzar y devuelve lo que había derribado. Cerrar sesión y apagar lo terminan sin ningún aviso al que pudiera reaccionar, y una sesión remota interrumpida puede hacer lo mismo.
En una tarea programada
La forma para la que se construyó esta herramienta: congelar el equipo cuando se sabe que está bien, y preguntar cada noche si lo sigue estando.
# el día en que el equipo entra en servicio
bws snapshot create C:\baselines\web01.json --note "after the build"
# cada noche, desde una tarea programada
bws snapshot diff C:\baselines\web01.json --live --exit-code --json > C:\logs\drift.json
# 0 - sin deriva de configuración
# 5 - la configuración se desvió, y drift.json dice en qué
# 3 - se ejecutó y no pudo leerlo todo, así que la respuesta es parcial
La ventana es la otra mitad del mismo motor: BetterWindowsServices-win-x64.zip la contiene, y la página de descarga dice qué es cada archivo.
El argumento de la ventana
BetterWindowsServices.exe admite un argumento pensado para una persona: --catalogue abre una hoja de desarrollador que muestra cada componente de la ventana en cada estado y no lee nada de su equipo. Un segundo, --carry, es la forma en que una ventana entrega lo que mostraba a la copia de sí misma que reinicia como administrador. Nadie lo escribe, y se rechaza todo lo que contenga que esa ventana no pudiera haber escrito.