The query language

Ask the machine a question

One language, in the search box of the window and in bws list --query. A bare word searches the name, the display name, the account and the launch path. A field narrows it. 21 fields, and the same text means the same thing in both halves of the tool.

Six that answer a real question

What should be up and is not

start:auto !status:running

The first query most people write, and the one services.msc cannot answer at all.

Services whose file is gone

file:missing

An entry pointing at a binary that is not on disk. Usually an uninstall that left the registration behind.

Unsigned, without the session noise

signed:no peruser:no

The per-user families make a copy per session and fill a list with near-duplicates. This asks about the rest.

Running although disabled

mismatch:running

Configuration and state that disagree - an entry the manager is set never to start, running anyway.

Anything asking for debug rights

privilege:SeDebugPrivilege

A privilege that lets a process open any other one. Worth knowing which services ask for it.

What the tool could not read

account:?

The entries where this session could not read the account. A question services.msc cannot even ask.

How a query is written

Terms

  • Terms are separated by spaces and all of them must match - there is no and keyword because there is nothing else it could mean.
  • The same field written twice is the one exception: status:running status:stopped means either, because that is what ticking two filters writes. Two bounds on a number still narrow - pid:>1000 pid:<2000 is the range between them.
  • ! in front of a term negates it: !status:running. In a batch file with setlocal EnableDelayedExpansion, cmd eats that ! without a word and the query quietly means something else - write ^! inside the quotes there.
  • A comma inside a field is or: start:manual,disabled.
  • Quotes protect anything with spaces or colons: account:"NT SERVICE\McmSvc".
  • A path pasted as it is - C:\Windows\System32\svchost.exe - is searched for, not read as a field called C.

How text is matched

  • name:spool matches anything containing it - the default, because it is what people expect from a search box.
  • name:=spooler is exact.
  • name:spool* takes wildcards, * and ?.
  • name:/^Sql.*/ is a regular expression, and inside the slashes it is written the way regular expressions are: \?, \\ and a comma mean what they mean there. A slash that never closes is an error - to search for the slash itself, write \/ or use quotes.
  • Case is ignored, including outside ASCII - a display name in Polish or Greek matches whichever way it is typed.

Three words every field accepts

  • any - there is a value, whatever it is
  • none - there is genuinely no value - the entry has none
  • ? - the tool could not read this field, or has not read it, which is a question services.msc cannot even ask

A mistyped value is an error, never an empty result. status:runing answers Did you mean running? and ends with code 2. An empty list would look like an answer, and the difference between "nothing matches" and "you typed it wrong" is the difference between a machine that is clean and an audit that proved nothing. A query that would narrow nothing is refused on the command line too, so a script does not operate on the whole machine because of a typo.

More examples

Each one works the same in the search box of the window and after bws list --query, and each was run on a real Windows before it was written here. What it finds depends on the machine - and for a question about trouble, an empty answer is the one you want.

State and start type

QueryWhat it finds
status:stopPending,startPendingStuck on stopping or starting - the wait the snap-in shows and never ends.
start:auto status:stopped trigger:noneSet to start automatically, stopped, and not waiting for a trigger - the short list worth reading after a restart.
start:delayedAutomatic, started a little after the other automatic entries.
start:manual,disabled status:runningRunning although nothing starts it at boot - something asked for it, a trigger started it, or somebody did.

Accounts

QueryWhat it finds
account:localsystem !publisher:microsoftRunning as LocalSystem, the strongest account, from a file Microsoft did not sign. A query about the publisher reads signatures by itself, so it takes a few seconds.
!account:localsystem,localservice,networkservice type:ownProcess,sharedProcessServices running under any other account - a virtual one, a managed one or a person's own.
account:"NT SERVICE"A virtual account of the service's own. The quotes keep the words together, because of the space.

Files and signatures

QueryWhat it finds
signed:notSigned,untrustedRoot,tamperedNo signature, a chain Windows does not trust, or a file changed after it was signed.
signed:trusted !publisher:microsoftSigned, trusted, and not by Microsoft - the software other companies put on this machine.
type:driver start:boot,system !signed:trustedDrivers loaded while Windows starts whose signature Windows does not trust. On a healthy machine, none.
!path:C:\Windows type:ownProcessA service with a process of its own whose file lives outside the Windows folder.
path:\AppData\Launched from inside somebody's profile, the last place a service is expected.
path:\System32\\ type:ownProcessA backslash in front of a space makes the space part of the word, so a path ending in a backslash is written with two when another term follows it. At the end of the query one is enough.

