Passing CMD Results to Variable in a Batch File - variables

I am trying to install an application and a group of services using PSTools, but I want to take into account that the computer I am trying to connect to may be turned off or on a different network, which is not reachable from the internal network.
Basically if the machine is not able to be accessed through the admin share, this is the message that I am getting:
Couldn't access MachineName:
The network path was not found.
Make sure that the default admin$ share is enabled on MachineName.
This is the syntax I am using to try to capture the "Error Message" and then report back that if installation was successful or not (depending on if it can contact the machine)
#echo off
set /p name=What is the machine name?:
psexec.exe \\%name% -u *useraccount* -p *password* \\ServerName\installation.bat
FOR /F "tokens=*" %%A IN ('COMMAND ^| FIND "Couldn't access"') DO SET Error=%%A
If "%Error%"=="Couldn't access"
ECHO Installation Failed.
Else
ECHO Installtion complete.
Pause
exit
Currently it hangs right at the point it's defining the Error Variable. Can't quite figure out what I am going wrong here.

'COMMAND ^| FIND "Couldn't access"' opens a command shell, which is why it hangs. It will not proceed until that shell is exited.
You will need to look at redirecting the error messages to another file. 2>Errors.txt on the psexec line will give you a file to search in the next line.
this will make the batch file look something like this:
#echo off
set /p name=What is the machine name?:
psexec.exe \\\%name% ... \\\ServerName\installation.bat 1>Error.txt 2>&1
for /f "tokens=*" %%A in ('FIND /i error.txt "Couldn't Access"') do SET Error=%%A
If not x%ERROR:Couldn=%==x%ERROR% (
ECHO Installation Failed.
) Else (
ECHO Installtion complete.
)
Pause
exit
(Also, notice the use of brackets to make a multi line IF)
the check for if will see if Couldn is part of the string, as a direct comparison will not work, as you would have to check against the whole string including the machine name

Related

Not able to pass the command-file in Jprofiler

I tried to automate the JProfiler in offline mode to connect to a running JVM using below batch script. I am not able to pass command-file which would take the inputs to the JProfiler. I am still unsure what format do I need to pass to the JProfiler. I tried passing as text and File formats but no luck.
BatchScript.bat
#echo off
TITLE "Profiling an application using JPofiler"
echo ***********Running JProfiler in non-interactive mode*****************
set "JPROFILER_HOME=C:\dev\jprofiler11"
set JPROFILER_CONFIG_FILE_LOCATION=C:\dev\profiler_start_script\config.xml
"%JPROFILER_HOME%"\bin\jpenable.exe --offline --id=116 --config=%JPROFILER_CONFIG_FILE_LOCATION%
if %ERRORLEVEL% NEQ 0 (
set ERROR= Jpenable is not able to profile the selected JVM, check JPROFILER_HOME and JPROFILER_CONFIG_FILE_LOCATION is set to correct location.
goto endError)
set /p PID=Enter the process id of the JVM:
SET "JPCONTRL=%JPROFILER_HOME%\bin\jpcontroller.exe"
"%JPCONTRL%" -n --non-interactive -f **--command-file=C:\dev\profiler_start_script\commands** %PID%
goto end
:endError
echo Error: %ERROR%
:end
endlocal
Commands
startCPURecording true
saveSnapshot C:\dev\build\trunk\WBScheduler\snapshot.jps
stopCPURecording
Can anyone tell me what format do i need to send the inputs file to the JProfiler?
I am using Jprofiler 11+ version.
The arguments to jpcontroller.exe should be
-n --non-interactive -f C:\dev\profiler_start_script\commands %PID%
Also, the commands should include a sleep, otherwise there will be no data in the snapshot:
startCPURecording true
sleep 10
stopCPURecording
saveSnapshot C:\dev\build\trunk\WBScheduler\snapshot.jps
Just tested this with JProfiler 11.1.4. If your problem persists, please include the error message. Also try to invoke the commands manually.

Running sqlcmd in batch file works but running the same batch file as a scheduled task works and does nothing

I have looked at many SO questions/answers and though some seem similar to my issue they do not seem to be. The answers given fix issues the questions were asking about but will not solve my issue.
I have a batch file...
#ECHO ON
ECHO Disabling the following... >> C:\App\Debug.log
ECHO - V1 >> C:\Apps\Debug.log
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'"`) DO (
Echo %%F >> C:\Apps\Debug.log
)
EXIT /B
When I run this file at the command prompt it works perfectly fine. When I run it as a scheduled task it show me the echos but nothing for the for loop as expected.
Yes I have made sure the username (using whoami) is the same for the scheduled task set up as the manual run that I do.
Yes I know the user running the script has rights to everything (file access as well as DB access) because it works fine running it from the command prompt.
Scheduled task is set to run wither user is logged on or not.
Any ideas what might be wrong or what I can try for debugging purposes?
Thanks!
sqlcmd is perhaps not enough. cmd.exe in environment of scheduled task may fail to find the executable using local PATHEXT and local PATH environment variables. The executable should be specified with full qualified file name, i.e. drive + path + name + extension. Then the batch file does not anymore depend on the environment variables PATH and PATHEXT because of all files are referenced with full qualified file name.
for executes the specified command line with starting in background one more command process with %ComSpec% /c and the specified command line appended. This means executed is following with Windows installed on drive C::
C:\Windows\System32\cmd.exe /c sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'"
for captures everything written to handle STDOUT of started command process. The lines of captured output are processed line by line by for after started cmd.exe terminated itself. Error messages output by started cmd.exe or the commands/executables executed by Windows command processor in background to handle STDERR are redirected to handle STDERR of command process processing the batch file and printed to console. But there is no console window on running a batch file as scheduled task. So error messages cannot be seen in this case.
The for command line can be modified easily here to get also error messages written into the C:\Apps\Debug.log.
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1' 2^>^&1"`) DO (
The Microsoft article Using command redirection operators explains 2>&1. The two operators > and & must be escaped with ^ to be interpreted as literal characters on Windows command processor parsing the for command line before executing finally for which executes next %ComSpec% /c with the specified command line on which 2^>^&1 is changed already to 2>&1.
Does the log file C:\App\Debug.log contain with this modification following two lines?
'sqlcmd' is not recognized as an internal or external command,
operable program or batch file.
Yes, then no executable with file name sqlcmd is found by started cmd.exe. The best solution is referencing this executable with full qualified file name. See also: What is the reason for "X is not recognized as an internal or external command, operable program or batch file"?
Otherwise sqlcmd outputs perhaps an error message which should be now also in the log file C:\App\Debug.log.
It would be also possible to use following command line to let background cmd.exe write the error messages into a separate error log file C:\App\Error.log:
FOR /F "tokens=* USEBACKQ" %%F IN (`sqlcmd -j -S DOMAIN\SQLSERVER -U username -P password -d DBNAME -Q "UPDATE [DBNAME].[dbo].[table1] SET ColOne='V1_OFF' WHERE ColOne='V1'" 2^>C:\App\Error.log`) DO (
"tokens=* usebackq" results in first deleting all leading horizontal tabs and normal spaces on non-empty lines by for, then checking if the remaining line starts with ; in which case the line is also ignored and finally assigning the captured line not starting with ; and with leading tabs/spaces removed to loop variable F for further processing.
Better would be using the options usebackq^ delims^=^ eol^= not enclosed in double quotes which requires escaping the two spaces and the two equal signs with caret character ^ to be interpreted as literal characters by cmd.exe on parsing the command line before executing for. The line splitting behavior is disabled completed with delims= because of the definition of an empty list of delimiters. And no line except an empty line is ignored anymore because of end of line character modified from default ; to no character.
Finally a space on an echo line left to redirection operator >> is also output by echo and for that reason written as trailing space into the log file. Therefore no space should be used left to > or >> on printing a line with echo redirected into a file. But care must be taken on omitting the space character left to the redirection operator. The word left to redirection operator should not be 1, 2, ..., 9 as this would result in redirecting the output to these numbered handles into the specified file instead of the character 1, 2, etc. So if unknown text should be written into a file, it is better to specify first the redirection operator > or >> and the full qualified file name and next the echo command with the text to output. See also: Why does ECHO command print some extra trailing space into the file?
The three command lines with echo would be for this batch file:
ECHO Disabling the following...>> C:\App\Debug.log
ECHO - V1>> C:\Apps\Debug.log
>>C:\Apps\Debug.log ECHO %%F
following... is safe for being correct written into the file as also V1. %%F could be just 1 or a string ending with a space and a single digit and so it is better to specify the redirection first on the last echo command line to get finally executed by cmd.exe the command line ECHO %%F 1>>C:\Apps\Debug.log.

Batch file hangs at SQL Error

I am using a batch file my.bat as given below:
#echo off
setlocal enabledelayedexpansion
for /F "tokens=*" %%A in (user.txt) do (
sqlplus -s -l %%A #fetch.sql
) >> output.txt
where user.txt (list of all user details for which I need expiry date. this list may have around 40-50 rows) is:
dbuser/password#database1
readuser/p#ssw0rd#database1
adminuser/Pa$$word#database2
.......
.......
.......
and fetch.sql is:
set pagesize 200
set linesize 200
select username, expiry_date from user_users;
exit;
The problem I am facing is, script my.bat captures here all the required details in output.txt along with SQL ERRORS (ORA-01017: invalid username/password; logon denied ,ORA-12154: TNS:could not resolve the connect identifier specified, ORA-28000: the account is locked ) but its getting hanged at the point whenever it encounteres below error message :
ERROR:
ORA-28001: the password has expired
Changing password for readuser
Please can you let me know how I can ignore this ERROR message too and keep my script running further ?
You can have whenever sqlerror exit failure in your SQL script, but because you only run that after a successful connection it won't catch this error.
You could instead launch SQL*Plus without logging in, using the /nolog switch, and then connect explicitly:
#echo off
setlocal enabledelayedexpansion
for /F "tokens=*" %%A in (user.txt) do (
(
echo whenever sqlerror exit failure
echo connect %%A
echo #fetch.sql
) | sqlplus -s /nolog
) >> output.txt
This also means your credentials aren't supplied on the command line; not sure about Windows so much but on other platforms that is a considerable security risk. Of course you still have them stored in a plain text file which itself isn't very secure, so that's more of a general point.
You could put your fetch.sql statements directly in the batch file if you prefer, by echoing those instead of the # start command; same effect but one less file to maintain.

How to run a command in vmware using vmrun, command is (echo %PROGRAMFILES%)

How to run a command in vmware using vmrun, command is (echo %PROGRAMFILES%) on the guest machine..
and the guest machine should return a value of the command result... how to do this??? please suggest
I needed to do something similar and found this unanswered question. Here's my solution.
#ECHO OFF
REM Set up abbreviations that we'll be using a lot.
SET VMRUN="C:\Program Files (x86)\VMware\VMware VIX\vmrun.exe" -T ws -gu Administrator -gp password
SET VMX="C:\Users\whoever\Documents\Virtual Machines\Windows\Windows.vmx"
SET GUEST_COMSPEC="C:\WINDOWS\system32\cmd.exe"
REM Tried to do this in one line, but couldn't figure out the quoting.
%VMRUN% CreateTempfileInGuest %VMX% >%TEMP%\GuestTmp.txt || GOTO :CantCreate
FOR /F "delims=;" %%F IN ( %TEMP%\GuestTmp.txt ) DO SET GTEMP=%%F
REM The batch file is a one-liner that echos the variable into a file.
REM It could be generated dynamically and copied to the guest
REM but I didn't want to complicate things any further.
%VMRUN% runProgramInGuest %VMX% %GUEST_COMSPEC% "/c C:\echo-ProgramFiles.bat %GTEMP%"
%VMRUN% CopyFileFromGuestToHost %VMX% %GTEMP% %TEMP%\GuestOut.txt
%VMRUN% DeleteFileInGuest %VMX% %GTEMP%
REM Do something with the result and delete the temp files.
TYPE %TEMP%\GuestOut.txt
DEL %TEMP%\GuestOut.txt %TEMP%\GuestTmp.txt
GOTO :EOF
:CantCreate
REM Provide details on any problems.
TYPE %TEMP%\GuestTmp.txt 1>&2
DEL %TEMP%\GuestTmp.txt
EXIT 100
And here's the batch file on the guest host. As you can see, it's pretty simple. I couldn't get redirection to work in runProgramInGuest (probably didn't experiment enough)
so I just pass the file as a command line argument.
#echo %PROGRAMFILES% >%1
Have a look at the vmrun commands here. You need the Guest OS Command runScriptInGuest.
I have not checked the command , but it should look like this. Please verify it.
vmrun -T server -h https://xps:8333/sdk -u user -p mypassword -gu administrator -gp guestpaswd
runScriptInGuest "[Vol1] win2008-1/win2008-1.vmx" "echo %PROGRAMFILES%"
I had to use runProgramInGuest
capture the output to a file
copy the file back to my host and use it
Thats the soln I used.

How to check if a particular command line is running in cmd propmt

I desperately need help to create a vb / dos code which will do the following:
Check if a command prompt window is running with the following command: mgms A1 (mgms is a custom command)
If it is running, exit.
If it is not running, start cmd prompt and run the command , exit
Thanks a lot for your help!
The Windows cmd.exe batch language is horrible, but you should be able to put this in a batch file and get it working:
tasklist /FI "IMAGENAME eq mgms.exe" 2>&1 | findstr /B "INFO: No tasks running" > tmp
for /F "delims=" %x in (tmp) do mgms A1
You may need to further check that the command-line arguments to mgms.exe match what you expect -- have a look at the help for tasklist.exe and findstr.exe. Both programs are both standard in WinXP Pro and up, I believe. If you don't have them, I'm sure you can find them or (near) equivalents on the web.