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
andkeyword because there is nothing else it could mean. - The same field written twice is the one exception:
status:running status:stoppedmeans either, because that is what ticking two filters writes. Two bounds on a number still narrow -pid:>1000 pid:<2000is the range between them. !in front of a term negates it:!status:running. In a batch file withsetlocal 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:spoolmatches anything containing it - the default, because it is what people expect from a search box.name:=spooleris 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 isnone- there is genuinely no value - the entry has none?- the tool could not read this field, or has not read it, which is a questionservices.msccannot 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
| Query | What it finds |
|---|---|
status:stopPending, | Stuck on stopping or starting - the wait the snap-in shows and never ends. |
start:auto status:stopped trigger:none | Set to start automatically, stopped, and not waiting for a trigger - the short list worth reading after a restart. |
start:delayed | Automatic, started a little after the other automatic entries. |
start:manual, | Running although nothing starts it at boot - something asked for it, a trigger started it, or somebody did. |
Accounts
| Query | What it finds |
|---|---|
account:localsystem !publisher:microsoft | Running 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, | Services 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
| Query | What it finds |
|---|---|
signed:notSigned, | No signature, a chain Windows does not trust, or a file changed after it was signed. |
signed:trusted !publisher:microsoft | Signed, trusted, and not by Microsoft - the software other companies put on this machine. |
type:driver start:boot, | Drivers loaded while Windows starts whose signature Windows does not trust. On a healthy machine, none. |
!path:C:\Windows type:ownProcess | A 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:ownProcess | A 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
| Query | What it finds |
|---|---|
trigger:device status:stopped | Waiting for a device to arrive, so stopped for a reason. |
trigger:network | Started when a request arrives at a network endpoint - a port, a named pipe or an RPC interface. |
trigger:stop | Entries a trigger can stop, not only start. |
dependson:Winmgmt | Entries that need WMI to run. |
requiredby:Spooler | Everything the Print Spooler needs to run, and what those need in turn. |
Privileges and processes
| Query | What it finds |
|---|---|
privilege:SeTcbPrivilege | Asks to act as part of the operating system. |
privilege:SeImpersonatePrivilege !account:localsystem | Can act on a client's behalf while running under an account other than LocalSystem. |
sidtype:unrestricted | Carries 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:running | Running inside a shared svchost, together with others. |
memory:>200MB | A process using more than 200 MB. Memory is read by itself when a query asks about it. |
pid:1000-2000 | In a process whose id is between 1000 and 2000. |
Names and text
| Query | What it finds |
|---|---|
spool | A bare word, searched in the name, the display name, the account and the launch path. |
name:=wuauserv | Exactly 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:none | No 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:template | The 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.
| Field | Asks about | Values |
|---|---|---|
name | the service name, the one Windows identifies it by | text |
display | the display name, as this Windows spells it | text |
description | what the entry says about itself | text |
type | what kind of entry it is | driver, kernelDriver, fileSystemDriver, ownProcess, sharedProcess, unknown |
peruser | whether it is one of the per-user families Windows makes a copy of per session | yes, no, template, instance |
status | what it is doing right now | running, stopped, paused, pending, startPending, stopPending, pausePending, continuePending, unknown |
start | what the manager does with it at the next boot | automatic, auto, delayed, manual, disabled, boot, system, unknown |
account | the account it runs as, as the manager spells it | text, e.g. localsystem |
pid | the process it is running in | a number: 1234, >1000, 100-200 |
trigger | a condition that starts or stops it | device, ip, domain, firewall, policy, network, custom, state, aggregate, unknown, start, stop |
path | the command line the manager launches | text |
file | whether the file it runs is on disk | present, missing |
signed | what Windows thinks of the file's signature, without checking revocation | yes, no, trusted, notSigned, untrustedRoot, expired, revoked, tampered, unknown |
publisher | who signed the file - proven only by a trusted signature | text |
privilege | a privilege the entry asks for | text, e.g. SeDebugPrivilege |
dependson | what this one needs | a service name |
requiredby | what breaks if this one stops | a service name |
sidtype | the service SID type | unrestricted, restricted, unknown |
sddl | the security descriptor, as text | text |
memory | what its process is using | a size with a unit: 500MB, >1GB, 100MB-1GB |
mismatch | configuration and state that disagree | stopped, 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.