Batch: errorlevel for sc stop <service> is inconsistent

shootbox
shootbox used Ask the Experts™
on
Hi,

Part of my script's purpose is to stop a service remotely and then wait for this service to stop before proceeding.
It's written in the following way:

            @Echo Stopping Watchdog service...
            sc \\%%a stop Watchdog
            :waitsomemore
            timeout 5 >nul
            sc \\%%a query Watchdog | find /i "STOPPED"
            if %errorlevel%!==!0 goto :waitsomemore
            @Echo Watchdog service stopped

Whereas %%a is an IP address from a list of IPs (that part works great).

The problem I am seeing, is that depending on where I run this from / to, the errorlevel for this command:
            sc \\%%a query Watchdog | find /i "STOPPED"
Will sometimes still be 1 after the service stopped. which means it will just loop and never continue.

So narrowing down my big pain to this problem only, should the errorlevel be 1 for this line, until the "find" actually finds the "STOPPED" string and then it should return 0?

Many thanks in advance
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
First of all, the syntax of the listing above is incorrect.
%errorlevel%!==!0
will *never* be true; "0!" will never be equal to "!0"
Then the logic is incorrect, too; "find" returns errorlevel 1 if the string is NOT found.
In other words: if the watchdog service stops reliably try this:

@Echo Stopping Watchdog service... 
sc \\%%a stop Watchdog
:waitsomemore
timeout 5 >nul
sc \\%%a query Watchdog | find /i "STOPPED" 
if errorlevel 1 goto waitsomemore
@Echo Watchdog service stopped

Open in new window

Author

Commented:
Hi,

Thanks very much for the answer. unfortunately, there is something very wrong here, because this still does not work. if I add a debug line in order to print the %errorlevel% each time it loop, it's always 1...
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
What's the output of this (and which for loop is generating %%a?):
@Echo Stopping Watchdog service on %%a ...
sc \\%%a stop Watchdog
:waitsomemore
timeout 5 >nul
@echo Current state:
sc \\%%a query Watchdog
sc \\%%a query Watchdog | find /i "STOPPED" 
if errorlevel 1 goto waitsomemore
@Echo Watchdog service stopped

Open in new window

Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

Author

Commented:
hmmm, this is weird. two first runs it was stop_pending, and when it finally stopped, it looped with the RCP not available error:


Current state:

SERVICE_NAME: infoginWatchdog
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN))
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0
Current state:
[SC] OpenSCManager FAILED 1722:

The RPC server is unavailable.
Current state:
[SC] OpenSCManager FAILED 1722:

The RPC server is unavailable.
Current state:
[SC] OpenSCManager FAILED 1722:

The RPC server is unavailable.


This is the for loop, working quite well:
FOR /F "tokens=1,2 delims==" %%a IN (servers.ini) DO (

Author

Commented:
Servicename is different in my last post, same thing though
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
Well, then it seems that shutting down this "Watchdog" service on the remote machine is tearing down the RPC service with it.
This is an issue with the Watchdog software, not with the batch script. The batch script is doing what it should, it's waiting for the string "STOPPED" which never appears.
This version should at least stop trying if it finds "FAILED" as well:
@Echo Stopping Watchdog service on %%a ...
sc \\%%a stop Watchdog
:waitsomemore
timeout 5 >nul
@echo Current state:
sc \\%%a query Watchdog | findstr /i "STOPPED FAILED" 
if errorlevel 1 goto waitsomemore
@Echo Watchdog service on %%a stopped; current state:
sc \\%%a query Watchdog

Open in new window

Author

Commented:
Umm, I don't think that's the case. cause if I open a command prompt and run:
sc stop watchdog
and then sc query watchdog
I get the "STOP_PENDING" reply for 10-15 seconds and then STOPPED.

So why would only stopping it through the script cause any problems?
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
The post the *complete* script you're using.

Author

Commented:
ok, here it is, not the best written script ever but kinda works :)
 
 

@Echo OFF
setlocal enabledelayedexpansion

set SourceFolder=
set BackupFolderDate=%date%
set BackupFolderDate=%BackupFolderDate:/=_%
set BackupFolderTime=%time%
set BackupFolderTime=%BackupFolderTime::=_%
set BackupFolderName=WD_Upgrade_%BackupFolderDate%_%BackupFolderTime%
Set Installfoldername=%BackupFolderDate%_%BackupFolderTime%_WD_Upgrade
set BackupFolderName=%BackupFolderName:/=_%
set BackupFolderName=%BackupFolderName: =_%
Set Installfoldername=%Installfoldername:/=_%
Set Installfoldername=%Installfoldername: =_%


