2

I am writing a batch script which should stopp services on a remote computer, copy something and then start it again.

The fact, that sc doesn't wait for the service to return a full stop / start signal doesn't satisfy me, as I fear that the service might be inconsistend or failing, and then could damage the program code / database which is depending on those services.

therefore I searched for a workaround, to have something similiar to usage of net , and come around this:

sc \\remote_server stop Service1 >> %LOGFILE%

:askservice1
for /f "tokens=4" %%a in (' sc \\remote_server query Service ^|findstr STATE') do set ServiceResult=%%a

if %ServiceResult%=STOPPED (goto nextservice2)
goto askservice1

:nextservice2

sc \\remote_service stop Service2 >> %LOGFILE%

:askservice2
for /f "tokens=4" %%a in (' sc \\remote server query Service ^|findstr STATE') do set ServiceResult2=%%a

if %ServiceResult2%=STOPPED (goto nextservice3)
goto askservice2 

this goes on for 6 services, then the copy will be done, and then the run should go other way round with starting up

as you can see, this is a. really strange and looks confusing and b, it could end in an endless loop if the service won't get to the state I am comparing to...

my questions would be, how can I terminate the goto after a few tries and just let it go to the next service ?

or do you have any other code for me that helps ? I am limited to use batch or powershell but as I've never used PS before, I couldn't understand the solutions I've found.

Mythoria
  • 125
  • 1
  • 3
  • Are you waiting for all 6 services to be stopped before the copy? – Matt Williamson Mar 20 '14 at 15:19
  • 1
    yes I want to. I am copying the instance directory of a database, and to have a consistent and restore-able state of the database, the services which use the DB should not be running to prevent access to the files. – Mythoria Mar 21 '14 at 06:21
  • would it be a solution if I put the service stop / start on a batch file locally on my remote computer, and start this from the one I am copying ? within this I could use net start / stop and have the successful signal that I need. How can I wait for the remote batch to finish and then continue on the machine I am working on ? – Mythoria Mar 21 '14 at 06:30

1 Answers1

0

Try this and see if it works for you. I tested it on my local machine with 2 services and it worked well. You'll have to tweak some of the ping timeout settings and take out the echo for the file copy but overall it should give you a nice starting place.

@echo off
setlocal enabledelayedexpansion

set "stopstart=stop"
set "state=STOPPED"
set "remoteserver=REMSERV"
set "LogFile=Logfile.log"
if exist %LogFile% del /q %LogFile%

:Start
for %%S in (service1 service2 service3 service4 service5 service6) do (
    sc \\%remoteserver% %stopstart% %%S>>%LogFile%
    Call :WaitForService %remoteserver% %%S %state% ret && (
    echo Service %%S %state% 
    set /a svc+=1) || (
    Service %%S is !state!
    )
)   

if "%svc%" EQU "6" (
  echo copy file now.
  ping -n 10 127.0.0.1>nul
  set "stopstart=start"
  set "state=RUNNING"
  goto :Start  
)

if "%svc%" EQU "12" (Echo All services are now running.)

exit /b

:WaitForService <remoteserver> <service> <stopstart> <return>
setlocal
for /L %%a in (1,10,1) do (
    for /f "tokens=4" %%a in ('
      sc \\%~1 query %~2^|findstr "STATE"') do (
        ping -n 2 -w 10000 127.0.0.1>nul
        if "%%a" EQU "%~3" set %~4=%%a & exit /b 0
    )
    exit /b 1
)

What it's doing is setting some variables at the start then looping through all 6 of your services sending them to a subroutine that checks the wait state given to it. In the first iteration, it's STOPPED so it checks in a loop for the service to be stopped. Once it is STOPPED, it sends an exit code and we check that exit code to make sure the service stopped. At this point, we add a +1 to a variable to keep track of each service that has stopped. Once all 6 have stopped, we copy the file in question, flip the state of the services to RUNNING and run through the routine again waiting for each of the services to start. Once all of them are started, it Echo's all services are running and ends. You can probably expand upon it more by checking additional states and running through the WaitForService routine until everything has STOPPED if you need to but in my testing, the services just stopped and started without any hiccups.

Matt Williamson
  • 6,947
  • 1
  • 23
  • 36