I would like to create a .bat file that will give me option to chose between different servers and perform actions such as stop/start services. So far I am getting System error 67 has occurred.The network name cannot be found. Is there a better way to do this. or can I chose the server name from a pop up option.
#ECHO OFF
CLS
ECHO 1.server1
ECHO 2.server2
ECHO 3.server3
ECHO 4.server4
ECHO.
set /p server_name=Enter server name:
IF %server_name%== 1 GOTO app1
IF %server_name%== 2 GOTO app2
IF %server_name%== 3 GOTO app3
IF %server_name%== 4 GOTO app4
:app1
call:restart "server1"
GOTO End
:app2
call:restart "server2"
GOTO End
:app3
call:restart "server3"
GOTO End
:app4
call:restart "server4"
GOTO End
:restart
net use \\%~1/User:%username%
SC \\%~1 Stop service
timeout 10
SC \\%~1 Start service
GOTO End
Instead of debugging your file, I'd like to present you a different solution:
On the servers where you want to restart your services create this bat file:
#ECHO OFF
:STOP
SC STOP <your_service>
ping 127.0.0.1 -n 6 > nul
SC QUERY <your_service> | find /I "STATE" | find "STOPPED"
if errorlevel 1 goto :STOP
SC START <your_service>
Now, create on your servers tasks with the task scheduler. Don't set any triggers but make the task execute your newly created bat file. Select any options you need (like a specific user with a specific password, whether to run the script when no one is logged in or not, whether to run it with admin priveledges or not, etc.) and give it name (your_task).
Finally, modify your script like this:
#ECHO OFF
CLS
ECHO 1.server1
ECHO 2.server2
ECHO 3.server3
ECHO 4.server4
ECHO.
:SELECT
set /p server_name=Enter server name:
IF %server_name%==1 GOTO app1
IF %server_name%==2 GOTO app2
IF %server_name%==3 GOTO app3
IF %server_name%==4 GOTO app4
GOTO SELECT
:app1
SCHTASKS /RUN /S "server1" /TN "your_task"
GOTO End
:app2
SCHTASKS /RUN /S "server2" /TN "your_task"
GOTO End
:app3
SCHTASKS /RUN /S "server3" /TN "your_task"
GOTO End
:app4
SCHTASKS /RUN /S "server4" /TN "your_task"
GOTO End
:End
You can also pass a user and a password to the SCHTASKS command if needed.
It should be clear how it works. I'd recommend taking a closer look at the first bat file. Using this:
SC \\%~1 Stop service
timeout 10
SC \\%~1 Start service
might cause trouble. Sometimes service won't stop within 10 seconds out of various reasons. Trying to start the service while it hasn't stopped yet, will result in an error and the service will remain stopped.
Instead, our bat script within the scheduled task will try to stop the service, then wait for 5 seconds (yes, -n 6 means 5 seconds ^^) and then it will check whether the service has the state "STOPPED". If it is, it will start it, otherwise, it will re-try to stop it, wait 5 more seconds and so on.
Related
Currently we are facing a problem that effects system stability, our server has SQL server 2012 and for unknown reason its services stop running and that needs someone to restart it manually every single day. I have created a command in batch file to restart SQL server automatically and it works fine, however, I am looking for better command that can check if SQL server stop, just restart it, if running, just ignore. How can I do that command that ?
#ECHO OFF
NET START MSSQL$SQLEXPRESS
You can use sc to query the status:
sc query MSSQL$SQLEXPRESS | findstr /I /C:STATE | findstr /I /C:RUNNING
If ERRORLEVEL 1 sc start MSSQL$SQLEXPRESS
But since you have Server 2012, Powershell is another option:
$service = Get-Service -Name MSSQL$SQLEXPRESS
If ($service.Status -ine "running") {
$service | Start-Service
}
Something like this. pause is optional. Don't use it if this goes in a scheduled task! In that case you wouldn't need all the echo statements either. Of course you will need to run this with administrative privileges to start the service. I added a check for that.
#echo off
set "Service=MSSQL$SQLEXPRESS"
rem Make sure service exists
sc query %Service% | (findstr "does not exist" && goto :Done)
for /f "tokens=1,2,3,4" %%A in ('sc query %Service%') do (
if /I %%A == STATE (
if /i not %%D == RUNNING (
echo(%Service% STATE is %%D. It should be RUNNING.
rem openfiles requires admin
openfiles >nul 2>&1 || (Color E0 & ECHO(You must run with Administrative priveleges to start the service. & goto :Done)
echo(Starting it now...
sc start %Service%
)
)
)
:Done
pause
Might be a good idea to look through the Windows event log and see if you can determine why the service is stopping, as there is obviously something wrong.
I have made a batch script to perform the following tasks :
if the file abc.laccdb still in the update folder , show a message : wait a minute.... if abc.laccdb file is not in the 'update' folder , show a message : updating data successfully..
My Batch script is :
#ECHO OFF
start update_data.vbs
:check
FOR %%F IN (update\abc.laccdb) DO (
echo wait a minute...
goto :check
)
echo updating data successfully
pause
with the script above , the message "wait a minute ... " continuously displayed in command prompt window, even though abc.laccdb file has not in the Update folder. properly if the abc.laccdb file is not there in the Update folder, the bacth application run the next line (echo updating data successfully). please correct my script. thank you :)
A for command with a wildcard will enumerate the files matching the wildcard, but without a wildcard, it will not ensure that the file exists, so the code in the do clause will always be executed whether the file exists or not.
Use
#ECHO OFF
start update_data.vbs
:check
ping -n 3 localhost >nul 2>nul
if exist "update\abc.laccdb" (
echo wait a minute...
goto :check
)
echo updating data successfully
pause
It is not always a good idea to have a waiting loop without some kind of wait. The ping has been included to generate a 2 seconds pause between loops to reduce the cpu usage.
Using MC ND's answer:
#ECHO OFF
echo wait a minute...
start update_data.vbs
ping -n 5 localhost >nul 2>nul
:check
if exist "update\abc.laccdb" (
ping -n 3 localhost >nul 2>nul
goto :check
)
echo updating data successfully
pause
Display echo wait a minute... message in advance...
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.
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.
As part of a solution I've just implemented, I'd like to automate a housekeeping schedule for log files maintenance.
I know what I've put together is a bit crude but it does the job anyway. Just want someone to take a quick look and fine tune the script if possible?
Requirement - Ideally, I would want the script to:
1. Stop two services.
2. Check if they are indeed stopped by verifying their error level status.
3. If they are in hung state, identify the process and kill the same.
4. Upon completion of the stop / kill, move two specific log files to archive folder
5. Start the services back again.
6. Nice to have - make sure they are both in running state (error level = 4).
My script:
echo off
:sub_StopServices
net stop sasl_svn
echo ======================================================
echo %date% %time% SASL service stopped
net stop SVNServe
echo ======================================================
echo %date% %time% SVN service stopped
::set level=%errorlevel%
sc query sasl_svn | find "STATE" | FIND "RUNNING" >NUL
sc query svnserve | find "STATE" | FIND "RUNNING" >NUL
if %errorlevel%==1 ( if %errorlevel%==1 (GOTO sub_moveLogs)
else (GOTO sub_StopServices))
if %errorlevel%==3 (taskkill /f /im svnserve.exe && taskkill /f /im saslauthd.exe)
else (GOTO sub_moveLogs))
:sub_MoveLogs
MOVE E:\cygwin\var\log\sasl_svn.log E:\cygwin\var\log\Archive\sasl_svn.log
MOVE E:\cygwin\var\log\SVNServe.log E:\cygwin\var\log\Archive\SVNServe.log
echo ======================================================
echo %date% %time% Log archive is successful
GOTO sub_StartServices
:sub_StartServices
net start sasl_svn
echo ======================================================
echo %date% %time% SASL service started
net start SVNServe
echo ======================================================
echo %date% %time% SVN service started
exit
Thanks
Karthik Durairajan
Two things I would suggest for this:
Don't outright kill the service exe, it may be completing a long running operation
SC STOP VCCDataService>nul
:waitforstop
SET ServiceToKill=[service name]
tasklist /nh /fi "imagename eq %ServiceToKill%" | find /i "%ServiceToKill%" >nul && (
echo %ServiceToKill% is running
TIMEOUT /T 15
GOTO waitforstop
) || (
echo %ServiceToKill% is not running
)
Rename your log files with the date, otherwise you will only retain one iteration of the log. windows-batch-script-format-date-and-time
I have around 140 virtual servers that need regular maintance, they all run message queuing, but the storage file needs to be kept below 512MB. I need to stop all the services in order and the last being MSMQ service, then go to the system32\msmg\storage file and delete all the *.mq files, once done I then would like the batch file to restart the services with the first being msmq. I also need to add some error messages, so if the service can not stop or start or its already running etc, below is what I think it should be like but not sure,. may be there is a better way of doing it,
the plan would be to but the batch file on all the servers and set a sceduled task to Run the batch file.
Would it be possible to have an email generated to say that it has been completed successfully ?
NET STOP AVLDataService 2>&1|FIND "2182"
IF errorlevel 1 goto :sub_already_stoped
You are on the right track. A batch file can certainly accomplish this with NET START/STOP calls in the desired order. For error handling, if the error is non-fatal echo a message to a text file and continue. If it's fatal, then use goto to jump to the end of the file. At the end of the file, you can email yourself the text file with error messages using BMAIL.
Try this:
#echo off
title Service Uninstaller
color 0A
set blank=
set service=blank
:start
echo.
echo.
echo.
SET /P service=Enter the name of the service you want to uninstall:
IF "%service%"=="" (ECHO Nothing is entered
GoTo :start)
cls
echo.
echo.
echo.
echo We will delete the service: %service%
ping -n 5 -w 1 127.0.0.1>nul
::net stop %service%
ping -n 2 -w 1 127.0.0.1>nul
sc delete %service%
pause
:end