How to check if a service is running via batch file and start it, if it is not running?
WindowsWindows ServicesBatch FileScheduled TasksWindows Problem Overview
I want to write a batch file that performs the following operations:
- Check if a service is running
- If is it running, quit the batch
- If it is not running, start the service
The code samples I googled so far turned out not to be working, so I decided not to post them.
Starting a service is done by:
net start "SERVICENAME"
- How can I check if a service is running, and how to make an if statement in a batchfile?
- I'm a bit confused. What is the argument I have to pass onto the net start? The service name or its display name?
Windows Solutions
Solution 1 - Windows
To check a service's state, use sc query <SERVICE_NAME>
. For if blocks in batch files, https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/if">check the documentation.
The following code will check the status of the service MyServiceName
and start it if it is not running (the if block will be executed if the service is not running):
for /F "tokens=3 delims=: " %%H in ('sc query "MyServiceName" ^| findstr " STATE"') do (
if /I "%%H" NEQ "RUNNING" (
REM Put your code you want to execute here
REM For example, the following line
net start "MyServiceName"
)
)
Explanation of what it does:
- Queries the properties of the service.
- Looks for the line containing the text "STATE"
- Tokenizes that line, and pulls out the 3rd token, which is the one containing the state of the service.
- Tests the resulting state against the string "RUNNING"
As for your second question, the argument you will want to pass to net start
is the service name, not the display name.
Solution 2 - Windows
To toggle a service use the following;
> NET START "Distributed Transaction > Coordinator" ||NET STOP "Distributed > Transaction Coordinator"
Solution 3 - Windows
You can use the following command to see if a service is running or not:
sc query [ServiceName] | findstr /i "STATE"
When I run it for my NOD32 Antivirus, I get:
STATE : 4 RUNNING
If it was stopped, I would get:
STATE : 1 STOPPED
You can use this in a variable to then determine whether you use NET START or not.
The service name should be the service name, not the display name.
Solution 4 - Windows
That should do it:
FOR %%a IN (%Svcs%) DO (SC query %%a | FIND /i "RUNNING"
IF ERRORLEVEL 1 SC start %%a)
Solution 5 - Windows
Language independent version.
@Echo Off
Set ServiceName=Jenkins
SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
echo %ServiceName% not running
echo Start %ServiceName%
Net start "%ServiceName%">nul||(
Echo "%ServiceName%" wont start
exit /b 1
)
echo "%ServiceName%" started
exit /b 0
)||(
echo "%ServiceName%" working
exit /b 0
)
Solution 6 - Windows
I just found this thread and wanted to add to the discussion if the person doesn't want to use a batch file to restart services. In Windows there is an option if you go to Services, service properties, then recovery. Here you can set parameters for the service. Like to restart the service if the service stops. Also, you can even have a second fail attempt do something different as in restart the computer.
Solution 7 - Windows
Cuando se use Windows en Español, el código debe quedar asi (when using Windows in Spanish, code is):
for /F "tokens=3 delims=: " %%H in ('sc query MYSERVICE ^| findstr " ESTADO"') do (
if /I "%%H" NEQ "RUNNING" (
REM Put your code you want to execute here
REM For example, the following line
net start MYSERVICE
)
)
Reemplazar MYSERVICE con el nombre del servicio que se desea procesar. Puedes ver el nombre del servicio viendo las propiedades del servicio. (Replace MYSERVICE with the name of the service to be processed. You can see the name of the service on service properties.)
Solution 8 - Windows
For Windows server 2012 below is what worked for me. Replace only "SERVICENAME" with actual service name:
@ECHO OFF
SET SvcName=SERVICENAME
SC QUERYEX "%SvcName%" | FIND "STATE" | FIND /v "RUNNING" > NUL && (
ECHO %SvcName% is not running
ECHO START %SvcName%
NET START "%SvcName%" > NUL || (
ECHO "%SvcName%" wont start
EXIT /B 1
)
ECHO "%SvcName%" is started
EXIT /B 0
) || (
ECHO "%SvcName%" is running
EXIT /B 0
)
Solution 9 - Windows
@echo off
color 1F
@sc query >%COMPUTERNAME%_START.TXT
find /I "AcPrfMgrSvc" %COMPUTERNAME%_START.TXT >nul
IF ERRORLEVEL 0 EXIT
IF ERRORLEVEL 1 NET START "AcPrfMgrSvc"
Solution 10 - Windows
I also wanted an email sent if the service was started this way so added a bit to @Ic code just thought I would post it in case it helped anyone. I used SendMail but there are other command line options https://stackoverflow.com/questions/9038926/how-to-send-a-simple-email-from-a-windows-batch-file
set service=MyServiceName
for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr " STATE"') do (
if /I "%%H" NEQ "RUNNING" (
net start %service%
for /F "tokens=3 delims=: " %%H in ('sc query %service% ^| findstr " STATE"') do (
if /I "%%H" EQ "RUNNING" (
SendMail /smtpserver localhost /to me@mydomain.com /from watchdog@mydomain.com /subject Service Autostart Notification /body Autostart on service %service% succeded.
) else (
SendMail /smtpserver localhost /to me@mydomain.com /from watchdog@mydomain.com /subject Service Autostart Notification /body Autostart on service %service% failed.
)
)
)
)
Solution 11 - Windows
Starting Service using Powershell script. You can link this to task scheduler and trigger it at intervals or as needed. Create this as a PS1 file i.e. file with extension PS1 and then let this file be triggered from task scheduler.
To start stop service
in task scheduler if you are using it on server use this in arguments
-noprofile -executionpolicy bypass -file "C:\Service Restart Scripts\StopService.PS1"
verify by running the same on cmd if it works it should work on task scheduler also
$Password = "Enter_Your_Password"
$UserAccount = "Enter_Your_AccountInfor"
$MachineName = "Enter_Your_Machine_Name"
$ServiceList = @("test.SocketService","test.WcfServices","testDesktopService","testService")
$PasswordSecure = $Password | ConvertTo-SecureString -AsPlainText -Force
$Credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $UserAccount, $PasswordSecure
$LogStartTime = Get-Date -Format "MM-dd-yyyy hh:mm:ss tt"
$FileDateTimeStamp = Get-Date -Format "MM-dd-yyyy_hh"
$LogFileName = "C:\Users\krakhil\Desktop\Powershell\Logs\StartService_$FileDateTimeStamp.txt"
#code to start the service
"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"###################### STARTING SERVICE ##########################" >> $LogFileName
for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName
Write-Output "`n####################################"
Write-Output "Starting Service - " $ServiceList[$i]
"$LogStartTime => Starting Service: $ServiceName" >> $LogFileName
Start-Service $ServiceList[$i]
$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}
if($ServiceState.Status -eq "Running")
{
"$LogStartTime => Started Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Started Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`n Service didn't Start. Current State is - "
Write-Host $ServiceState.Status
}
}
#code to stop the service
"`n####################################################################" > $LogFileName
"####################################################################" >> $LogFileName
"###################### STOPPING SERVICE ##########################" >> $LogFileName
for($i=0;$i -le 3; $i++)
{
"`n`n" >> $LogFileName
$ServiceName = $ServiceList[$i]
"$LogStartTime => Service Name: $ServiceName" >> $LogFileName
Write-Output "`n####################################"
Write-Output "Stopping Service - " $ServiceList[$i]
"$LogStartTime => Stopping Service: $ServiceName" >> $LogFileName
Stop-Service $ServiceList[$i]
$ServiceState = Get-Service | Where-Object {$_.Name -eq $ServiceList[$i]}
if($ServiceState.Status -eq "Stopped")
{
"$LogStartTime => Stopped Service Successfully: $ServiceName" >> $LogFileName
Write-Host "`n Service " $ServiceList[$i] " Stopped Successfully"
}
else
{
"$LogStartTime => Unable to Stop Service: $ServiceName" >> $LogFileName
Write-Output "`nService didn't Stop. Current State is - "
Write-Host $ServiceState.Status
}
}
Solution 12 - Windows
@Echo off
Set ServiceName=wampapache64
SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
echo %ServiceName% not running
echo
Net start "%ServiceName%"
SC queryex "%ServiceName%"|Find "STATE"|Find /v "RUNNING">Nul&&(
Echo "%ServiceName%" wont start
)
echo "%ServiceName%" started
)||(
echo "%ServiceName%" was working and stopping
echo
Net stop "%ServiceName%"
)
pause
Solution 13 - Windows
Related with the answer by @DanielSerrano, I've been recently bit by localization of the sc.exe
command, namely in Spanish. My proposal is to pin-point the line and token which holds numerical service state and interpret it, which should be much more robust:
@echo off
rem TODO: change to the desired service name
set TARGET_SERVICE=w32time
set SERVICE_STATE=
rem Surgically target third line, as some locales (such as Spanish) translated the utility's output
for /F "skip=3 tokens=3" %%i in ('""%windir%\system32\sc.exe" query "%TARGET_SERVICE%" 2>nul"') do (
if not defined SERVICE_STATE set SERVICE_STATE=%%i
)
rem Process result
if not defined SERVICE_STATE (
echo ERROR: could not obtain service state!
) else (
rem NOTE: values correspond to "SERVICE_STATUS.dwCurrentState"
rem https://msdn.microsoft.com/en-us/library/windows/desktop/ms685996(v=vs.85).aspx
if not %SERVICE_STATE%==4 (
echo WARNING: service is not running
rem TODO: perform desired operation
rem net start "%TARGET_SERVICE%"
) else (
echo INFORMATION: service is running
)
)
Tested with:
- Windows XP (32-bit) English
- Windows 10 (32-bit) Spanish
- Windows 10 (64-bit) English
Solution 14 - Windows
Maybe a much simpler way? Just adding to the list of answers here:
@for /f "tokens=1,* delims=: " %%a in ('sc queryex state=Inactive') do net start "%%b"