Scott Langham
Scott Langham

Reputation: 60351

How to test whether a service is running from the command line

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.

Upvotes: 71

Views: 332429

Answers (16)

Helder Magalhães
Helder Magalhães

Reputation: 616

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

Upvotes: 1

MSBUTech
MSBUTech

Reputation: 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)

Upvotes: -1

kayleeFrye_onDeck
kayleeFrye_onDeck

Reputation: 6958

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$"

Upvotes: 1

not2qubit
not2qubit

Reputation: 16930

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.)

Upvotes: 0

Muhammad Imron
Muhammad Imron

Reputation: 49

@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

Upvotes: 4

Luis Ramos
Luis Ramos

Reputation: 21

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

Upvotes: 2

Quack
Quack

Reputation: 39

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.

Upvotes: 3

Chris Voon
Chris Voon

Reputation: 1999

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

Upvotes: 1

Scott Langham
Scott Langham

Reputation: 60351

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.

Upvotes: 2

Shahin
Shahin

Reputation: 211

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

net start | find "Service Name"

This will work everywhere...

Upvotes: 21

Mark Sowul
Mark Sowul

Reputation: 10600

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

Upvotes: 3

JGurtz
JGurtz

Reputation:

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

Upvotes: 7

NicJ
NicJ

Reputation: 4155

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
)

Upvotes: 7

joerg
joerg

Reputation:

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

Upvotes: 8

Galwegian
Galwegian

Reputation: 42247

Try

sc query state= all 

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

Upvotes: 3

Igal Serban
Igal Serban

Reputation: 10684

sc query "ServiceName" | find "RUNNING"

Upvotes: 97

Related Questions