The top answer to this question tells me how to stop/start a remote service. Great. Now, all I need is to wait for the actual stop/start to complete. So, what I\'m looking f
What about powershell and WaitForStatus? Eg, the script below would restart SQL Server on a remote machine:
$computer = "COMPUTER_NAME"
$me = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\user", (convertto-securestring "password" -asplaintext -force)
$restartSqlServer = {
$sqlServer = get-service mssqlserver
$waitInterval = new-timespan -seconds 5
if (-not ($sqlServer.Status -eq "Stopped")) {
$sqlServer.Stop()
$sqlServer.WaitForStatus('Stopped', $waitInterval)
}
$sqlServer.Start()
$sqlServer.WaitForStatus('Running', $waitInterval)
}
icm -ComputerName $computer -ScriptBlock $restartSqlServer -Credential $me
Edit on 10/20/2011 - updated my code. I posted it before fully debugging. Many thanks to Eric Falsken. What a great solution. I tweaked Eric's code (BTW look for a couple of typographical errors if you intend to use it). I added logging and some additional error-checking for some conditions Eric didn't account for. Since I'm most interested in a service restart (not just stopping and/or starting), I only built upon Eric's restart code. Anyway, I'm posting my version, hope you like it!
@ECHO off
:: This script originally authored by Eric Falsken http://stackoverflow.com/
:: Revised for by George Perkins 10/20/2011
IF [%1]==[] GOTO Usage
IF [%2]==[] GOTO Usage
:SetLocalVariables
SET /A MyDelay=0
SET MyHours=%time:~0,2%
IF %MyHours%==0 SET MyHours=00
IF %MyHours%==1 SET MyHours=01
IF %MyHours%==2 SET MyHours=02
IF %MyHours%==3 SET MyHours=03
IF %MyHours%==4 SET MyHours=04
IF %MyHours%==5 SET MyHours=05
IF %MyHours%==6 SET MyHours=06
IF %MyHours%==7 SET MyHours=07
IF %MyHours%==8 SET MyHours=08
IF %MyHours%==9 SET MyHours=09
SET MyMinutes=%time:~3,2%
SET MySeconds=%time:~6,2%
SET MyHundredths=%time:~9,2%
SET MyMonth=%date:~4,2%
SET MyDay=%date:~-7,2%
SET MyCentury=%date:~-4,4%
SET MyTimeStamp=%MyCentury%%MyMonth%%MyDay%%MyHours%%MyMinutes%%MySeconds%
IF "%3" == "" (
SET MyLog=C:\Temp
) ELSE (
SET MyLog=%3
)
SET MyLogFile=%MyLog%\ServiceRestart%MyTimeStamp%.log
ECHO.
ECHO. >> %MyLogFile%
ECHO ------------- ------------- %MyHours%:%MyMinutes%:%MySeconds%.%MyHundredths% %MyMonth%/%MyDay%/%MyCentury% ------------- -------------
ECHO ------------- ------------- %MyHours%:%MyMinutes%:%MySeconds%.%MyHundredths% %MyMonth%/%MyDay%/%MyCentury% ------------- ------------- >> %MyLogFile%
ECHO Begin batch program %0.
ECHO Begin batch program %0. >> %MyLogFile%
ECHO Logging to file %MyLogFile%.
ECHO Logging to file %MyLogFile%. >> %MyLogFile%
ECHO Attempting to restart service %2 on computer %1.
ECHO Attempting to restart service %2 on computer %1. >> %MyLogFile%
PING -n 1 %1 | FIND "TTL=" >> %MyLogFile%
IF errorlevel 1 IF NOT errorlevel 2 GOTO SystemOffline
SC \\%1 query %2 | FIND "FAILED 1060" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO InvalidServiceName
SC \\%1 query %2 | FIND "STATE" >> %MyLogFile%
IF errorlevel 1 IF NOT errorlevel 2 GOTO SystemOffline
:ResolveInitialState
SET /A MyDelay+=1
SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO StopService
SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO StartService
SC \\%1 query %2 | FIND "STATE" | FIND "PAUSED" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO SystemOffline
ECHO Service State is changing, waiting %MyDelay% seconds for service to resolve its state before making changes.
ECHO Service State is changing, waiting %MyDelay% seconds for service to resolve its state before making changes. >> %MyLogFile%
TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile%
GOTO ResolveInitialState
:StopService
SET /A MyDelay=0
ECHO Stopping %2 on \\%1.
ECHO Stopping %2 on \\%1. >> %MyLogFile%
SC \\%1 stop %2 | FIND "FAILED" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO Unstoppable
:StoppingServiceDelay
SET /A MyDelay+=1
IF %MyDelay%==21 GOTO MaybeUnStoppable
ECHO Waiting %MyDelay% seconds for %2 to stop.
ECHO Waiting %MyDelay% seconds for %2 to stop. >> %MyLogFile%
TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile%
:StoppingService
SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService
SC \\%1 query %2 | FIND "STATE" | FIND "STOP_PENDING" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppingServiceDelay
GOTO StoppingServiceDelay
:MaybeUnStoppable
:: If we got here we waited approximately 3 mintues and the service has not stopped.
SC \\%1 query %2 | FIND "NOT_STOPPABLE" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO OneLastChance
GOTO Unstoppable
:OneLastChance
SC \\%1 stop %2 >> %MyLogFile%
SET /A MyDelay+=1
ECHO Waiting %MyDelay% seconds for %2 to stop.
ECHO Waiting %MyDelay% seconds for %2 to stop. >> %MyLogFile%
TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile%
SC \\%1 query %2 | FIND "STATE" | FIND "STOPPED" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO StoppedService
SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile%
IF errorlevel 1 IF NOT errorlevel 2 GOTO UnknownState
SC \\%1 query %2 | FIND "NOT_STOPPABLE" >> %MyLogFile%
IF errorlevel 0 IF NOT errorlevel 1 GOTO Unstoppable
GOTO StoppingServiceDelay
:StoppedService
ECHO %2 on \\%1 is stopped.
ECHO %2 on \\%1 is stopped. >> %MyLogFile%
GOTO StartService
:StartService
SET /A MyDelay=0
ECHO Starting %2 on \\%1.
ECHO Starting %2 on \\%1. >> %MyLogFile%
SC \\%1 start %2 >> %MyLogFile%
GOTO StartingService
:StartingServiceDelay
SET /A MyDelay+=1
ECHO Waiting %MyDelay% seconds for %2 to start.
ECHO Waiting %MyDelay% seconds for %2 to start. >> %MyLogFile%
TIMEOUT /t %MyDelay% /nobreak >> %MyLogFile%
:StartingService
SC \\%1 query %2 | FIND "STATE" | FIND "RUNNING" >> %MyLogFile%
IF errorlevel 1 IF NOT errorlevel 2 GOTO StartingServiceDelay
:StartedService
ECHO %2 on \\%1 is started.
ECHO %2 on \\%1 is started. >> %MyLogFile%
GOTO EndExit
:SystemOffline
ECHO Failure! Server \\%1 or service %2 is not accessible or is offline!
ECHO Failure! Server \\%1 or service %2 is not accessible or is offline! >> %MyLogFile%
ECHO See log file %MyLogFile% for details!
GOTO EndExit
:InvalidServiceName
ECHO Failure! Service %2 is not valid!
ECHO Failure! Service %2 is not valid! >> %MyLogFile%
ECHO See log file %MyLogFile% for details!
GOTO EndExit
:UnknownState
ECHO Failure! Service %2 in an unknown state and cannot be stopped!
ECHO Failure! Service %2 in an unknown state and cannot be stopped! >> %MyLogFile%
ECHO See log file %MyLogFile% for details!
GOTO EndExit
:UnStoppable
ECHO Failure! Service %2 cannot be stopped! Check dependencies or system state.
ECHO Failure! Service %2 cannot be stopped! Check dependencies or system state. >> %MyLogFile%
ECHO See log file %MyLogFile% for details!
GOTO EndExit
:Usage
ECHO Will restart a remote service, waiting for the service to stop/start (if necessary).
ECHO.
ECHO Usage:
ECHO %0 [system name] [service name] [logfile path]
ECHO Example: %0 server1 MyService C:\Temp\Log
ECHO.
GOTO EndExit
:EndExit
ECHO.
ECHO %0 Ended.
ECHO.
I improved the script of Eric Falsken and revised by Gerorge Perkins.
Changes:
sparse optimizations.
@ECHO off :: This script originally authored by Eric Falsken http://stackoverflow.com/ :: Revised by George Perkins 10/20/2011 :: Revised by Armando Contestabile 02/23/2015 IF "%1"=="" GOTO Usage IF "%2"=="" GOTO Usage SET ACTION=%1 SET SERVICENAME=%2 IF "%3"=="" ( SET SYSTEMNAME=%COMPUTERNAME% ) ELSE ( SET SYSTEMNAME=%3 ) IF "%ACTION%" == "stop" ( SET ACTION=STOP ) ELSE IF "%ACTION%" == "STOP" ( SET ACTION=STOP ) ELSE IF "%ACTION%" == "start" ( SET ACTION=START ) ELSE IF "%ACTION%" == "START" ( SET ACTION=START ) ELSE IF "%ACTION%" == "restart" ( SET ACTION=RESTART ) ELSE IF "%ACTION%" == "RESTART" ( SET ACTION=RESTART ) ELSE GOTO Usage SET STATE= SET CURRENT_STATUS= SET /A DEFAULT_DELAY=5 SET /A SLEEP_COUNT=0 SET /A RESTARTED=0 SET /A MAX_WAIT_PERIODS=5 ECHO. ECHO Attempting to %ACTION% service %SERVICENAME% on computer %SYSTEMNAME%. PING -n 1 %SYSTEMNAME% | FIND "TTL=" >nul 2>&1 IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 ( ECHO Failure! Server \\%SYSTEMNAME% or service %SERVICENAME% is not accessible or is offline! EXIT /B 1 ) SC \\%SYSTEMNAME% query %SERVICENAME% | FIND "FAILED 1060" >nul 2>&1 IF ERRORLEVEL 0 IF NOT ERRORLEVEL 1 ( ECHO Failure! Service %SERVICENAME% is not valid! EXIT /B 2 ) SC \\%SYSTEMNAME% query %SERVICENAME% | FIND "STATE" >nul 2>&1 IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 ( ECHO Failure! Server \\%SYSTEMNAME% or service %SERVICENAME% is not accessible or is offline! EXIT /B 3 ) :Dispatch FOR /f "tokens=*" %%i IN ('SC \\%SYSTEMNAME% query %SERVICENAME% ^| FIND "STATE"') DO SET STATE=%%i ECHO %STATE% | FINDSTR /C:"1" >nul IF %ERRORLEVEL%==0 SET CURRENT_STATUS=STOPPED ECHO %STATE% | FINDSTR /C:"2" >nul IF %ERRORLEVEL%==0 SET CURRENT_STATUS=START_PENDING ECHO %STATE% | FINDSTR /C:"3" >nul IF %ERRORLEVEL%==0 SET CURRENT_STATUS=STOP_PENDING ECHO %STATE% | FINDSTR /C:"4" >nul IF %ERRORLEVEL%==0 SET CURRENT_STATUS=RUNNING ECHO %STATE% | FINDSTR /C:"5" >nul IF %ERRORLEVEL%==0 SET CURRENT_STATUS=CONTINUE_PENDING ECHO %STATE% | FINDSTR /C:"6" >nul IF %ERRORLEVEL%==0 SET CURRENT_STATUS=PAUSE_PENDING ECHO %STATE% | FINDSTR /C:"7" >nul IF %ERRORLEVEL%==0 SET CURRENT_STATUS=PAUSED ECHO Current status of service is %CURRENT_STATUS% IF NOT "%CURRENT_STATUS%"=="RUNNING" IF NOT "%CURRENT_STATUS%"=="STOPPED" IF NOT "%CURRENT_STATUS%"=="PAUSED" ( IF "%SLEEP_COUNT%"=="%MAX_WAIT_PERIODS%" ( ECHO Service state won't change. Script exececution is canceled. EXIT /B 4 ) ECHO Service State is changing, waiting %DEFAULT_DELAY% seconds... SLEEP %DEFAULT_DELAY% SET /A SLEEP_COUNT+=1 GOTO Dispatch ) IF "%ACTION%"=="START" ( IF "%CURRENT_STATUS%"=="RUNNING" ( ECHO Service %SERVICENAME% is running. GOTO EndExit ) ELSE ( GOTO StartService ) ) ELSE IF "%ACTION%"=="RESTART" ( IF "%CURRENT_STATUS%"=="RUNNING" ( IF %RESTARTED%==1 ( ECHO Service %SERVICENAME% restarted. GOTO EndExit ) SET /A SLEEP_COUNT=0 GOTO StopService ) ELSE ( SET /A RESTARTED=1 GOTO StartService ) ) ELSE IF "%ACTION%"=="STOP" ( IF "%CURRENT_STATUS%"=="STOPPED" ( ECHO Service %SERVICENAME% is stopped. GOTO EndExit ) ELSE ( GOTO StopService ) ) :StartService ECHO Starting %SERVICENAME% on \\%SYSTEMNAME% SC \\%SYSTEMNAME% start %SERVICENAME% >nul 2>&1 SET SLEEP_COUNT=0 GOTO Dispatch :StopService ECHO Stopping %SERVICENAME% on \\%SYSTEMNAME% SC \\%SYSTEMNAME% stop %SERVICENAME% >nul 2>&1 SET SLEEP_COUNT=0 GOTO Dispatch :Usage ECHO This script can start/stop/restart a local or remote service, waiting for the service to stop/start ^(if necessary^). ECHO. ECHO Usage: ECHO %0 ^<start^|stop^|restart^> ^<SERVICE^> [SYSTEM] ECHO. ECHO If no SYSTEM is provided, the script attempts to execute on the local system. EXIT /B 5 :EndExit ECHO. EXIT /B 0
Eric Falsken's solution works perfectly. +1.
But I'd like to add that the timeout command would sometimes fail with error: "Input redirection is not supported, exiting the process immediately"
To fix this I've had to replace the timeout command:
timeout /t 2 /nobreak >NUL
with the following:
ping -n 2 127.0.0.1 1>NUL
NET START and NET STOP shouldn't return until the service has indicated that the service has started or stopped successfully.