When I run the below batch file code, it thinks that the server address is 'dbuser' and the Database is 'False'
What am I doing wrong?
Here is the code:
#echo off
set toolspath=C:\Program Files (x86)\Folder\Application
Set ApplicationServer=00.0.00.000
Set ApplicationDatabase=dbApplication
Set ApplicationUser=dbuser
Set ApplicationPassword=abcdefg
Set ApplicationUpgradeFromPre12_5=False
REM echo "Attaching dbApplication .. "
REM osql -S %ApplicationServer% -U %ApplicationUser% -P %ApplicationPassword% -i %ApplicationScriptsPath%\AttachApplicationDatabase.sql
REM osql -S %ApplicationServer% -U %ApplicationUser% -P %ApplicationPassword% -i %ApplicationScriptsPath%\SetDBVersion.sql
REM echo "Done."
call ApplicationUpgradeScripts.bat %%2 %ApplicationUser% %ApplicationPassword% %ApplicationDatabase% %ApplicationUpgradeFromPre12_5%
#if ERRORLEVEL 1 goto ERRORSEXIT
#Echo %ApplicationDatabase% Database Updated Successfully.
goto FINISH
:ERRORSEXIT
#Echo Error: Database Excecuted With Error. To Find out Exact Error see file ErrorLog.log
exit /B 1
goto ENDBUILD
:FINISH
#Echo All Databases Excecuted Successfully.
exit 0
:ENDBUILD
pause
Related
I am working on a batch file that calls 4 other batch files. If the sub-batch file returns with an errorlevel code other than 0, I want the parent batch file to capture it, send out an email and exit the parent batch file. However, as soon as the first child batch file is called and returns with a non-zero errorlevel, none of the subsequent commands in the parent batch file run. Here is my batch code:
rem ** setup so it logs itself **
set parent=%~dp0
set me=%~n0
set LOGFILE=%parent%logs\%me%.log 2>&1
if exist "%LOGFILE%" del %LOGFILE% /f /s /q
call :LOG > %LOGFILE%
exit
:LOG
#ECHO OFF
SETLOCAL ENABLEEXTENSIONS EnableDelayedExpansion
echo ParentDir: %parent%
echo ProgramName: %me%
echo.
rem ** script variables **
set batFile1=%parent%FILE1.bat
set batFile2=%parent%FILE2.bat
set batFile3=%parent%FILE3.bat
set batFile4=%parent%FILE4.bat
set FromEmail=server#domain.com
set Recipient=adminuser#domain.com
set CCRecipient=
set Subject=Email Subject
set Message=There was an error in running nightly batch files. Please look at the logs to determine which batch file is causing a problem. \n\nAt your service\nAdmin
set Server=smtp.domain.com
set Port=25
rem ** run bat files and capture error message **
echo.
echo Start: Send Email
set Message=Debug test code
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
call %batFile1%
set exitcode=%ERRORLEVEL%
echo %exitcode%
echo.
echo Start: Send Email
set Message=Debug test code !exitcode!
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
if %exitcode% NEQ 0 (
echo.
set Message=Execution of !batFile1! failed with error message !errorcode!. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f !FromEmail! -t !Recipient! -cc !CCRecipient! -u "!Subject!" -m "!Message!" -v -s !Server!
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile2%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile2% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile3%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile3% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
call %batFile4%
if %ERRORLEVEL% NEQ 0 (
echo.
set Message=Execution of %batFile4% failed with error message %ERRORLEVEL%. Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f %FromEmail% -t %Recipient% -cc %CCRecipient% -u "%Subject%" -m "%Message%" -v -s %Server%
rem ** force execution to quit if check fails
EXIT /B %ERRORLEVEL%
)
EXIT /B %ERRORLEVEL%
It appears that none of the lines of code are executed that follow the command call %batFile1%
For information purposes, this is how the %batFile1% exits:
EXIT /B 254
so that should be coming back with %ERRORLEVEL% 254 every time. the test email that I send just before calling batFile1 works fine.
#echo off
setlocal EnableExtensions
rem ** setup so it logs itself **
set "parent=%~dp0"
set "me=%~n0"
set "LOGFILE=%parent%logs\%me%.log"
if exist "%LOGFILE%" del "%LOGFILE%" /f /s /q
call :LOG > "%LOGFILE%" 2>&1
exit
:LOG
setlocal
echo ParentDir: %parent%
echo ProgramName: %me%
echo.
rem ** script variables **
set batFiles="%parent%FILE1.bat" "%parent%FILE2.bat" "%parent%FILE3.bat" "%parent%FILE4.bat"
set "FromEmail=server#domain.com"
set "Recipient=adminuser#domain.com"
set "CCRecipient="
set "Subject=Email Subject"
set Message=There was an error in running nightly batch files.^
Please look at the logs to determine which batch file is causing a problem.\n\n^
At your service\n^
Admin
set "Server=smtp.domain.com"
set "Port=25"
rem ** Send email test **
echo.
echo Start: Send Email
set Message=Debug test code
c:\APPS\sendemail.exe -f "%FromEmail%" -t "%Recipient%" -cc "%CCRecipient%" -u "%Subject%" -m "%Message%" -v -s "%Server%"
rem ** run bat files and capture error message **
for %%A in (%batFiles%) do (
call :EMAIL %%A
if errorlevel 1 exit /b
)
exit /b
:EMAIL
setlocal
echo.
call "%~1"
if errorlevel 1 (
echo %errorlevel%
set "exitcode=%errorlevel%"
) else exit /b
rem ** Send email **
if "%~n1" == "FILE1" (
set "Message=Debug test code %exitcode%"
) else set Message=Execution of '%~1' failed with error message %exitcode%.^
Examine the logs and fix any issues before next run.\n\nAt your service\nAdmin
echo Start: Send Email
c:\APPS\sendemail.exe -f "%FromEmail%" -t "%Recipient%" -cc "%CCRecipient%" -u "%Subject%" -m "%Message%" -v -s "%Server%"
rem ** force execution to quit if check fails **
if %errorlevel% neq 0 echo Email send error message %errorlevel%.
exit /b
With optimizing the code some, to remove duplication etc.
It appears to be working better. I may have accidently fixed it.
Suggest checking echo %errorlevel% of the call before using
set, else %errorlevel% is of the set command.
None of the new code requires delayed expansion, so remove the
EnableDelayedExpansion setting.
Scripts are set to one variable and is used as a file-set,
in a for loop.
Many of set variable=value are double quoted to avoid any
trailing space issues. Those not, are multiline etc. that
are better without.
The Send Email code is not in a label :EMAIL which helped
to merge the duplicate code. It does a check if name FILE1
is the argument and uses a different email message to match
your original code.
It will end the script if sendemail.exe sets %errorlevel%
to not zero, which is later checked in the for loop.
If you want to exit on the called child batch-file instead,
change the last line from exit /b to exit /b %exitcode%.
Note, implicit use of exit /b is same as exit /b %errorlevel%.
If you prefer the later, update the code to you preference.
The later may require delayed variable expansion if used
in a code block i.e. (command & exit /b !errorlevel!).
I am trying to query each instance on my CMS. But why the errorlevel is still 0 when I tested the stopped instance? And how can I skip the last line in my Instance_list.txt (The %%a will be '(44')
:Start
REM get the full list of our instance from CMS to Instance_list.txt
"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\sqlcmd" -S cms_instance -e -d msdb -Q "SELECT DISTINCT server_name FROM sysmanagement_shared_registered_servers_internal" -o Instance_list.txt
:Run
REM Run query against all instances one by one.
#echo off
setlocal enabledelayedexpansion
for /f "tokens=1,2 skip=3" %%a in (Instance_list.txt) do (
Set Intance_NAME=%%a
"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\sqlcmd" -S !Intance_NAME! -e -d master -Q "SELECT ##SERVERNAME" -o SQL_result.txt
TIMEOUT /T 2
FINDSTR "!Intance_NAME!" SQL_result.txt
IF %ERRORLEVEL% NEQ 0 (
ECHO SQL INSTANCE !Intance_NAME! HAS SOME ISSUE...
)
)
This is a SQLCMD FAQ. You need to set the -b switch for sqlcmd to set the ERRORLEVEL
-b Specifies that sqlcmd exits and returns a DOS ERRORLEVEL value when an error occurs. The value that is returned to the DOS ERRORLEVEL
variable is 1 when the SQL Server error message has a severity level
greater than 10; otherwise, the value returned is 0. If the -V option
has been set in addition to -b, sqlcmd will not report an error if the
severity level is lower than the values set using -V. Command prompt
batch files can test the value of ERRORLEVEL and handle the error
appropriately. sqlcmd does not report errors for severity level 10
(informational messages).
https://learn.microsoft.com/en-us/sql/tools/sqlcmd-utility?view=sql-server-2017
I want the program to process an arbitrary number of command-line arguments, but I'm unsure how to implement a for loop to go through multiple shift commands. Also, the program shouldn't close the command prompt window when it ends.
Here is what I have so far:
#echo off
if "%1"=="" goto skip
if "%1"=="-ti" time /t
if "%1"=="-da" date /t
if "%1"=="-c" cls
if "%1"=="-ip" ipconfig
if "%1"=="-d" dir
if "%1"=="-p" path
if "%1"=="-v" ver
if "%1"=="-t" type
if "%1"=="-m" md
exit /b
:skip
echo No arguments!
I'd like to have the following command-line arguments run properly:
C:\>batchfile –d –ti –da –ip –v
C:\>batchfile
C:\>batchfile –d –m CSC3323 –d
C:\>batchfile –d –t batchfile.bat –m CSC3323 –d
Use this code to loop through your arguments in a file called batchfile.bat:
#echo off
echo arguments: "%*"
:loop
if "%~1"=="" goto skip
if "%~1"=="-ti" time /t
if "%~1"=="-da" date /t
if "%~1"=="-c" cls
if "%~1"=="-ip" ipconfig
if "%~1"=="-d" dir
if "%~1"=="-p" path
if "%~1"=="-v" ver
if "%~1"=="-t" type
if "%~1"=="-m" md
shift
goto loop
:skip
echo No arguments!
pause
and call the batchscript like this:
start batchfile.bat -ti -d -ti -da -ip -v
start batchfile.bat
start batchfile.bat -d -m CSC3323 -d
start batchfile.bat -d -t batchfile.bat -m CSC3323 -d
I have a batch script which asks the user to input a server. Then it checks if it is from an array, where the servers require 3 password to login. Otherwise 2 passwords are needed. I check this in a for loop but always end up going to the else statement. Why? Here is the code:
#echo off
set arrayserver[0]=server1
set arrayserver[1]=server2
set arrayserver[2]=server3
set arrayserver[3]=server4
set arrayserver[4]=server5
set arrayserver[5]=server6
set arrayserver[6]=server7
set arrayserver[7]=server8
set arrayserver[8]=server9
set arrayserver[9]=server10
set arrayserver[10]=server11
set arrayserver[11]=server12
set arrayserver[12]=server13
set arrayserver[13]=server14
set arrayserver[14]=server15
set arrayserver[15]=server16
set arrayserver[16]=server17
set arrayserver[17]=server18
set arrayserver[18]=server19
set arrayserver[19]=server20
set arrayserver[20]=server21
set arrayserver[21]=server22
set arrayserver[22]=server23
set arrayserver[23]=server24
set arrayserver[24]=server25
set arrayserver[25]=server26
set arrayserver[26]=server27
set user2=user2
set user3=user3
set i=0
set /p server=Enter server:
for /F "tokens=2 delims==" %%s in ('set arrayserver[') do (
if "%server%" == "%%s" (
goto breakit
) else (
goto breakit2
))
:breakit
echo You will be prompted for 3 passwords:
echo -pass1
echo -pass2
echo -Oracle user
echo ssh -t -A %user2%#hop2 ssh -t -A %EDSUSER%#%server% su - oracle > C:\Temp\linkche.txt
"C:\Program Files (x86)\Putty\putty.exe" -ssh -A -t %USER%#hop1 -m C:\Temp\linkche.txt
del C:\Temp\linkche.txt
goto :oef
:breakit2
echo You will be prompted for 2 passwords:
echo -pass1
echo -Oracle user
echo ssh -t -A %user2%#hop2 ssh -A oracle#%server% > C:\Temp\linkche.txt
"C:\Program Files (x86)\Putty\putty.exe" -ssh -A -t %USER%#hop1 -m C:\Temp\linkche.txt
del C:\Temp\linkche.txt
goto :oef
Well, that's simple. You are in a loop but after checking the first server you are entering the ELSE case. So you are jumping out of the loop after the first iteration. You can verify this by entering server1. In this case the IF case is executed. Further, GOTO :oef makes no sense. I suppose you want to do GOTO :EOF. While EOF means EndOfFile, OEF means nothing (or possibly OfEndFile? :D).
To fix your problem you should modify your loop like this:
...
for /F "tokens=2 delims==" %%s in ('set arrayserver[') do (
if "%server%" == "%%s" (
goto breakit
)
)
goto breakit2
...
Now you will jump to breakit if the input is between server1 and server27 or to breakit2 otherwise. And don't forget to replace oef with eof.
You do not need to iterate over the array elements. If you define the array with the server values as subscripts with any value in the element (instead of numeric subscripts with the server in the value), then you may directly test if such server exist via a if defined arrayserver[%server%] ... command. I also use a simpler way to define the array.
#echo off
rem Define the server array with the server *in the subscript*; the assigned value does NOT matter
for %%a in (server1 server2 server3 server4 server5 server6 server7 server8 server9 server10
server11 server12 server13 server14 server15 server16 server17 server18 server19 server20
server21 server22 server23 server24 server25 server26 server27) do (
set arrayserver[%%a]=3
)
set user2=user2
set user3=user3
set /p server=Enter server:
if not defined arrayserver[%server%] goto passwords-2
:passwords-3
echo You will be prompted for 3 passwords:
echo -pass1
echo -pass2
echo -Oracle user
echo ssh -t -A %user2%#hop2 ssh -t -A %EDSUSER%#%server% su - oracle > C:\Temp\linkche.txt
"C:\Program Files (x86)\Putty\putty.exe" -ssh -A -t %USER%#hop1 -m C:\Temp\linkche.txt
del C:\Temp\linkche.txt
goto :eof
:passwords-2
echo You will be prompted for 2 passwords:
echo -pass1
echo -Oracle user
echo ssh -t -A %user2%#hop2 ssh -A oracle#%server% > C:\Temp\linkche.txt
"C:\Program Files (x86)\Putty\putty.exe" -ssh -A -t %USER%#hop1 -m C:\Temp\linkche.txt
del C:\Temp\linkche.txt
goto :eof
You may even define array elements with different values for 2 and 3 passwords, and then directly use their values to go to the appropriate section with no if command!
setlocal EnableDelayedExpansion
rem Servers with 3 passwords:
for %%a in (server1 server2 server27) do set arrayserver[%%a]=3
rem Servers with 2 passwords:
for %%a in (serverA serverB serverZ) do set arrayserver[%%a]=2
set /p server=Enter server:
goto passwords-!arrayserver[%server%]!
For further info about array management in Batch files, see this post.
Is it possible to have conditional statements in batch scripts?
For example:
I have two servers, S1 and S2.When the batch file is deployed in S1 then the output should be generated in location L1. Likewise if the batch file is deployed in S2 then output should be generated in location L2.
My script:
set ComputerName=S1
set RepServer=%ComputerName%
set DBServer=%ComputerName%
set ReportPath="/DEV/Clearviewbilling"
set SharedPath=\\scottvdr1\ClearviewBilling\DEV-TEST
set UserId=-E
set fn=Create_Log.txt
if exist %fn% del %fn%
#echo on
#rem Reports
rs -i "%CD%"\Reports\Create_Sub.rss -s http://%RepServer%/reportserver -v Path=%SharedPath% -v rootpath=%ReportPath% -v DBServer=%DBServer% -t >> %fn% 2>&1
But i want the script to be:
set ComputerName=S1
set RepServer=%ComputerName%
set DBServer=%ComputerName%
If ComputerName=S1
Set SharedPath=//blah/blah
else
Set sharedPath=//some/path
set ReportPath="/DEV/Clearviewbilling"
set UserId=-E
set fn=Create_Log.txt
if exist %fn% del %fn%
#echo on
#rem Reports
rs -i "%CD%"\Reports\Create_Sub.rss -s http://%RepServer%/reportserver -v Path=%SharedPath% -v rootpath=%ReportPath% -v DBServer=%DBServer% -t >> %fn% 2>&1
Hence when the file is deployed, the reports are generated in the required path. But this is not working.
You compare the string ComputerName against S1 with the wrong if-else syntax
This should work
if "%ComputerName%"=="S1" (
Set "SharedPath=//blah/blah"
) else (
Set "sharedPath=//some/path"
)