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.
This question is related to
windows
batch-file
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
)
Let's go back to the old school of batch programing on windows
net start | find "Service Name"
This will work everywhere...
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
Try
sc query state= all
for a list of services and whether they are running or not.
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$"
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.)
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.
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$"
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.
Try
sc query state= all
for a list of services and whether they are running or not.
Let's go back to the old school of batch programing on windows
net start | find "Service Name"
This will work everywhere...
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
Try
sc query state= all
for a list of services and whether they are running or not.
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.
@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
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
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
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.
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
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
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.
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
)
@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
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.)
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
)
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
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
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
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
Source: Stackoverflow.com