sc.exe, Get-Service, and this
Both are already on the machine, and both will stay useful. This page is about where they stop - and it says plainly where they are still the better answer.
Where each one stops
sc.exe
It can reach almost everything the service control manager knows, and it tells you nothing about how to ask. The syntax is from the nineties - sc config X start= auto, where the space after the equals sign is mandatory and its absence is a silent failure to do what you meant.
It answers about one entry at a time. There is no filtering, no output a script can parse without writing a parser, and no preview: sc stop either works or returns a number.
Get-Service and the *-Service cmdlets
Proper objects, a pipeline, and a shallow view. In Windows PowerShell 5.1, the one that comes with Windows, Get-Service does not show the account a service runs as or its description. PowerShell 7 shows both, and the launch path too, and it is installed separately.
Stop-Service -Force means "even if something depends on it" - it stops the dependents, and it tells you afterwards rather than before.
The same questions, three ways
| Question | With what is on the machine | Here |
|---|---|---|
| What should be running and is not | Get-Service | Where-Object { $_.StartType -eq 'Automatic' -and $_.Status -ne 'Running' } |
bws list --query "start:auto !status:running" |
| Which services have an unsigned binary | Read each launch path, resolve it, call Get-AuthenticodeSignature on each - a script, not a command |
bws list --query "signed:no" |
| What would stopping this take down | sc enumdepend X, then read the list and decide yourself |
bws stop X --dry-run --dependents, which is the plan that would run |
| What changed since last week | Nothing, unless you wrote the collector yourself | bws snapshot diff before.json --live |
| Who changed the start type, and when | Get-WinEvent -FilterHashtable @{ LogName = 'System'; Id = 7040 }, then read the message of each event |
bws history Spooler, whose first line says how far back the log reaches |
| Machine-readable output | Objects from PowerShell, text from sc.exe |
--json on every command, on standard output, with warnings on standard error |
Where this tool disagrees with sc.exe about a service, that is a bug here. Part of the test suite runs both against the machine it is on and compares them entry by entry, and a difference between the two is the single most useful thing to put in an issue.
When to keep using what you have
- You are on a machine you will touch once. Both are already there and nothing has to get past a policy.
- You need to change the account, the launch path, or recovery actions.
sc.exedoes all three. This tool shows the account and the launch path and changes neither, and reads recovery actions only to warn before it ends a process. - You need to create or delete a service.
sc createandsc delete. Not here, on purpose. - You are already deep in a PowerShell pipeline.
bws list --jsoncomes back as objects throughConvertFrom-Json, so it joins the pipeline rather than replacing it.
Together, rather than instead
The tool that answers what is wrong with this machine and the tools that change one setting are not the same tool. Ask the question here, read the plan here, and use whatever you like to carry it out - the plan prints the command line that asks for the same thing, and that line is meant to be copied.