69

I would like to be able to query whether or not a service is running from a windows batch file. I know I can use:

sc query "ServiceName"

but, this dumps out some text. What I really want is for it to set the errorlevel environment variable so that I can take action on that.

Do you know a simple way I can do this?

UPDATE
Thanks for the answers so far. I'm worried the solutions that parse the text may not work on non English operating systems. Does anybody know a way around this, or am I going to have to bite the bullet and write a console program to get this right.

Scott Langham
  • 58,735
  • 39
  • 131
  • 204
  • 2
    I just tested on a China locale Chinese Language Windows 7 laptop, the "sc query ..." command output are still English. – wangf Aug 31 '15 at 07:15
  • To get service state that will be easy to parse by script no matter what OS language is used I have used `WMIC Service WHERE "Name = 'SericeName'" GET Started /format:list`. It produces `State=Running` - easy to parse by regexp and always in English. – Michał Maciej Gałuszka Feb 19 '18 at 08:22

16 Answers16

95
sc query "ServiceName" | find "RUNNING"
Igal Serban
  • 10,558
  • 3
  • 35
  • 40
  • @ShaiAlon, it was powershell that it did not work. It worked on the usual command prompt (cmd.exe). – Chris Voon Aug 04 '16 at 09:00
  • 1
    It does not work on powershell because sc is an alias to Set-Content. – Chris Voon Aug 04 '16 at 09:01
  • 6
    `sc.exe query "ServiceName" | findstr RUNNING` will work within Powershell. – Chris Voon Aug 04 '16 at 09:07
  • is there a way to use regex search while looking for a particular service name? Sometimes I maynot remember exactly what the name is but I would know parts of the name.. – alpha_989 Mar 11 '18 at 18:53
  • 2
    If the task is to start a service in case it is not running, then testing for the `STOPPED` status is much safer, for the service may also be in one of the transitory states `STARTING` and `STOPPING`, when it is best left alone. – Anton Shepelev Aug 31 '18 at 16:11
19

Let's go back to the old school of batch programing on windows

net start | find "Service Name"

This will work everywhere...

RealHowTo
  • 34,977
  • 11
  • 70
  • 85
