Conditionally exit out of a FOR loop - for-loop

Cant seem to figure this one out - hope someone can provide advice
I have a batch file that has an array of servers and loops through these to stop then start a Windows service
The stop part is working fine and the array of server names and service etc is all working as expected - so I will skip that for now.
The start part is what is causing me problems
What I want to happen is:
Try to start each server's service via a for loop (I can get this working OK)
If it fails to start try 'x' more times then move onto the next server - I am trying to use a nested for loop (I think correct terminology) for this. It sort of works - but I want it to try to start the service - then check if running - if it is - break out of loop and go to next server in array - if it fails to start the service try 'x' more times then move on... I can't really seem to make this part work properly.
This is the code at present that sort of works but won't jump out of the nested loop if the service actually is started successfully. I have commented out the errorlevel check that I was trying to use to make it exit the loop if the service check did not error
rem Start service
echo 3. Starting "%service1%" Services >> %LOGPath%
for /L %%n in (0,1,1) do (
echo Starting the "%service1%" service on !server[%%n]! >> %LOGPath%
sc \\!server[%%n]! start "%service1%" > NUL
rem Wait a specified time between each check
timeout /t %StartWaitLoopDelay% /nobreak
echo Service "%service1%" status on !server[%%n]! is: >> %LOGPath%
sc \\!server[%%n]! query "%service1%" | find /I "STATE" | find "RUNNING" >> %LOGPath%
if errorlevel 1 (
for /L %%a in (1,1,2) do (
echo The "%service1%" service failed to start on !server[%%n]! - attmepting restart %%a times >> %LOGPath%
sc \\!server[%%n]! start "%service1%" > NUL
rem Wait a specified time between each check
timeout /t %StartWaitLoopDelay% /nobreak
echo Service "%service1%" status on !server[%%n]! is now: >> %LOGPath%
sc \\!server[%%n]! query "%service1%" | find /I "STATE" | find "RUNNING" >> %LOGPath%
rem if %errorlevel% EQU 0 goto ExitStartLoop
)
)
rem :ExitStartLoop
)
I have also tried the below using a Call (to another restart loop - then exit /b to try and get out of it) in the first loop if the service fails to start - also sort of works but not really - doesn't actually exit properly and prints the first loop code to output in cmd window...
rem Start service
echo 3. Starting "%service1%" Services >> %LOGPath%
for /L %%n in (0,1,1) do (
echo Starting the "%service1%" service on !server[%%n]! >> %LOGPath%
sc \\!server[%%n]! start "%service1%" > NUL
rem Wait a specified time between each check
timeout /t %StartWaitLoopDelay% /nobreak
echo Service "%service1%" status on !server[%%n]! is: >> %LOGPath%
sc \\!server[%%n]! query "%service1%" | find /I "STATE" | find "RUNNING" >> %LOGPath%
if errorlevel 1 Call :RestartLoop
)
GoTo :End
:RestartLoop
for /L %%a in (1,1,2) do (
echo The "%service1%" service failed to start on !server[%%n]! - attmepting to restart %%a times >> %LOGPath%
sc \\!server[%%n]! start "%service1%" > NUL
rem Wait a specified time between each check
timeout /t %StartWaitLoopDelay% /nobreak
echo Service "%service1%" status on !server[%%n]! is now: >> %LOGPath%
sc \\!server[%%n]! query "%service1%" | find /I "STATE" | find "RUNNING" >> %LOGPath%
if %errorlevel% EQU 0 (exit /b)
)
:End
Hope this makes sense and someone can provide some advice. I know I am using errorlevel and %errorlevel% - will clean this up if/when I can get it working correctly

