Grepping `reg query` result value? - scripting

Consider the following result from a hypothetical reg query:
..>reg query HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MediaPlayer /v "I
nstallation Directory"
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MediaPlayer
Installation Directory REG_EXPAND_SZ %ProgramFiles%\Windows Media Play
er
How do I grep the output so that I can assign the actual value of the setting (%ProgramFiles%\...) into a variable (or temp file)?

example for batch files:
#FOR /F "tokens=2* " %%A IN ('reg query HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MediaPlayer /v "Installation Directory"') DO #SET PARAM=%%B
If you want to use it directly in console - use single percent sign to denote variables (i.e. %A and %B)

Related

Output forfiles error to a variable

I am trying to save the output of forfiles to a variable in batch.
I've tried a few things to set a var to the output directly as well as saving to a file
Long story short, I am comparing the output text to another string variable, if it matches an event log is created and I get an alert.
Everything in my script works as intended other than saving the forfile output to the variable so I can compare it to my default text variable
forfiles /P %filename% /D -1 > variable
set TEST=
the variable just stays completely blank.
If I run the command just in command prompt it outputs like this
forfiles /P C:\users\justin.pcs\desktop\test\ /D -1 > variable
ERROR: No files found with the specified search criteria.
So I am getting the error I am watching for, but the variable stays blank. I'm assuming I am missing some sort of switch that is necessary for this.
to get the output of a command, either redirect STDERR to a file and read it back:
forfiles /P C:\users\justin.pcs\desktop\test\ /D -1 2>temp
<temp set /p variable=
echo %variable"%
or use a for construct (no temporary file needed):
for /f "delims=" %%a in ('forfiles /P C:\users\justin.pcs\desktop\test\ /D -1 2^>^&1 1^>nul') do set variable=%%a
echo %variable%
The redirections (2^>^&1 1^>nul)are needed, because STDOUT is parsed, but you need STDERR.

How to set batch variable to output of another script

I try to set a batch variable to an output of another command. In Linux/Unix you can simply use backticks, e.g. (in csh)
set MY_VAR = `tail /etc/passwd`
Is there something similar available in windows batch?
Actually I found already something but it is not fully working:
d:\>for /F "skip=1" %n in ('wmic OS Get CurrentTimeZone') do set TimeZone=%n
d:\>set TimeZone=120
:\>set TimeZone=
d:\>
The problem is the wmic commands returns several lines, otherwise it would work fine. The first I know to skip, however I did not manage to skip the second empty line. I tried with IF but no success.
yes - the output of wmic is a bit ugly to handle.
Use a trick: search for a number in the ouput (findstr "[0-9] will only return lines, that contain a number):
for /F %n in ('wmic OS Get CurrentTimeZone ^|findstr "[0-9]"') do set TimeZone=%n
echo Timezone is %TimeZone%.
(for use in a batchfile use %%n instead of %n)
Another way is:
for /F %n in ('wmic OS Get CurrentTimeZone') do if not defined TimeZone set TimeZone=%n
EDIT:
I prefer the first version, as findstr (or find) converts the wmic-line-endings, so the second for mentioned by MC ND is not neccessary.
I suggest following batch code:
#echo off
for /F "skip=1" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS Get CurrentTimeZone') do (
set "TimeZone=%%I"
goto BelowLoop
)
:BelowLoop
echo Time zone difference is: %TimeZone%
The FOR loop is exited with command GOTO after the value of interest is assigned to environment variable TimeZone.
The entire FOR loop can be optimized to a single command line:
#echo off
for /F "skip=1" %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS Get CurrentTimeZone') do set "TimeZone=%%I" & goto BelowLoop
:BelowLoop
echo Time zone difference is: %TimeZone%
Exiting the FOR loop after having the value of interest avoids the problem with wrong parsing of Unicode (UTF-16 Little Endian) encoded output of WMIC by FOR which otherwise would result in deleting the environment variable TimeZone. For details on wrong parsing of Unicode output by FOR see answer on How to correct variable overwriting misbehavior when parsing output?
for /f "tokens=2 delims==" %a in ('wmic OS get CurrentTimeZone /value') do set "timeZone=%a"
(to use in a batch file, remember to double the percent signs)
The added /value in wmic changes its output to key=value format. The delims clause in for command indicates a = as a separator. The tokens clause ask to retrieve only the second token/field in the line. As the only line with two tokens is the line with the required data, only this line is processed.
BUT, wmic output includes an aditional carriage return at the end of its output, that needs to be removed from the variable. An aditional for command can be used. The resulting command will be
for /f "tokens=2 delims==" %a in ('wmic OS get CurrentTimeZone /value') do for /f %b in ("%a") do set "timeZone=%b"
Or, for a batch file
for /f "tokens=2 delims==" %%a in (
'wmic OS get CurrentTimeZone /value'
) do for /f %%b in ("%%a") do set "timeZone=%%b"
echo %timeZone%

Saving Number of Lines in File as a Variable in Batch File