Shahin
  • 191
  • 1
  • 2
  • _errorlevel_ is 1 both when the service exists or not. So I can't use "find". (Win 7 Pro 64 bit) – Mogens Beltoft Oct 08 '14 at 06:32
  • @RealHowTo, I am running "MobaSSH", and if I open the "Services" app from Control panel, I can check that "MobaSSH" is working. Further, the command you mentioned, `net start | find "MobaSSH"` also prints out "MobaSSH", indiciating that this command works. However, if I use the `sc query "MobaSSH" | find "RUNNING"` command, it shows an error saying "EnumQueryServicesStatus: Open Service Failed 1060". Any idea why these 2 commands are showing different results? – alpha_989 Mar 11 '18 at 16:57
  • When I use default Windows services such as "Fax", both commands give similar results. Also `sc query` does work.. but its not working for "MobaSSH". is there something special about a service initiated by an external program? – alpha_989 Mar 11 '18 at 16:58
  • Isn't net start the command to start a service? The question is to check if the service is running, not start it – trees_are_great Jun 06 '19 at 10:11
  • 1
    @trees_are_great using `net start` alone will list all "started" services. – Nilpo Jun 12 '21 at 04:25
  • Will work on both cmd and ps but there one should keep the [differences between `net` and `sc`](https://superuser.com/a/315172/447380) in mind. – Veverke Jan 12 '23 at 10:05
8

if you don't mind to combine the net command with grep you can use the following script.

@echo off
net start | grep -x "Service"
if %ERRORLEVEL% == 2 goto trouble
if %ERRORLEVEL% == 1 goto stopped
if %ERRORLEVEL% == 0 goto started
echo unknown status
goto end
:trouble
echo trouble
goto end
:started
echo started
goto end
:stopped
echo stopped
goto end
:end
7

Thinking a little bit outside the box here I'm going to propose that powershell may be an answer on up-to-date XP/2003 machines and certainly on Vista/2008 and newer (instead of .bat/.cmd). Anyone who has some Perl in their background should feel at-home pretty quickly.


$serviceName = "ServiceName";
$serviceStatus = (get-service "$serviceName").Status;

if ($serviceStatus -eq "Running") {
    echo "Service is Running";
}
else {
    #Could be Stopped, Stopping, Paused, or even Starting...
    echo "Service is $serviceStatus";
}

Another way, if you have significant investment in batch is to run the PS script as a one-liner, returning an exit code.


@ECHO off
SET PS=powershell -nologo -command
%PS% "& {if((get-service SvcName).Status -eq 'Running'){exit 1}}"

ECHO.%ERRORLEVEL%

Running as a one-liner also gets around the default PS code signing policy at the expense of messiness. To put the PS commands in a .ps1 file and run like powershell myCode.ps1 you may find signing your powershell scripts is neccessary to run them in an automated way (depends on your environment). See http://www.hanselman.com/blog/SigningPowerShellScripts.aspx for details

7

You could use wmic with the /locale option

call wmic /locale:ms_409 service where (name="wsearch") get state /value | findstr State=Running
if %ErrorLevel% EQU 0 (
    echo Running
) else (
    echo Not running
)
NicJ
  • 4,070
  • 1
  • 25
  • 18
4
@ECHO OFF
REM testing at cmd : sc query "MSSQLSERVER" | findstr RUNNING
REM "MSSQLSERVER" is the name of Service for sample
sc query "MSSQLSERVER" %1 | findstr RUNNING
if %ERRORLEVEL% == 2 goto trouble
if %ERRORLEVEL% == 1 goto stopped
if %ERRORLEVEL% == 0 goto started
echo unknown status
goto end
:trouble
echo Oh noooo.. trouble mas bro
goto end
:started
echo "SQL Server (MSSQLSERVER)" is started
goto end
:stopped
echo "SQL Server (MSSQLSERVER)" is stopped
echo Starting service
net start "MSSQLSERVER"
goto end
:erro
echo Error please check your command.. mas bro 
goto end

:end
3

I would suggest WMIC Service WHERE "Name = 'SericeName'" GET Started

or WMIC Service WHERE "Name = 'ServiceName'" GET ProcessId (ProcessId will be zero if service isn't started)

You can set the error level based on whether the former returns "TRUE" or the latter returns nonzero

Mark Sowul
  • 10,244
  • 1
  • 45
  • 51
3
sc query "servicename" | findstr STATE

for example:

sc query "wuauserv" | findstr STATE

To report what the Windows update service is doing, running/paused etc.
This is also for Windows 10. Thank me later.

General Failure
  • 2,421
  • 4
  • 23
  • 49
Quack
  • 39
  • 1
2

Try

sc query state= all 

for a list of services and whether they are running or not.

Galwegian
  • 41,475
  • 16
  • 112
  • 158
2

I've found this:

  sc query "ServiceName" | findstr RUNNING  

seems to do roughly the right thing. But, I'm worried that's not generalized enough to work on non-english operating systems.

RealHowTo
  • 34,977
  • 11
  • 70
  • 85
Scott Langham
  • 58,735
  • 39
  • 131
  • 204
  • If you really need to do i18n, you should write an app which queries and sets the errorlevel. – hometoast Dec 09 '08 at 15:49
  • how to access the answer of the command `sc query "ServiceName" | findstr RUNNING` so with conditional statements i can do some processing – Prabhat Mishra Jun 13 '18 at 07:02
1

Just to add on to the list if you are using Powershell.

sc.exe query "ServiceName" | findstr RUNNING

The command below does not work because sc is an alias to Set-Content within Powershell.

sc query "ServiceName" | findstr RUNNING

find also does not work on Powershell for some reason unknown to me.

sc.exe query "ServiceName" | find RUNNING
Chris Voon
  • 1,974
  • 2
  • 18
  • 11
1
SERVICO.BAT
@echo off
echo Servico: %1
if "%1"=="" goto erro
sc query %1 | findstr RUNNING
if %ERRORLEVEL% == 2 goto trouble
if %ERRORLEVEL% == 1 goto stopped
if %ERRORLEVEL% == 0 goto started
echo unknown status
goto end
:trouble
echo trouble
goto end
:started
echo started
goto end
:stopped
echo stopped
goto end
:erro
echo sintaxe: servico NOMESERVICO
goto end

:end
thor
  • 21,418
  • 31
  • 87
  • 173
Luis Ramos
  • 11
  • 1
1

I noticed no one mentioned the use of regular expressions when using find/findstr-based Answers. That can be problematic for similarly named services.

Lets say you have two services, CDPUserSvc and CDPUserSvc_54530

If you use most of the find/findstr-based Answers here so far, you'll get false-positives for CDPUserSvc queries when only CDPUserSvc_54530 is running.

The /r and /c switches for findstr can help us handle that use-case, as well as the special character that indicates the end of the line, $

This query will only verify the running of the CDPUserSvc service and ignore CDPUserSvc_54530

sc query|findstr /r /c:"CDPUserSvc$"

kayleeFrye_onDeck
  • 6,648
  • 5
  • 69
  • 80
1

A suggested approach can be found in an answer to a related question: target very specific things which are locale-independent. In this case, for obtaining service status from sc.exe, the integer which identifies the state was found to be independent of active language and, therefore, robust.

Short example (additional details in the linked answer):

for /F "skip=3 tokens=3" %%i in ('""%windir%\system32\sc.exe" query "W32Time" 2^>nul"') do (
  if "%%i"=="4" (
    echo 'W32Time' service is running
    goto :SkipRemainingIterations
  )
)
:SkipRemainingIterations
0

Use Cygwin Bash with:

sc query "SomeService" |grep -qo RUNNING && echo "SomeService is running." || echo "SomeService is not running!"

(Make sure you have sc.exe in your PATH.)

not2qubit
  • 14,531
  • 8
  • 95
  • 135
-1

I have created one based from above but will show if the service is installed first then get whether it is running or not.

sc query "YourService" | find /i "failed" 2>&1>nul && echo.'YourService Not Installed' || (sc query "YourService"| find /i "running" 2>&1>nul && echo.Yes || echo.No)
  • Your answer is a bit hard to read and understand. Please clarify what it does, and ideally convert the code into multiple lines so it's easier to grasp. – CherryDT Nov 02 '21 at 10:29