Why do I get different results running the batch file? - batch-file

I have batch file:
#echo off
set vers=0.0
FOR /F "USEBACKQ" %%A IN (`wmic datafile where name^="C:\\Windows\\System32\\msiexec.exe" get Version`) do (set vers=%%A)
echo %vers%
#pause
Windows XP (SP2):
3.0.3790.2180
Windows Vista (SP1), Windows XP (x64):
ECHO is off.
How to fix that in both situations the batch file executed correctly?

#echo off
setlocal enableextensions
set vers=0.0
FOR /F "tokens=2 delims== usebackq" %%A IN (
`wmic datafile where name^="C:\\Windows\\System32\\msiexec.exe" get Version /value ^| find "="`
) do set "vers=%%A"
echo %vers%
endlocal
pause
It just asks wmic to output data in the format key=value, filters the output of the wmic command searching only lines with = and splits the lines using this character as token delimiter. The first token (the key) is ignored, and second token (the value) is assigned to vers variable.

Related

Batch file to collect UUID and Serial number

I have been using this batch file to collect the Serial number and UUID number and output to a CSV and now it no longer works.
#echo off
set outputfile="Y:\HP\UUDI.csv"
for /f "delims== tokens=2" %%i in ('wmic csproduct Get "UUID" /value') do SET CSPRODUCT=%%i
for /f "delims== tokens=2" %%i in ('wmic bios get serialnumber /value') do SET SERIAL=%%i
echo UUID,Serial,>>%outputfile%
echo %CSPRODUCT%,%SERIAL%,>>%outputfile%
If someone can look at this file and help me understand what went wrong I would appreciate it
I don't understand what did you mean by "No Longer Works" ? Please be more explicit when you ask a question !
here is a test and tell me if this works or not on your side and i will edit this aswer according to your response !
#echo off
set "outputfile=%~dp0UUDI.csv"
#for /f %%i in (
'wmic csproduct Get "UUID" /value ^& wmic bios get serialnumber /value'
) do (
#for /f %%j in ("%%i") do set "%%j" & echo "%%j"
)
echo UUID,SerialNumber>"%outputfile%"
echo %UUID%,%SERIALNumber%>>"%outputfile%"
If exist "%outputfile%" Start "" "%outputfile%" & Exit
The only reason I can see for your provided code to change its behavior, is that which was commented already by Mofi. That is, you've somehow caused the location of WMIC.exe to have been removed from the %Path% environment.
I have decided to provide an alternative method of achieving your goal using your chosen command utility WMIC.exe, and using its full path, to prevent such a reliance in future.
The WMIC command is traditionally one of the slower ones, so this method invokes it only once. All you should need to do is Echo your commands, currently on lines 12and 14, each separated as in line 13. If any of your commands requires to Get more than one property, you should separate those with caret escaped commas, e.g. Get Property1^,Property2. The results, (subject to line/environment length limitations), will then be saved to variables, %Title%, and %Record%, which can later be output to a file outside of the loop. Note: all commands should use /Value, or the more correct, /Format:List.
Example, (don't forget to adjust your output file path on line 4 as needed):
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "outputfile=Y:\HP\UUDI.csv"
Set "WMIC=%SystemRoot%\System32\wbem\WMIC.exe"
Set "FIND=%SystemRoot%\System32\find.exe"
Set "Title="
Set "Record="
For /F "Tokens=1,* Delims==" %%G In ('
(
Echo CSProduct Get UUID /Value
^&
Echo BIOS Get SerialNumber /Value
^)
^| %WMIC% ^| %FIND% "="
') Do (If Not Defined Title (Set "Title=%%G") Else (
SetLocal EnableDelayedExpansion
For /F "Tokens=*" %%I In ("!Title!") Do (EndLocal
Set "Title=%%I,%%G"))
If Not Defined Record (Set "Record=%%H") Else (
SetLocal EnableDelayedExpansion
For /F "Tokens=*" %%I In ("!Record!") Do (EndLocal
Set "Record=%%I,%%H")))
If Defined Title ( Echo %Title%
Echo %Record%) 1>"%outputfile%"

How to create a batch command to make a .zip file name in UTC Time

How can we create a zip file in UTC time or current time (-) minus 3 hours from the existing time.
The command which I use is below pasted:
echo on
for /f "tokens=3,2,4 delims=/- " %%x in ("%date%") do set d=%%z%%x_%%y
set date=%d%
for /f "tokens=1,2,3 delims=:. " %%x in ("%time%") do set t=%%x%%y%%z
set time=%t%
Echo zipping...
"C:\Program Files\7-Zip\7z.exe" a -tzip "C:\DFD\JZR_%d%%t%.zip" "C:\DFD\*.txt"
del "C:\DFD*.txt" /s /f /q
echo Done!
if anybody have idea, please help.
Try this:
#echo off & for /f "usebackq tokens=* delims= " %%a in (`%windir%\system32\windowspowershell\v1.0\powershell.exe -noprofile -command "& {(Get-Date).ToUniversalTime().AddHours(-3).ToString('yyyyMM_dd')}`) do set "d=%%a"
for /f "usebackq tokens=* delims= " %%a in (`%windir%\system32\windowspowershell\v1.0\powershell.exe -noprofile -command "& {(Get-Date).ToUniversalTime().AddHours(-3).ToString('hhmmss')}"`) do set "t=%%a"
echo Zipping.... & "C:\Program Files\7-Zip\7z.exe" a -tzip "C:\DFD\JZR_%d%%t%.zip" "C:\DFD\*.txt" & del /q /f /s "C:\DFD*.txt" & echo Done!
Don't overwrite DATE and TIME they are environment variables.
Used inline powershell to get UTC date and time in your format 3 hours back.
One possible solution to get UTC time is using WMIC:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1* delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_UTCTime GET /VALUE') do if not "%%J" == "" set "%%I=%%J"
rem Insert a leading 0 if one of the two digit values has just one digit.
if "%Month:~1%" == "" set "Month=0%Month%"
if "%Day:~1%" == "" set "Day=0%Day%"
if "%Hour:~1%" == "" set "Hour=0%Hour%"
if "%Minute:~1%" == "" set "Minute=0%Minute%"
if "%Second:~1%" == "" set "Second=0%Second%"
rem Use the date/time values in format yyyy-MM-dd_hh_mm_ss in ZIP file name.
"%ProgramFiles%\7-Zip\7z.exe" a -tzip "C:\DFD\JZR_%Year%-%Month%-%Day%_%Hour%_%Minute%_%Second%.zip" "C:\DFD\*.txt"
endlocal
Please run in a command prompt window once wmic path win32_utctime get /value to see what WMIC outputs in Unicode with UTF-16 LE encoding converted with a quirks by cmd.exe to ASCII encoding which requires the IF condition. See my answer on How to remove new lines in batch file? for details about the character encoding conversion problem worked around here with the IF condition.
It would be also possible to use as third line:
for /F "tokens=1* delims==" %%I in ('%SystemRoot%\System32\wbem\wmic.exe PATH Win32_UTCTime GET Day^,Month^,Year^,Hour^,Minute^,Second /VALUE') do if not "%%J" == "" set "%%I=%%J"
Then just the six date/time values of interest would be output by WMIC whereby character ^ left to each comma is necessary to pass the command line with the commas correct to the command process started in background which executes the WMIC command, i.e. to execute in background:
C:\Windows\System32\cmd.exe /c C:\Windows\System32\wbem\wmic.exe PATH Win32_UTCTime GET Day,Month,Year,Hour,Minute,Second /VALUE
The commas would be otherwise interpreted by cmd.exe processing the batch file as argument separators inside set of command FOR and would replace each , by a space character which would make the WMIC command invalid.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
if /?
set /?
setlocal /?
wmic /?
wmic path /?
wmic path win32_utctime /?
wmic path win32_utctime get /?

Get only numbers in version from dll file

I'm trying to get the vertion of a .dll file, but only the number of the version.
I find the code
wmic datafile where name='C:\\...\\MY_FILE.dll' get version
This code returns:
Version
3.56.0.1
I need the return to be only '3.56.0.1' and this could be saved in a variable for i'll can call in a echo after.
set var="HOW DO I DO?"
echo %var%
How can I get this?
I can use the code below too, but in this format I think its harder
wmic datafile where name='C:\\...\\MY_FILE.dll' get version /format:list
This code returns:
Version=3.56.0.1
And similarly to those posted, with minor differences.
A batch-file:
#For /F "Delims=" %%A In ('WMIC DataFile Where "Name='C:\\...\\MY_FILE.dll'" Get Version /Value 2^>Nul')Do #For /F "Tokens=*" %%B In ("%%A")Do #Set "%%B"
#Echo(%Version%&Pause
A cmd version:
For /F "Delims=" %A In ('WMIC DataFile Where "Name='C:\\...\\MY_FILE.dll'" Get Version /Value 2^>Nul')Do #For /F "Tokens=*" %B In ("%A")Do #Set "%B"
Where the variable %Version% should be set to the local environment.
You'll need to parse with a for /f.
And another for /f to repair broken WMIC output.
On cmdline (using a windows dll):
For /f "usebackqdelims=" %A in (`wmic datafile where name^='C:\\Windows\\System32\\authui.dll' get version /format:list^|findstr "Version"`) do #For /F "delims=" %B in ("%A") do #Set "%B"
set Version
Version=10.0.17134.1
In a batch file double the percent signs of the for meta variable(s)
So you would require a for loop to do this.. see more help on it by running for /? from cmd.exe
#echo off
for /f "tokens=1,* delims==" %%i in ('wmic datafile where name^="C:\\...\\MY_FILE.dll" get version /format:list') do if not defined var set var=%%j
echo %var%
Note that the help will not assist you with the caret escape character used on the = which however you can find help on here at SO.
You should use:
#echo off
for /F "delims== tokens=2" %%A IN ('wmic datafile where name^="C:\\...\\MY_FILE.dll" get version /format:list') do (
for %%B IN ("%%A") do set "var_name=%%~B"
)
echo %var_name%
which loops through your command and finds the second token according to the delimeter specified (=).
Due to wmic unusual line endings (<CR><CR><LF>), you should use a double for loop.
If you scripted in PowerShell, you could use:
$var = [Diagnostics.FileVersionInfo]::GetVersionInfo('C:/.../MY_FILE.dll').ProductVersion
If you want to do it in a .bat file script, there is some overhead.
C:>TYPE gv.bat
#ECHO OFF
FOR /F "delims=" %%v IN ('PowerShell -NoLogo -NoProfile -Command ^
"[Diagnostics.FileVersionInfo]::GetVersionInfo('C:/Windows/System32/dfscli.dll').ProductVersion"') DO (
SET "var=%%~v"
)
ECHO var is +++%var%+++
C:>CALL gv.bat
var is +++10.0.17763.1+++

how to write a batch file using file inputs as a variable in a for loop

I know c++ pretty well and unix commands (bourn shell) fairly well, but I am very unfamiliar with batch files.
I'm working on getting serial numbers for all of our machines to verify that they are named properly, and are issued to the correct user. Please note that this is my first post and am just giving you the down and dirty code.
This is what I have so far (good for one computer)
hostname >> computerlog.txt rem send the pcname to txtfile computerlog
rem get serial number from bios
wmic bios get serialnumber >> computerlog.txt
rem get serial number from network location (pcname is a network pc)
wmic /user:johnnyboy/node:pcname bios get serialnumber >> computerlog.txt
What I would like to do is use a loop to read the names in and store them as a variable, run the command above, and output the name followed by serial number to a text file.
I don't know how to use a loop or create a variable.
Thank you for all of your help.
Provided the data in the file YourData.csv has this format
"NODENAME","USERNAME","PASSWORD"
"Computer1","Johnnyboy","secret"
This batch should do what you want:
#Echo off&SetLocal EnableExtensions EnableDelayedExpansion
(Echo "NODENAME","SerialNumber"
For /f "usebackq skip=1 tokens=1-3 delims=," %%A in (
"YourData.csv"
) Do For /f "tokens=2 delims==" %%S in (
'wmic /NODE:%%A /USER:%%B /PASSWORD:%%C bios get serialnumber /value^|find "="'
) Do For /f "delims=" %%T in ("%%S") Do Echo %%A,"%%T"
) > "YourSerials.csv"
Since the wmic output is in UTF16 and one for loop can't compensate the conversion remnants cr,cr,lf the third for will do this.
Sample output:
> type YourSerials.csv
"NODENAME","SerialNumber"
"HP-G1610","CZxxxyyyPM "
Be warned that wmic here was terribly slow.
snippets:
set "varName=varValue"
:loopName
:: do something
goto:loopName
:: take each line of log to %%t - variable of cycle
for /f "usebackq delims=" %%t in ("computerlog.txt") do echo.%%t
example:
setlocal enabledelayedexpansion
set counter=0
for /f "usebackq delims=" %%t in ("computerlog.txt") do (
set "var!counter!=%%t"
set /a counter+=1
)
set var

Batch script to find System make and model then run another script

Im trying to make a batch script to find out a computers manufacture, model and then execute another batch script that I have already created.
So far I have this to get the Computer Manufacturer:
FOR /F "tokens=2 delims='='" %%A in ('wmic ComputerSystem Get Manufacturer /value') do SET manufacturer=%%A
and this to get the model:
FOR /F "tokens=2 delims='='" %%A in ('wmic ComputerSystem Get Model /value') do SET model=%%A
Now I'm not sure how to use the make and models as variables within an IF statement.
The first issue: how-to assign wmic output to an environment variable:
for /f "tokens=1* delims==" %%a in (
'wmic computersystem get model /value'
) do for /f "delims=" %%c in ("%%~b") do set "model=%%c"
echo %model%
Where the for loops are
%%a to retrieve the model (in the second token, %%b)
%%c to remove the ending carriage return in the value returned (wmic behaviour: each output line ends with 0x0D0D0A instead of common 0x0D0A)
Another potential issue: how-to reference an environment variable, if assigned within a command block (in parentheses):
#ECHO OFF >NUL
SETLOCAL enableextensions disabledelayedexpansion
set "model=nothing assigned yet"
for /f "tokens=1* delims==" %%a in (
'wmic computersystem get model /value'
) do for /f "delims=" %%c in ("%%~b") do (
set "model=%%c"
echo %model% :referenced using percent signs within a command block
SETLOCAL enabledelayedexpansion
echo !model! :referenced using exclamation marks within a command block
ENDLOCAL
)
echo %model% :referenced using percent signs out of a command block
ENDLOCAL
goto :eof
Run above script to see EnableDelayedExpansion effect:
==>D:\bat\StackOverflow\29893432.bat
nothing assigned yet :referenced using percent signs within a command block
System Product Name :referenced using exclamation marks within a command block
System Product Name :referenced using percent signs out of a command block
==>
Follow Stephan's comment on using If statement.

Resources