I have this really nice line in my batch file that tells me how many lines are in a file:
find /v /c "" C:\Users\c1921\mypath\myfolder\!$Unit!.txt
This is nice and gives me 31 for the particular file I'm working with. My problem is the file looks something like this:
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
my_handled
219278
check
219276
control
219274
I want to be able to skip the first three lines entirely and then save the first value and then use the second value in my next command etc.
How do I save the number (e.g. 31) into a variable in my batch file?
On a hunch I tried setting a variable like so but it wasn't effective:
set "$testVar="""
echo !$testVar!
This command allows you to "save the number (e.g. 31) into a variable in my batch file":
for /F %%a in ('find /v /c "" ^< C:\Users\c1921\mypath\myfolder\!$Unit!.txt') do set numLines=%%a
This command allows you "to skip the first three lines entirely" and process the rest:
for /F "skip=3 delims=" %%a in (C:\Users\c1921\mypath\myfolder\!$Unit!.txt) do echo Processing: "%%a"
However, in my opinion this problem could be entirely avoided if the three first lines in the text file are supressed from the very beginning. I think this file is generated via a VBScript of JScript program that is executed this way:
cscript progname.vbs > C:\Users\c1921\mypath\myfolder\!$Unit!.txt
The first three lines in the text file may be avoided adding //nologo switch this way:
cscript //nologo progname.vbs > C:\Users\c1921\mypath\myfolder\!$Unit!.txt
#ECHO OFF
SETLOCAL
SET /a count=3
SET "first="
FOR /f "skip=3delims=" %%a IN (q25089468.txt) DO (
IF DEFINED first (CALL :show %%a) ELSE (SET "first=%%a")
)
ECHO count=%count%
GOTO :EOF
:show
ECHO first=%first% second=%1
SET /a count+=2
SET "first="
GOTO :eof
I used a file named q25089468.txt containing your data for my testing.
You appear to be asking two entirely different things - how to count the lines and how to skip the first 3, then deliver each succeeding pair to another process.

Get a filename bat

I am new to BAT writing.
I am trying to write a batch file which will check to see if a file is above or below a certain size and then send an email accordingly. I have written something that can do this with a static file name
#echo off
setlocal
set file="ssoff.bat"
set maxbytesize=1000
FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA
if %size% LSS %maxbytesize% (
echo.File is ^< %maxbytesize% bytes
blat -server mail.omers.com -f checker#omers.com -t rplomp#omers.com -s "filesize less than" -body testbody
) ELSE (
echo.File is ^>= %maxbytesize% bytes
blat -server mail.omers.com -f checker#omers.com -t rplomp#omers.com -s "filesize greater than" -body testbody
)
In this case, the filename being checked is ssoff.bat. However, I need to have the bat check a filename which changes daily according to the date. The mask for the filename uses the date string IE: deployEAR_restartWAS_03132013.log ; deployEAR_restartWAS_03142013.log ... and so on - with the last 8 chars reflecting the date generated. The bat needs to check the latest file in that directory. For today it would be deployEAR_restartWAS_03152013.log
This logfile would not be in the parent dir either.
I thought maybe of having the bat copying over the latest file from that dir to the parent dir and then checking its size? Or using the static part of the filename 'deployEAR_restartWAS_' and then passing the last part of it through a date variable?
But I'm not sure what approach would be best, and I'm sure there are others that I have not thought of.
The bat file run time would be the same day as the date variable at the end of the filename.
for /f %%i in ('dir /b /a-d /od deployEAR_restartWAS_*.log') do set name=%%i&set size=%%~zi
echo latest file is %name% size %size%
Can't work out in which directory this set of .log files resides from your description. You tell us it won't be in the parent directory and your only reference appears to be that directory.
If the .log files are not in the CURRENT directory, all you need do is add the directory name to the deploy... thus: Q:\wherever\it\maybe\deployEAR_restartWAS_*.log or, if the file's path contains spaces, quote the name thus: "Q:\where ever\it\may be\deployEAR_restartWAS_*.log"

How to get the PID of a VB3 process running in Win7?

I tried to use the tasklist command in cmd but it was not listed in there.
I also notice that the process is a little indented in task manager together with another process called wowexec.exe.
Any way to get the PID of the process? For reasons of hex editing.
wmic is nice for running sql-like queries to get the information you need. Replace wowexec in the following example with something resembling the task name of your VB3 process.
for /f "tokens=2 delims==" %%I in ('wmic process where "name like '%%wowexec%%'" get processid /format:list') do set "PID=%%I"
Something like that is what you would put in a batch script.
If you're just running this from a cmd console, use %I instead of %%I, and do #echo %I instead of do set etc.
for /f "tokens=2 delims==" %I in ('wmic process where "name like '%%wowexec%%'" get processid /format:list') do #echo %I
Note: The double percents around wowexec signify literal percent symbols, a SQL syntax wildcard character. wowexec is not a variable, but a literal string.