batch wmi for loop - batch-file

I'm having trouble using wmi in a for loop. I'm simply trying to grab the first number for the OS Version to differentiate between XP (5) and Win7 (6).
The following works fine by itself for querying a single machine.
for /f "tokens=1 delims=." %%a in ('wmic /node:%machine% os get version') do #for /f "tokens=1 delims=." %%b in ("%%a") do #set osver=%%b
echo %osver%
However once I attempt to put it in a for loop, I'm only getting a blank for %osver%
for /f %%G in (list.txt) do (
for /f "skip=2 tokens=2 delims=.," %%a in ('wmic /node:%%G os get version /format:csv') do #for /f "tokens=1 delims=." %%b in ("%%a") do #set osver=%%b
echo %osver%
) > results.txt
I'm assuming it's an issue with my skip/tokens/delims but I'm not sure how to figure out where exactly it's going wrong. Any variation on them that I've tried still results in a blank line.

You also dont have to set %%b to osver, if you only need to echo the value of %%b you may as well echo %%b because on its own it is a variable that is available only to the method in which it was declared.. you only make an instance variable if you are planning on using it outside the for body ..
So you should probably stick to enabledelayedexpansion if you wana use it elsewhere ...
also you should enclose your statements with parenthesis to to avoid code mix up ....

I'd say you're assuming wrong.
Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).
Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.
Two common ways to overcome this are 1) to use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var or 2) to call a subroutine to perform further processing using the changed values.
Note therefore the use of CALL ECHO %%var%% which displays the changed value of var. CALL ECHO %%errorlevel%% displays, but sadly then RESETS errorlevel.
So, I'd predict that call echo %%osver%% in place of echo %osver% would fix your problem.
OTOH, echo %%b would likely be easier and quicker.
for /f %%G in (list.txt) do (
for /f "skip=2 tokens=2 delims=.," %%a in (
'wmic /node:%%G os get version /format:csv'
) do for /f "tokens=1 delims=." %%b in ("%%a") do (
set osver=%%b
echo %%b
)
CALL echo %%osver%%
) > results.txt

Related

Trying to understand this code (Batch, CMD)

#echo off
setlocal enabledelayedexpansion
::just a sample adapter here:
set "adapter=Ethernet adapter Local Area Connection"
set adapterfound=false
echo Network Connection Test
for /f "usebackq tokens=1-2 delims=:" %%f in (`ipconfig /all`) do
(
set "item=%%f"
if /i "!item!"=="!adapter!"
(
set adapterfound=true
)
else if not "!item!"=="!item:IP Address=!" if "!adapterfound!"=="true"
(
echo Your IP Address is: %%g
set adapterfound=false
)
)
VERY new to batch, can someone explain a few things here:
What does setlocal enabledelayedexpansion do in this particular instance?
What does usebackq do? (I've tried looking this up but didn't quite understand)
How did the variable %%g get initialized and is it global or local?
Thank you for your time!
Delayed Expansion will cause variables to be expanded at execution time rather than at parse time.
Code below would seem to echo second second, but it prints first second instead.
setlocal EnableDelayedExpansion
set var=first
set var=second & Echo %var% !var!
Source: SS64
usebackq forces for loops use backquotes (`dir`) to evaluate the commands inside it and use the output for the forloop, instead of open a file. This will list all elements of Documents predeced with an asterisk.
echo Documents:
for /f "usebackq" %%i in (`dir /b "C:\Users\%username%\Documents\"`) do (
echo * %%i
)
pause
They're local. Using the previous example, %%iis defined just in the for loop, no additional initialization needed.

Using if conditions at the end of a FOR loop in Batch

I have a simple for loop in a batch file I'm working on but I can't get the variables to expand correctly. the whole script is below..
setlocal enabledelayedexpansion
set track=0
FOR /f "tokens=2" %%G IN ('find "PhysicalTrackNumber" %1') DO if %track% LSS %%G set track=%%G
echo %track%
echo %1
pause
The for command pulls all the rows with the physical track number and I'm just trying to get the biggest number. IT always stays 0 though when it's comparing. I've tried with !! around my variable as well but then the script seems to do something completely different. I thought it would take the new variable.
What am I missing to compare the outputs to the previous and just get the biggest number?
find "string" filename output consists of
an empty line;
a string of 10 dashes followed by the filename being searched line;
any matching lines of text in the file.
Use skip=2 option (a number of lines to skip at the beginning):
FOR /f "skip=2 tokens=2" %%G IN ('find "PhysicalTrackNumber" "%~1"') DO (
if !track! LSS %%G set "track=%%~G"
)
As an alternative, use findstr instead of find:
FOR /f "tokens=2" %%G IN ('findstr "PhysicalTrackNumber" "%~1"') DO (
if !track! LSS %%G set "track=%%~G"
)

Batch scripting not assigning variable as expected