Triggers and dependencies

QueryWhat it finds
trigger:device status:stoppedWaiting for a device to arrive, so stopped for a reason.
trigger:networkStarted when a request arrives at a network endpoint - a port, a named pipe or an RPC interface.
trigger:stopEntries a trigger can stop, not only start.
dependson:WinmgmtEntries that need WMI to run.
requiredby:SpoolerEverything the Print Spooler needs to run, and what those need in turn.

Privileges and processes

QueryWhat it finds
privilege:SeTcbPrivilegeAsks to act as part of the operating system.
privilege:SeImpersonatePrivilege !account:localsystemCan act on a client's behalf while running under an account other than LocalSystem.
sidtype:unrestrictedCarries a service SID of its own in its process, so permissions can name it alone. sidtype:restricted asks for the ones whose process is write-restricted as well.
type:sharedProcess status:runningRunning inside a shared svchost, together with others.
memory:>200MBA process using more than 200 MB. Memory is read by itself when a query asks about it.
pid:1000-2000In a process whose id is between 1000 and 2000.

Names and text

QueryWhat it finds
spoolA bare word, searched in the name, the display name, the account and the launch path.
name:=wuauservExactly this name, and nothing that merely contains it.
name:win*Names that start with win, written with a wildcard.
name:/svc$/Names that end in svc, written as a regular expression.
description:noneNo description at all, which is most drivers.
description:?A description Windows could not hand over, usually because it points at a language file that is not there.
peruser:templateThe per-user templates Windows copies for each signed-in session.

Every field

Built from the program itself, so this table cannot drift from what the tool accepts. A field with no list of values takes text, a number or a size - the third column says which.

FieldAsks aboutValues
namethe service name, the one Windows identifies it bytext
displaythe display name, as this Windows spells ittext
descriptionwhat the entry says about itselftext
typewhat kind of entry it isdriver, kernelDriver, fileSystemDriver, ownProcess, sharedProcess, unknown
peruserwhether it is one of the per-user families Windows makes a copy of per sessionyes, no, template, instance
statuswhat it is doing right nowrunning, stopped, paused, pending, startPending, stopPending, pausePending, continuePending, unknown
startwhat the manager does with it at the next bootautomatic, auto, delayed, manual, disabled, boot, system, unknown
accountthe account it runs as, as the manager spells ittext, e.g. localsystem
pidthe process it is running ina number: 1234, >1000, 100-200
triggera condition that starts or stops itdevice, ip, domain, firewall, policy, network, custom, state, aggregate, unknown, start, stop
paththe command line the manager launchestext
filewhether the file it runs is on diskpresent, missing
signedwhat Windows thinks of the file's signature, without checking revocationyes, no, trusted, notSigned, untrustedRoot, expired, revoked, tampered, unknown
publisherwho signed the file - proven only by a trusted signaturetext
privilegea privilege the entry asks fortext, e.g. SeDebugPrivilege
dependsonwhat this one needsa service name
requiredbywhat breaks if this one stopsa service name
sidtypethe service SID typeunrestricted, restricted, unknown
sddlthe security descriptor, as texttext
memorywhat its process is usinga size with a unit: 500MB, >1GB, 100MB-1GB
mismatchconfiguration and state that disagreestopped, running

Two things worth knowing

Some fields are expensive, and asking for them turns the reading on

Signatures take several seconds over a whole machine and memory is a measurement rather than a setting, so neither is read for a listing unless asked. A query that mentions one turns that reading on by itself - you do not have to remember --signatures as well as signed:no. In the window, a query about signatures says the answer is incomplete until they arrive, rather than showing a shorter list as though it were the answer.

A result judged on something unreadable says so

If entries were judged on a field this session could not read, the result carries a line saying how many - because such a result may be missing entries, or holding ones that do not belong. That is the same rule the whole tool keeps: an unsuccessful read is visible in the answer, never swallowed. A publisher gets the same treatment when only the certificate claims it: beside any verdict other than trusted the name is shown as not verified, and publisher: counts the entry as unsure in a line of its own - so !publisher:microsoft keeps a Microsoft file somebody changed after it was signed.

The command line reference