I suggest you to use this method. The new lines inserted by me have an uppercase REM comment before.
rem Start service
echo 3. Starting "%service1%" Services >> %LOGPath%
for /L %%n in (0,1,1) do (
echo Starting the "%service1%" service on !server[%%n]! >> %LOGPath%
sc \\!server[%%n]! start "%service1%" > NUL
rem Wait a specified time between each check
timeout /t %StartWaitLoopDelay% /nobreak
REM Clear "error" flag
set "anyError="
echo Service "%service1%" status on !server[%%n]! is: >> %LOGPath%
sc \\!server[%%n]! query "%service1%" | find /I "STATE" | find "RUNNING" >> %LOGPath%
REM If was an error, set "error" flag
if errorlevel 1 set "anyError=true"
for /L %%a in (1,1,2) do if defined anyError (
echo The "%service1%" service failed to start on !server[%%n]! - attmepting restart %%a times >> %LOGPath%
sc \\!server[%%n]! start "%service1%" > NUL
rem Wait a specified time between each check
timeout /t %StartWaitLoopDelay% /nobreak
echo Service "%service1%" status on !server[%%n]! is now: >> %LOGPath%
sc \\!server[%%n]! query "%service1%" | find /I "STATE" | find "RUNNING" >> %LOGPath%
REM If was not an error, clear "error" flag
if not errorlevel 1 set "anyError="
)
)

Related

batch script stops after winrs command

#(setlocal enableextensions enabledelayedexpansion
echo off
set "Node1=Node1"
set "Node2=Node2"
set "Node3=Node3"
set "Cluster=Cluster1"
set LOGFILE=C:\BatchLog.log
)
CALL:Main >> %LOGFILE% 2>&1
( ENDLOCAL
CALL :END
EXIT /B 0
)
:Main
CALL :Connect_Remote "%Node3%"
CALL :Print_NodeStatus
GOTO :EOF
:Connect_Remote
start winrs -r:%~1 cmd
TIMEOUT /T 5
ECHO Login to %COMPUTERNAME%
ECHO %DATE% %TIME%
ECHO.
ECHO %DATE% %TIME%
ECHO.
GOTO :EOF
:Print_NodeStatus
ECHO ***CURRENT STATUS OF SERVERS***
cluster.exe WINCLU01 node /status
ECHO %DATE% %TIME%
ECHO.
GOTO :EOF
:Error
EXIT /B 0 %ERRORLEVEL%
GOTO :EOF
I have a batch script that needs to run on another server locally ( 4th server) but same VLAN. It needs to check if the servers (node1, node2, and node 3) in the cluster is UP and running.
I have created subclass in my script:
:Connect_Remote
and
:Print_NodeStatus
After this part is run: start winrs -r:%~1 cmd
It doesn't continue to :Print_NodeStatus
What am I missing?

Ping results in notepad

Can anyone please tell what is wrong in this code, what I am trying is to capture the date and time of link fail else, it shall report Link is working or it would be better if it shows the ping response.
#echo off
echo Internet Testing by RN Choudhury.
:loop
ping 8.8.8.8 -n 1 -w 60 > nul
if errorlevel 1 echo %date% - %time% Not connected >> InternetFail.txt else
echo Link is working
ping -n 30 127.0.0.1 > nul
goto loop
Continually output internet connection status to text file and host.
Windows 10 64-bit. Does not require admin privileges.
CMD batch script to continually output internet connection status to text file and host using ping, if/else, echo, re-direction and goto loop.
Ctrl+C to break out of loop.
#title Output internet connection status to text file and host.
#rem Windows 10 64-bit. Does not require admin privileges.
#echo off
setlocal enableextensions
cd.> InternetFail.txt
:loop
SET errorlevel=
ping -n 2 8.8.8.8 -w 60 | find "TTL=" > nul
REM ping -n 30 8.8.8.8 -w 60 | find "TTL=" > nul
if errorlevel == 1 (
(
ECHO.
ECHO %date% - %time% INTERNET DOWN
ping -n 2 8.8.8.8 -w 60
REM ping -n 30 8.8.8.8 -w 60
)>> InternetFail.txt
ECHO.
ECHO Ctrl+C to break out of loop.
ECHO.
ECHO %date% - %time% INTERNET DOWN
ping -n 2 8.8.8.8 -w 60
REM ping -n 30 8.8.8.8 -w 60
) else (
ECHO.
ECHO Ctrl+C to break out of loop.
ECHO.
ECHO %date% - %time% Link is working.
ping -n 2 127.0.0.1
REM ping -n 30 127.0.0.1
)
goto :loop
exit /b
Your if syntax is flawed:
if errorlevel 1 (echo %date% - %time% Not connected >> InternetFail.txt) else echo Link is working
or for better readabilty:
if errorlevel 1 (
echo %date% - %time% Not connected >> InternetFail.txt
) else (
echo Link is working
)
Note: ping may give false positives (Reply from <localhost>: destination not reachable technically is a response, so errorlevel will be zero.
Better use:
ping 8.8.8.8 -n 1 -w 60 | find "TTL=" > nul
Edit for additional requirements in comments:
#echo off
setlocal
set "logfile=InternetFail.txt"
set "host=8.8.8.8"
:loop
for /f "delims=" %%a in ('ping -n 1 -w 60 %host% ^|findstr /r "TTL= \.$"') do (
echo %%a|find "TTL=" >nul && (
>>"%logfile%" echo %date% %time% Link is up: %%a
echo %date% %time% Link is up: %%a
) || (
>>"%logfile%" echo %date% %time% Link is up: %%a
echo %date% %time% Link is up: %%a
)
)
timeout 30 >nul
goto :loop

Windows Service fails to start when the service is already running using windows batch script

I am writing a windows batch script that will Install a service. If its already running, then I am stopping and deleting the service and then installing the service again.
I am facing a peculiar behavior. When the service is already running, and when I am running the below batch file, the service gets installed again, but it fails to start. When I reboot the system, and start the service, it gets started.
How to solve this start service issue without rebooting computer. I also added taskkill /f /PID to kill the process libertyserver.exe.
This is my code : test.bat. I am running test.bat from command line.
test.bat:
#echo off
setlocal
#echo off
set JAVA_SERVICE_EXE=libertyserver.exe
...
....
set SERVICE_DISPLAY_NAME="%LIBERTY_SERVICE_NAME%"
set SERVICE_DESCRIPTION="%LIBERTY_SERVICE_NAME%"
echo Stopping and Deleting existing services
for /F "tokens=3 delims=: " %%H in ('sc query %SERVICE_NAME% ^| findstr "STATE" ') do (
if /I "%%H" EQU "RUNNING" (
sc stop %SERVICE_NAME% >nul 2>&1
timeout /t 30 /nobreak >nul 2>&1
)
sc delete %SERVICE_NAME% >nul 2>&1
timeout /t 30 /nobreak >nul 2>&1
)
for /f "tokens=2" %%a in ('tasklist^|find /i "libertyserver.exe"') do (taskkill.exe /f /pid %%a >nul 2>&1)
echo Installing liberty profile %SERVICE_NAME%
set INSTALL_SERVICE_COMMAND=%DAEMON_EXEC% //IS//%SERVICE_NAME% --Startup=manual --DisplayName=%SERVICE_DISPLAY_NAME% --Description=%SERVICE_DESCRIPTION% ++DependsOn=Tcpip --LogPath=%LOG_PATH% --StdOutput=auto --StdError=auto --StartMode=exe --StartPath=%SERVER_START_COMMAND_PATH% --StartImage=%SERVER_START_COMMAND% --StartParams=start#SIServer --StopMode=exe --StopPath=%SERVER_STOP_COMMAND_PATH% --StopImage=%SERVER_STOP_COMMAND% --StopParams=stop#SIServer
%INSTALL_SERVICE_COMMAND%
echo Installed liberty profile %SERVICE_NAME%

windows batch file eq was unexpected at this time

I am writing a windows batch script that will Install a service. First, I need to find if the service already exists. If the service exists, it has to check the state. If the state is running, it has to stop and delete the service.
This is my code : test.bat. I am running this from command line.
for /F "tokens=3 delims=: " %%H in ('sc query "IBMLibertyProfile" ^| findstr "STATE" ') do (
if /I "%%H" EQ "RUNNING" (
sc stop "IBMLibertyProfile"
)
)
I am getting error :
C:>test1.bat EQ was unexpected at this time.
C:> if /I "%H" EQ "RUNNING" (
How to solve this error?
Try this:
#rem If the service doesn't exist, exit.
#sc query IBMLibertyProfile > NUL 2>&1
#if %ERRORLEVEL% neq 0 #exit /b 0
#rem If the service is already stopped, delete it.
#sc query IBMLibertyProfile | findstr /s "STOPPED" > NUL 2>&1
#if %ERRORLEVEL% neq 0 #goto :DeleteService
#rem No matter it's state, tell it to stop.
#sc stop IBMLibertyProfile
#rem Wait for it to stop.
#set _WaitLoopCount=0
:StoppedWait
#if _WaitLoopCount equ 10 #goto :ServiceWaitTimeout
#timeout /t 3 > NUL 2>&1
#sc query IBMLibertyProfile | findstr /s "STOPPED" > NUL 2>&1
#if %ERRORLEVEL% neq 0 #goto :StoppedWait
#rem Delete the service and exit.
:DeleteService
#sc delete IBMLibertyProfile
#exit /b 0
:ServiceWaitTimeout
#echo Service failed to reach the STOPPED state. Reboot the computer and try again.
NOTE: If your service is not well behaved, the script might hang. I'll leave it to you to work out how to deal with sc delete failures.

Task Scheduler running a Windows Batch file

I have seen this post..
Batch runs manually but not in scheduled task
It is not Win 2008, but is server 2003
Have a on-time Scheduled Task..
Does not run. Whether it is scheduled or "asked" to run manually.
Run..
D:\WORK\Scripts\res_tc.bat
Have had issue before with the use of double-colons "::" before and have tried to use: REM instead - but there is no difference.
Run as:
NT AUTHORITY\SYSTEM
#ECHO OFF
CLS
REM DISABLE TOMCAT CHECK
SCHTASKS /QUERY|find /i "TCCheck">NUL
IF NOT ERRORLEVEL 1 SCHTASKS /CHANGE /TN "TCCheck" /DISABLE
ECHO CHECKING FOR AND KILLING JAVA
TASKLIST | FIND /I "java.exe" && IF NOT ERRORLEVEL 1 TASKKILL /F /IM java.exe
REM LOOK FOR TOMCAT..
REM If Tomcat was not installed using the installer - instead using a batch file
REM We have to look for the service instead
REM We cannot depend on the Registry key - HKLM\SOFTWARE\Apache Software Foundation\Tomcat
REM Instead, we have to look for it using the registry key
REM HKLM\SYSTEM\CurrentControlSet\services
REM However, we know Tomcat - could be tomcat5, tomcat6, or tomcat7
FOR /F "usebackq tokens=1" %%a in (`reg query "HKLM\SYSTEM\CurrentControlSet\services" ^| find /i "tomcat"`) do SET TomcatService=%%a
REM THANKS FOR THIS - https://stackoverflow.com/questions/17279114/split-path-and-take-last-folder-name-in-batch-script
set TomcatServiceName1=%TomcatService:~0,-1%
for %%f in (%TomcatServiceName1%) do set TomcatServiceName=%%~nxf
FOR /F "usebackq tokens=3" %%a in (`reg query "%TomcatService%" /v ImagePath`) do SET TomcatFolder=%%a
FOR /F "tokens=1-2,* delims=\" %%1 IN ("%TomcatFolder%") do Set TomcatLocation= %%1\%%2
REM Stop Service: Apache Tomcat
ECHO STOPPING SERVICE Apache Tomcat
NET STOP %TomcatServiceName%
ECHO CHECKING TO INSURE SERVICE Apache Tomcat IS STOPPED
NET START | FIND /I "Apache Tomcat"
IF NOT ERRORLEVEL 1 ECHO Apache Tomcat IS STARTED... STOPPING NOW
IF NOT ERRORLEVEL 1 NET STOP %TomcatServiceName%
ECHO DOUBLE-CHECKING TO INSURE SERVICE Apache Tomcat IS STOPPED
PING 127.0.0.1 -w 1 > NUL
NET START | FIND /I "Apache Tomcat"
IF ERRORLEVEL 1 ECHO Apache Tomcat IS STOPPED... GOOD TO GO
IF NOT ERRORLEVEL 1 ECHO Apache Tomcat IS STARTED...
REM -- SOME FAILURE IN STOPPING THE SERVICE, YOU WILL WANT TO EXIT
IF NOT ERRORLEVEL 1 GOTO END
PING 127.0.0.1 -w 1000 > NUL
REM DELETE LOGS - YOU DON'T WANT TO DELETE LOGS IN A PRODUCTION ENVIRONMENT
ECHO DEL Tomcat Log files
ECHO Y | DEL %TomcatLocation%\aa*.*
ECHO Y | DEL %TomcatLocation%\logs\*.*
ECHO DEL Log files
ECHO Y | DEL D:\logs\*.*
ECHO Y | DEL D:\bo_logs\*.*
REM DELETE FOLDER: %TomcatLocation%\work (Catalina Work Directory)
ECHO DELETING THE %TomcatLocation%\work DIRECTORY
RD /S/Q %TomcatLocation%\work
REM DELETE FOLDER: %TomcatLocation%\temp (Temp Directory)
ECHO DELETING THE %TomcatLocation%\temp DIRECTORY
RD /S/Q %TomcatLocation%\temp
IF NOT EXIST %TomcatLocation%\temp\. MD %TomcatLocation%\temp
REM START SERVICE: APACHE TOMCAT
ECHO STARTING Apache Tomcat
NET START | FIND /I "Apache Tomcat"
IF ERRORLEVEL 1 NET START %TomcatServiceName%
IF NOT ERRORLEVEL 1 ECHO Apache Tomcat IS ALREADY STARTED
PING 127.0.0.1 -w 1000 > NUL
ECHO.
ECHO PROCESS IS COMPLETE - VISUALLY DOUBLE CHECK TO INSURE
ECHO Apache Tomcat
ECHO ARE STARTED
REM ENABLE TOMCAT CHECK
SCHTASKS /QUERY|find /i "TCCheck">NUL
IF NOT ERRORLEVEL 1 SCHTASKS /CHANGE /TN "TCCheck" /ENABLE
GOTO END
:END
rem pause
EXIT
Another consideration for safety for use in a Scheduled Task.. You may want to insist the use of ARGS (Arguments) so that the files is not "automatically" invoked..
Consider..
SET /A ARGS_COUNT=0
FOR %%A in (%*) DO SET /A ARGS_COUNT+=1
REM ECHO %ARGS_COUNT%
If %ARGS_COUNT% == 0 GOTO END
If %ARGS_COUNT% == 1 GOTO CONTINUE
:CONTINUE
REM DISABLE TOMCAT CHECK
SCHTASKS /QUERY|find /i "TCCheck">NUL
IF NOT ERRORLEVEL 1 SCHTASKS /CHANGE /TN "TCCheck" /DISABLE
...
In your scheduled task, modify the Run to be (note the space after bat and 1)..
D:\WORK\Scripts\res_tc.bat 1
Then, you must run the batch file from a command prompt as follows: res_tc.bat 1 or something like that.. If you run just a res_tc.bat with no ARGS, the fille will simply end with no execution. Hope this helps.
Note: THIS NEXT SECTION IS NOT RECOMMENDED IN A SCHEDULED TASK but for a stand-alone file. If you want relatively quick and reliable way to stop/start Apache Tomcat, you can do the following (near the top - note the add of CHOICE):
#ECHO OFF
CLS
CHOICE /C YN /M "DO YOU WANT TO RESTART APACHE TOMCAT WEB SERVICE?"
IF %ERRORLEVEL% == 2 GOTO END
REM DISABLE TOMCAT CHECK
SCHTASKS /QUERY|find /i "TCCheck">NUL
IF NOT ERRORLEVEL 1 SCHTASKS /CHANGE /TN "TCCheck" /DISABLE
...
ECHO CHECKING FOR AND KILLING JAVA
TASKLIST | FIND /I "java.exe" && IF NOT %ERRORLEVEL% 1 TASKKILL /F /IM java.exe
if not %errorlevel% 1 ... is not correct. Correct usages are
if not errorlevel 1 ...
if not %errorlevel%==1 ...

Resources