I'm working on a batch script which will assign a variable string and then trim it. I'm facing two issues:
The variables are not assigning properly. It is taking last value from from the variable file.
The variables are not assigning the first time I run the script. I need to run the script second time to see if the variables have been assigned. On third run, I can see the trim is working.
My script looks like this:
#echo off
for /f "tokens=*" %%a in ('findstr "W3SVCWINSRVRHOSTS" "C:\Data\SiebelAdmin\Commands\file.txt"') do (
for /f "tokens=2 delims==" %%b in ("%%a") do (
for %%c in (%%b) do (
echo in loop
set str=%%c
echo %%c
echo.%str%
set str=%str:~-6%
echo.%str%
)))
The output looks like this on third run:
> C:\Users\parthod\Desktop>b.bat
in loop
xsj-uvapoms72
7.2.27
7.2.27
in loop
xsj-uvapoms82
7.2.27
7.2.27
in loop
172.17.2.26
7.2.27
7.2.27
in loop
172.17.2.27
7.2.27
7.2.27
You fell into the delayed expansion trap -- try this:
#echo off
setlocal EnableDelayedExpansion
for /f "tokens=*" %%a in ('findstr "W3SVCWINSRVRHOSTS" "C:\Data\SiebelAdmin\Commands\file.txt"') do (
for /f "tokens=2 delims==" %%b in ("%%a") do (
for %%c in (%%b) do (
echo in loop
set str=%%c
echo %%c
echo.!str!
set str=!str:~-6!
echo.!str!
)))
endlocal & set str=%str%
In between the setlocal/endlocal block, delayed variable expansion is active. To actually use this feature enclose the variables by !! rather than %%.
Since setlocal sets up a new namespace for variables, the compound endlocal & set statement is required to transfer the value of str beyond the block.

Using if condition inside a for loop using batch script

I have a script which need to be iterating through the file and checking a condition, when it meets condition every time corresponding values should be stored to a variable and displayed.
for /f "tokens=1,6,8 delims= " %%D in (test.txt) do (if %%D==01 (set x=%%I
set y=%%K)
echo %x% %y%)
Can some one help me on the above code?
The tokens are asigned to the nominated control (%%D) and then %%E, %%F.
Solution: replace %%I with %%E and %%K with %%F
BUT within a block statement ( a parenthesised series of statements) %var% refers to the value of var at the time the statement is parsed, that is, checked for validity, not at run-time, that is, as the value changes through the operation of the loop.
To see the value as it changes, the easiest method is to change the echo statement to
call echo %%x%% %%y%%
For more information, see any of hundreds of SO responses on the subject of delayed expansion.
It could be done as below.
#echo off
setlocal enableextensions enabledelayedexpansion
for %%F in ("C:\Users\JOhn\Desktop\Check\*.txt") do SET input=%%F
for /f "tokens=1-10 delims= " %%a in (%input%) do (
if %%a==01 (
set "_y=%%f"
set "_z=%%h")
echo %%a %%b %%c %%d %%e %%f %%g %%h %%i %%j !_y! !_z!)>>temp.txt

Batch File - Getting Volume Labels in a For Loop

I'm trying to set up a batch file that will iterate through the local drives on a PC and get the Volume Name of each drive into an Environment Variable that I can then use for further processing.
Here's what I've got so far, but it doesn't return the correct value for the volume label into the VLABEL1 variable inside the For loop.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /f "tokens=2 delims==" %%D in ('wmic logicaldisk where "drivetype=3" get name /format:value') do (
echo Processing Drive %%D
call :GetLabel %%D VLABEL1
echo The Label of Volume %%D is !VLABEL1!
echo.
)
endlocal
goto :EOF
:GetLabel
setlocal
for /f "tokens=5*" %%A in ('vol "%~1"^|find "Volume in drive "') do (
set VOLLABEL=%%B
)
set %2=%VOLLABEL%
endlocal
goto :EOF
Needles to say I've tried various combinations & permutations, but without success, so I'd appreciate any suggestions.
Try to run this from command line and you will see the reason
for /f "tokens=2 delims==" %a in ('wmic logicaldisk where "drivetype=3" get name /format:value') do echo .[%a].
There is an aditional carriage return at the end of each of the lines.
So, it is necessary to eliminate it before calling your subroutine.
for /f "tokens=2 delims==" %%A in (
'wmic logicaldisk where "drivetype=3" get name /format:value'
) do for %%D in (%%A) do (
....
)
...
The aditional for loop removes the CR so now you have the correct value in the variable to call your subroutine.
Now, inside your subroutine,
set %2=%VOLLABEL%
endlocal
The endlocal cancels the assignment of the upper line. It is its mission, cancel changes made in the environment since the previous setlocal. So, it is necessary to both, change the variable and cancel the non required changes. To do so, the fact that the parser works on lines can be used. So the code should be written as
endlocal & set "%2=%VOLLABEL%"
The full line is readed, at parse time all the value reads are replaced with values and then the line is executed. So, when the second command in the line (the set) is executed, there is no access to the %VOLLABEL% variable. This read has been replaced with the value of the variable before the endlocal were executed.

Resources