@echo off rem Name: StopAndRestartService.bat rem Revision: v3.0.0.1 rem Description: Stops a Windows Service and restarts it once stopped. Intended to be run as a scheduled task every 1 hour on a CP3/DX Server. rem Notes: Must create shortcut and setup shortcut to Run as Administrator. Then call shortcut from scheduled task. Scheduled task should be set to run even when not logged in and use Windows SYSTEM account. rem Created: 01/03/2025 by JN rem Updated: 01/08/2025 by JN rem Changes From Previous Revision: Added logging all actions to file; removed quotation marks from variable values. rem specify Windows Service name, Process name for that Service, App Pool name and Site name below set ServiceNameToBeRestarted=D-Scribe X Sync Service set ServiceProcessNameToBeRestarted=Dscribex.SyncService.exe set AppPoolNameToBeRestarted=dx-service set SiteNameToBeRestarted=dx-service rem variable initialization set ServiceRestartAttempted=0 set AppPoolRestartAttempted=0 set SiteRestartAttempted=0 set CurrentYear=%date:~10,4% set CurrentMonth=%date:~4,2% set CurrentDayOfMonth=%date:~7,2% set LogFileBaseDirectory=C:\ProgramData\General Devices\D-Scribe X Tasks\StopAndRestartServiceLogs set LogFileName="%LogFileBaseDirectory%"\%CurrentYear%\%CurrentMonth%\%CurrentDayOfMonth%\%CurrentYear%-%CurrentMonth%-%CurrentDayOfMonth%.log set CurrentDate=%CurrentYear%-%CurrentMonth%-%CurrentDayOfMonth% rem EnabledDelayExpansion needed to use !ERRORLEVEL! in 2nd Query functions since they are nested within IF statements which does not allow them to show accuate ERRORLEVEL (https://ss64.com/nt/errorlevel.html#:~:text=If%20you%20are,expression%20has%20completed.) Setlocal EnableDelayedExpansion :CREATE_LOG_DIRECTORY_STRUCTURE if not exist "%LogFileBaseDirectory%" md "%LogFileBaseDirectory%" > nul if not exist "%LogFileBaseDirectory%"\%CurrentYear% md "%LogFileBaseDirectory%"\%CurrentYear% > nul if not exist "%LogFileBaseDirectory%"\%CurrentYear%\%CurrentMonth% md "%LogFileBaseDirectory%"\%CurrentYear%\%CurrentMonth% > nul if not exist "%LogFileBaseDirectory%"\%CurrentYear%\%CurrentMonth%\%CurrentDayOfMonth% md "%LogFileBaseDirectory%"\%CurrentYear%\%CurrentMonth%\%CurrentDayOfMonth% > nul echo ------------------------- >> %LogFileName% :QUERY_SERVICE_1 echo %CurrentDate% - %TIME% - Query "%ServiceNameToBeRestarted%" Service status... echo %CurrentDate% - %TIME% - Query "%ServiceNameToBeRestarted%" Service status... >> %LogFileName% rem query service sc query "%ServiceNameToBeRestarted%" | FIND "STOPPED" > nul if %ERRORLEVEL% == 0 ( echo %CurrentDate% - %TIME% - ERROR - "%ServiceNameToBeRestarted%" Service is STOPPED already, will try to start "%ServiceNameToBeRestarted%" Service... echo %CurrentDate% - %TIME% - ERROR - "%ServiceNameToBeRestarted%" Service is STOPPED already, will try to start "%ServiceNameToBeRestarted%" Service... >> %LogFileName% call :START_SERVICE ) else ( echo %CurrentDate% - %TIME% - "%ServiceNameToBeRestarted%" Service is NOT STOPPED, will try to stop "%ServiceNameToBeRestarted%" Service... echo %CurrentDate% - %TIME% - "%ServiceNameToBeRestarted%" Service is NOT STOPPED, will try to stop "%ServiceNameToBeRestarted%" Service... >> %LogFileName% call :STOP_SERVICE ) :QUERY_APPPOOL_1 echo %CurrentDate% - %TIME% - Query "%AppPoolNameToBeRestarted%" App Pool status... echo %CurrentDate% - %TIME% - Query "%AppPoolNameToBeRestarted%" App Pool status... >> %LogFileName% rem query IIS App Pool C:\Windows\System32\inetsrv\appcmd.exe list apppool "%AppPoolNameToBeRestarted%" | FIND "Stopped" > nul if %ERRORLEVEL% == 0 ( echo %CurrentDate% - %TIME% - ERROR - "%AppPoolNameToBeRestarted%" App Pool is Stopped already, will try to start "%AppPoolNameToBeRestarted%" App Pool... echo %CurrentDate% - %TIME% - ERROR - "%AppPoolNameToBeRestarted%" App Pool is Stopped already, will try to start "%AppPoolNameToBeRestarted%" App Pool... >> %LogFileName% call :START_APPPOOL ) else ( echo %CurrentDate% - %TIME% - "%AppPoolNameToBeRestarted%" App Pool is NOT Stopped, will try to stop "%AppPoolNameToBeRestarted%" App Pool... echo %CurrentDate% - %TIME% - "%AppPoolNameToBeRestarted%" App Pool is NOT Stopped, will try to stop "%AppPoolNameToBeRestarted%" App Pool... >> %LogFileName% call :STOP_APPPOOL ) :QUERY_SITE_1 echo %CurrentDate% - %TIME% - Query "%SiteNameToBeRestarted%" Site status... echo %CurrentDate% - %TIME% - Query "%SiteNameToBeRestarted%" Site status... >> %LogFileName% rem query IIS Site C:\Windows\System32\inetsrv\appcmd.exe list site "%SiteNameToBeRestarted%" | FIND "Stopped" > nul if %ERRORLEVEL% == 0 ( echo %CurrentDate% - %TIME% - ERROR - "%SiteNameToBeRestarted%" Site is Stopped already, will try to start "%SiteNameToBeRestarted%" Site... echo %CurrentDate% - %TIME% - ERROR - "%SiteNameToBeRestarted%" Site is Stopped already, will try to start "%SiteNameToBeRestarted%" Site... >> %LogFileName% call :START_SITE ) else ( echo %CurrentDate% - %TIME% - "%SiteNameToBeRestarted%" Site is NOT Stopped, will try to stop "%SiteNameToBeRestarted%" Site... echo %CurrentDate% - %TIME% - "%SiteNameToBeRestarted%" Site is NOT Stopped, will try to stop "%SiteNameToBeRestarted%" Site... >> %LogFileName% call :STOP_SITE ) :QUERY_SERVICE_2 if %ServiceRestartAttempted% == 0 ( echo %CurrentDate% - %TIME% - Waiting 15 seconds, then query "%ServiceNameToBeRestarted%" Service status... echo %CurrentDate% - %TIME% - Waiting 15 seconds, then query "%ServiceNameToBeRestarted%" Service status... >> %LogFileName% rem wait 15 seconds Timeout /t 15 /nobreak > nul rem query service sc query "%ServiceNameToBeRestarted%" | FIND "STOPPED" > nul if !ERRORLEVEL! == 0 ( echo %CurrentDate% - %TIME% - "%ServiceNameToBeRestarted%" Service has been STOPPED, will try to restart "%ServiceNameToBeRestarted%" Service... echo %CurrentDate% - %TIME% - "%ServiceNameToBeRestarted%" Service has been STOPPED, will try to restart "%ServiceNameToBeRestarted%" Service... >> %LogFileName% call :START_SERVICE ) else ( echo %CurrentDate% - %TIME% - ERROR - "%ServiceNameToBeRestarted%" Service has NOT been STOPPED, will use taskkill to kill "%ServiceNameToBeRestarted%"... echo %CurrentDate% - %TIME% - ERROR - "%ServiceNameToBeRestarted%" Service has NOT been STOPPED, will use taskkill to kill "%ServiceNameToBeRestarted%"... >> %LogFileName% call :KILL_SERVICE ) ) :QUERY_APPPOOL_2 if %AppPoolRestartAttempted% == 0 ( echo %CurrentDate% - %TIME% - Query "%AppPoolNameToBeRestarted%" App Pool status... echo %CurrentDate% - %TIME% - Query "%AppPoolNameToBeRestarted%" App Pool status... >> %LogFileName% rem query IIS App Pool C:\Windows\System32\inetsrv\appcmd.exe list apppool "%AppPoolNameToBeRestarted%" | FIND "Stopped" > nul if !ERRORLEVEL! == 0 ( echo %CurrentDate% - %TIME% - "%AppPoolNameToBeRestarted%" App Pool has been Stopped, will try to restart "%AppPoolNameToBeRestarted%" App Pool... echo %CurrentDate% - %TIME% - "%AppPoolNameToBeRestarted%" App Pool has been Stopped, will try to restart "%AppPoolNameToBeRestarted%" App Pool... >> %LogFileName% call :START_APPPOOL ) else ( echo %CurrentDate% - %TIME% - ERROR - "%AppPoolNameToBeRestarted%" App Pool has NOT been Stopped, will try to stop "%AppPoolNameToBeRestarted%" App Pool again... echo %CurrentDate% - %TIME% - ERROR - "%AppPoolNameToBeRestarted%" App Pool has NOT been Stopped, will try to stop "%AppPoolNameToBeRestarted%" App Pool again... >> %LogFileName% call :STOP_APPPOOL ) ) :QUERY_SITE_2 if %SiteRestartAttempted% == 0 ( echo %CurrentDate% - %TIME% - Query "%SiteNameToBeRestarted%" Site status... echo %CurrentDate% - %TIME% - Query "%SiteNameToBeRestarted%" Site status... >> %LogFileName% rem query IIS Site C:\Windows\System32\inetsrv\appcmd.exe list site "%SiteNameToBeRestarted%" | FIND "Stopped" > nul if !ERRORLEVEL! == 0 ( echo %CurrentDate% - %TIME% - "%SiteNameToBeRestarted%" Site has been Stopped, will try to restart "%SiteNameToBeRestarted%" Site... echo %CurrentDate% - %TIME% - "%SiteNameToBeRestarted%" Site has been Stopped, will try to restart "%SiteNameToBeRestarted%" Site... >> %LogFileName% call :START_SITE ) else ( echo %CurrentDate% - %TIME% - ERROR - "%SiteNameToBeRestarted%" Site has NOT been Stopped, will try to stop "%SiteNameToBeRestarted%" Site again... echo %CurrentDate% - %TIME% - ERROR - "%SiteNameToBeRestarted%" Site has NOT been Stopped, will try to stop "%SiteNameToBeRestarted%" Site again... >> %LogFileName% call :STOP_SITE ) ) GOTO QUERY_SERVICE_3 :STOP_SERVICE echo %CurrentDate% - %TIME% - Trying to stop "%ServiceNameToBeRestarted%" Service... echo %CurrentDate% - %TIME% - Trying to stop "%ServiceNameToBeRestarted%" Service... >> %LogFileName% rem stop Service sc stop "%ServiceNameToBeRestarted%" > nul exit /B :STOP_APPPOOL echo %CurrentDate% - %TIME% - Trying to stop "%AppPoolNameToBeRestarted%" App Pool... echo %CurrentDate% - %TIME% - Trying to stop "%AppPoolNameToBeRestarted%" App Pool... >> %LogFileName% rem stop App Pool C:\Windows\System32\inetsrv\appcmd.exe stop apppool "%AppPoolNameToBeRestarted%" > nul exit /B :STOP_SITE echo %CurrentDate% - %TIME% - Trying to stop "%SiteNameToBeRestarted%" Site... echo %CurrentDate% - %TIME% - Trying to stop "%SiteNameToBeRestarted%" Site... >> %LogFileName% rem stop Site C:\Windows\System32\inetsrv\appcmd.exe stop site "%SiteNameToBeRestarted%" > nul exit /B :KILL_SERVICE echo %CurrentDate% - %TIME% - ERROR - Killing "%ServiceNameToBeRestarted%" Service since it did not respond to stop command... echo %CurrentDate% - %TIME% - ERROR - Killing "%ServiceNameToBeRestarted%" Service since it did not respond to stop command... >> %LogFileName% rem kill service with taskkill taskkill /F /IM "%ServiceProcessNameToBeRestarted%" /T > nul echo %CurrentDate% - %TIME% - Waiting 15 seconds for "%ServiceProcessNameToBeRestarted%" Process to end... echo %CurrentDate% - %TIME% - Waiting 15 seconds for "%ServiceProcessNameToBeRestarted%" Process to end... >> %LogFileName% rem wait 15 seconds Timeout /t 15 /nobreak > nul call :START_SERVICE exit /B :START_SERVICE echo %CurrentDate% - %TIME% - Trying to start "%ServiceNameToBeRestarted%" Service... echo %CurrentDate% - %TIME% - Trying to start "%ServiceNameToBeRestarted%" Service... >> %LogFileName% rem start service sc start "%ServiceNameToBeRestarted%" > nul set ServiceRestartAttempted=1 exit /B :START_APPPOOL echo %CurrentDate% - %TIME% - Trying to start "%AppPoolNameToBeRestarted%" App Pool... echo %CurrentDate% - %TIME% - Trying to start "%AppPoolNameToBeRestarted%" App Pool... >> %LogFileName% rem start App Pool C:\Windows\System32\inetsrv\appcmd.exe start apppool "%AppPoolNameToBeRestarted%" > nul set AppPoolRestartAttempted=1 exit /B :START_SITE echo %CurrentDate% - %TIME% - Trying to start "%SiteNameToBeRestarted%" Site... echo %CurrentDate% - %TIME% - Trying to start "%SiteNameToBeRestarted%" Site... >> %LogFileName% rem start Site C:\Windows\System32\inetsrv\appcmd.exe start site "%SiteNameToBeRestarted%" > nul set SiteRestartAttempted=1 exit /B :QUERY_SERVICE_3 echo %CurrentDate% - %TIME% - Waiting 15 seconds, then query "%ServiceNameToBeRestarted%" Service status... echo %CurrentDate% - %TIME% - Waiting 15 seconds, then query "%ServiceNameToBeRestarted%" Service status... >> %LogFileName% rem wait 15 seconds Timeout /t 15 /nobreak > nul rem query service sc query "%ServiceNameToBeRestarted%" | FIND "RUNNING" > nul if %ERRORLEVEL% == 0 ( echo %CurrentDate% - %TIME% - "%ServiceNameToBeRestarted%" Service is RUNNING, will exit... echo %CurrentDate% - %TIME% - "%ServiceNameToBeRestarted%" Service is RUNNING, will exit... >> %LogFileName% ) else ( echo %CurrentDate% - %TIME% - ERROR - "%ServiceNameToBeRestarted%" Service is NOT RUNNING, TODO HERE... echo %CurrentDate% - %TIME% - ERROR - "%ServiceNameToBeRestarted%" Service is NOT RUNNING, TODO HERE... >> %LogFileName% ) :QUERY_APPPOOL_3 echo %CurrentDate% - %TIME% - Query "%AppPoolNameToBeRestarted%" App Pool status... echo %CurrentDate% - %TIME% - Query "%AppPoolNameToBeRestarted%" App Pool status... >> %LogFileName% rem query IIS App Pool C:\Windows\System32\inetsrv\appcmd.exe list apppool "%AppPoolNameToBeRestarted%" | FIND "Started" > nul if %ERRORLEVEL% == 0 ( echo %CurrentDate% - %TIME% - "%AppPoolNameToBeRestarted%" App Pool is Started, will exit... echo %CurrentDate% - %TIME% - "%AppPoolNameToBeRestarted%" App Pool is Started, will exit... >> %LogFileName% ) else ( echo %CurrentDate% - %TIME% - ERROR - "%AppPoolNameToBeRestarted%" App Pool is NOT Started, TODO HERE... echo %CurrentDate% - %TIME% - ERROR - "%AppPoolNameToBeRestarted%" App Pool is NOT Started, TODO HERE... >> %LogFileName% ) :QUERY_SITE_3 echo %CurrentDate% - %TIME% - Query "%SiteNameToBeRestarted%" Site status... echo %CurrentDate% - %TIME% - Query "%SiteNameToBeRestarted%" Site status... >> %LogFileName% rem query IIS Site C:\Windows\System32\inetsrv\appcmd.exe list site "%SiteNameToBeRestarted%" | FIND "Started" > nul if %ERRORLEVEL% == 0 ( echo %CurrentDate% - %TIME% - "%SiteNameToBeRestarted%" Site is Started, will exit... echo %CurrentDate% - %TIME% - "%SiteNameToBeRestarted%" Site is Started, will exit... >> %LogFileName% ) else ( echo %CurrentDate% - %TIME% - ERROR - "%SiteNameToBeRestarted%" Site is NOT Started, TODO HERE... echo %CurrentDate% - %TIME% - ERROR - "%SiteNameToBeRestarted%" Site is NOT Started, TODO HERE... >> %LogFileName% ) :DONE rem wait 5 seconds to give time to read last log entry Timeout /t 5 /nobreak > nul rem PAUSE echo ------------------------- >> %LogFileName% exit