FOR /F "tokens=1,2 delims==" %%a IN (servers.ini) DO (
	IF %%a==sourcefolder (
		@ECHO Source Folder: %%b
		set SourceFolder=%%b
	) ELSE (
		IF "!SourceFolder!"=="" GOTO :sourcefoldererror
		
		Echo Starting %%a >> InstallationLog.txt
		@Echo Starting %%a...	Close the batch window in order to exit 
		
		@echo Copying the new bins from the local server to the remote server
		xcopy !SourceFolder!\* \\%%a\d$\install\!Installfoldername!\* /Y
		echo New Watchdog BINs copied to d:\install\!Installfoldername! >> InstallationLog.txt
			
		Echo Stopping watchdog service... >> InstallationLog.txt
		@echo Stopping watchdog service... 
		sc \\%%a stop watchdog
		:waitsomemore
		timeout 5 >nul
		sc \\%%a query watchdog | find /i "STOPPED" 
		if errorlevel 1 goto waitsomemore
		Echo watchdog service stopped >> InstallationLog.txt
		@Echo watchdog service stopped								
			
		@echo Copying the new bins to the working directory
		xcopy \\%%a\d$\install\!Installfoldername!\* \\%%a\d$\wd* /Y
		
		echo Starting watchdog service >> InstallationLog.txt
		@echo Starting watchdog service
		sc \\%%a start watchdog
		:waitsomemore2
		timeout 5 >nul
		sc \\%%a query watchdog | find /i "Running" >nul
		if errorlevel 1 goto waitsomemore2
		echo.
		echo ========================================================= >> InstallationLog.txt
	)
	@echo.
)

PAUSE
EXIT


:sourcefoldererror
@ECHO sourcefolder is not defined in first line of input file!
PAUSE
EXIT

Open in new window

Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
It's the "goto" in the round brackets. The brackets in batch don't have the same meaning as in a programming language, it just indicates to the parser that the following is one long line.
Try this; the watchdog service handling is now done in subroutines:
@Echo OFF
setlocal enabledelayedexpansion

set SourceFolder=
set BackupFolderDate=%date%
set BackupFolderDate=%BackupFolderDate:/=_%
set BackupFolderTime=%time%
set BackupFolderTime=%BackupFolderTime::=_%
set BackupFolderName=WD_Upgrade_%BackupFolderDate%_%BackupFolderTime%
Set Installfoldername=%BackupFolderDate%_%BackupFolderTime%_WD_Upgrade
set BackupFolderName=%BackupFolderName:/=_%
set BackupFolderName=%BackupFolderName: =_%
Set Installfoldername=%Installfoldername:/=_%
Set Installfoldername=%Installfoldername: =_%

FOR /F "tokens=1,2 delims==" %%a IN (servers.ini) DO (
	IF %%a==sourcefolder (
		ECHO Source Folder: %%b
		set SourceFolder=%%b
	) ELSE (
		IF "!SourceFolder!"=="" (
			ECHO sourcefolder is not defined in first line of input file!
			GOTO leave
		)
		Echo Starting %%a >> InstallationLog.txt
		Echo Starting %%a...	Close the batch window in order to exit 

		call :WatchdogStop

		echo Copying the new bins from the local server to the remote server
		xcopy !SourceFolder!\* \\%%a\d$\install\!Installfoldername!\* /Y
		echo New Watchdog BINs copied to d:\install\!Installfoldername! >> InstallationLog.txt
			
		echo Copying the new bins to the working directory
		xcopy \\%%a\d$\install\!Installfoldername!\* \\%%a\d$\wd* /Y
		
		call :WatchdogStart

		echo.
		echo ========================================================= >> InstallationLog.txt
	)
	echo.
)
goto leave

:WatchdogStop
Echo Stopping watchdog service... >> InstallationLog.txt
echo Stopping watchdog service... 
sc \\%1 stop watchdog
:WaitStop
	timeout 5 >nul
	sc \\%1 query watchdog | find /i "STOPPED" >nul
if errorlevel 1 goto WaitStop
Echo watchdog service stopped >> InstallationLog.txt
Echo watchdog service stopped								
goto :eof

:WatchdogStart
echo Starting watchdog service >> InstallationLog.txt
echo Starting watchdog service
sc \\%1 start watchdog
:WaitStart
	timeout 5 >nul
	sc \\%1 query watchdog | find /i "RUNNING" >nul
if errorlevel 1 goto WaitStart
Echo watchdog service started >> InstallationLog.txt
Echo watchdog service started								
goto :eof

:leave
PAUSE
EXIT

Open in new window

Author

Commented:
oBdA, why did the \\%%a turn to \\%1, is this a mistake? or did I miss something?
Most Valuable Expert 2018
Distinguished Expert 2018

Commented:
Well, that's not a mistake. With the "call :WatchDogStop", the script jumps into the batch equivalent of a subroutine. %1 in the subroutine is the first argument passed to the routine.
But there is actually a mistake in the call, I've forgot to add the argument there, sorry.
Place %%a at the end of line 28 and 37:
call :WatchdogStop %%a
...
call :WatchdogStart %%a

Author

Commented:
Perfect, many thanks!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial