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.
Related
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%"
I am creating a script that will get the computer version and serial number, turn it into variables, and then combine them together to create the new hostname.
However, the WMIC command for the serial number returns "T300"-"FDHGFJ "
Running just the serial number WMIC alone (without the does not "wmic csproduct get version") does not include the extra spaces.
I've tried looping it around one more time as other posts suggest but no luck.
Below is the full code.
#ECHO ON
PUSHD "%~dp0"
setlocal EnableDelayedExpansion
for /f "usebackq skip=1 tokens=*" %%i in (`wmic bios get serialnumber ^| findstr /r /v "^$"`) do set "serialn=%%i"
for /f "usebackq skip=1 tokens=2 delims= " %%a in (`wmic csproduct get version ^| findstr /r /v "^$"`) do set "modeln=%%a"
ECHO "%modeln%"-"%serialn%" >>test.txt
POPD
exit
I want the final result to be "T300"-"FDHGFJ" as it might get implemented into a task sequence.
You can try a bit of a hack by setting the variable only if not defined. I removed "tokens=*" and "delims=" as that will get the entire line. We then just do substitution on whitespace.
#echo off
set serialn=
set modeln=
for /f "usebackq skip=1" %%i in (`wmic bios get serialnumber`) do if not defined serialn set "serialn=%%i"
for /f "usebackq skip=1" %%a in (`wmic csproduct get version`) do if not defined modeln set "modeln=%%a"
echo "%modeln: =%"-"%serialn: =%">>test.txt
Note the output of second string on my device wmic csproduct get version has only one value and therefore I had to change the string, if yours really has 2 tokens then you should use your original string:
for /f "usebackq skip=1 tokens=2" %%a in (`wmic csproduct get version`) do if not defined modeln set "modeln=%%a"
The wmic command with its get verb might pad the returned data by trailing SPACEs, which I assume you want to have removed without removing SPACEs in the returned values themselves.
To achieve this you need to change the output format by adding the VALUE option, like this:
#echo off
setlocal EnableDelayedExpansion
cd /D "%~dp0."
for /F "tokens=1* delims==" %%I in ('wmic BIOS get SerialNumber /VALUE') do for /F "delims=" %%K in ("%%J") do set "serialn=%%K"
for /F "tokens=1* delims==" %%I in ('wmic CSProduct get Version /VALUE') do for /F "delims=" %%K in ("%%J") do set "modeln=%%K"
>> "test.txt" echo "%modeln%"-"%serialn%"
endlocal
exit /B
In addition I changed the following:
I placed another for /F loop inside of the one that parses the wmic output in order to avoid Unicode-to-ASCII/ANSI conversion artefacts by for /F, like orphaned carriage-return characters;
I replaced the pushd/popd pair by cd /D, because setlocal/endlocal already localises the environment, including the current working directory;
I added an explicit endlocal just to explicitly end the environment localisation (although this would be done upon termination of the batch script anyway);
I replaced exit by exit /B in order to only quit the batch file but not the parent cmd instance;
I put the redirection portion >> "test.txt" in front of the echo command in order to avoid the trailing space between the last closing " and >> (in your code) to be returned too;
As my initial comment regarding using /Value has already been implemented into an answer, this one expands upon using the wmic CSV format:
#Echo Off
SetLocal DisableDelayedExpansion
Set "DWM=%__AppDir__%wbem"
Rem Fixes 'Invalid XSL format (or) file name' errors in some Windows versions.
Set "CSV="
For /F "Delims=" %%A In ('"Dir /B/S/A-D "%DWM%\csv.xsl" 2>Nul"'
)Do If Not Defined CSV Set "CSV=%%A"
If Not Defined CSV Exit /B
Set "Serial#=Null"
For /F "Skip=2Tokens=1*Delims=," %%A In (
'""%DWM%\wmic.exe" BIOS Get SerialNumber /Format:"%CSV%" 2>Nul"'
)Do For /F Tokens^=* %%C In ("%%~B")Do Set "Serial#=%%~C"
Set "Model#=Null"
For /F "Skip=2Tokens=1*Delims=," %%A In (
'""%DWM%\wmic.exe" CSProduct Get Version /Format:"%CSV%" 2>Nul"'
)Do For /F Tokens^=* %%C In ("%%~B")Do Set "Model#=%%~C"
Echo "%Model#%"-"%Serial#%">>"test.txt"
Pause
The following code is ment to get Chrome current version into a runtime variable. What am I missing here?
for /f %%i in ('wmic datafile where name="C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" get Version /value') do set VAR=%%i
echo %VAR%
pause
The result :
C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe - Invalid alias
verb.
Quoting gets a little different when inside a FOR command. Need the nested FOR to get rid of the empty lines.
#echo off
for /f "delims=" %%G in ('wmic datafile where "name='C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'" get Version /value ') do (
FOR /F "tokens=2 delims==" %%H in ("%%~G") do set var=%%H
)
echo %var%
pause
I am trying to detect the drive letter that contains removable media (i.e. a memory stick) via wmic logicaldisk get caption^,description^,drivetype 2^>NUL then I want to use dir to get the name of the file on the drive (there should only be one but I don't know what the name is) and pass that filename into netsh wlan add profile.
I have this batch file I have written:
#echo off
for /F "usebackq tokens=1,2,3,4 " %%i in (`wmic logicaldisk get caption^,description^,drivetype 2^>NUL`) do (
if %%l equ 2 (
SET file= | dir %%i /b
echo %%i\%file%
netsh wlan add profile filename="%%i\%file%" user=all
)
)
pause
and I expect the output to be D:\%some file%.xml but I am only getting D:. It seems that the variable %file% is not being set correctly.
I've tried many variations but I can't get it to set properly. Any suggestions welcome!
Although I do not exactly know what you are trying to accomplish, I decided to provide a modified script in which some issues are fixed. As soon as you edit your question and clarify it I will update my answer accordingly.
So here is the updated code:
#echo off
setlocal EnableDelayedExpansion
for /F "skip=1 delims=" %%L in ('
2^> nul wmic LogicalDisk ^
WHERE ^(DriveType^=2^) ^
GET Caption^,Description
') do (
for /F "tokens=1,*" %%I in ("%%L") do (
set file=myfile.xml
echo %%I\!file!
)
)
endlocal
pause
skipped header line from wmic by the skip option of for /F;
implemented a WHERE clause to the wmic command line to filter out DriveType and so to not need the if condition;
put token Description to the last position by removing DriveType, so for /F token string * can be used, as the property value may contain delimiters (spaces) on its own (although %%J is not used in the loop then);
added a second for /F loop to remove artefacts from conversion of Unicode output of wmic by first for /F;
set variable file to a constant value myfile.xml just to demonstrate delayed expansion (see also setlocal command); of course file could be set in advance outside of the loop here;
removed the pipe stuff SET file= | dir %%i /b as I have no clue what this is intended to do;
Update
After the question has been revised and clarified I can provide a solution for the requested task:
#echo off
for /F "skip=1 delims=" %%L in ('
2^> nul wmic LogicalDisk WHERE ^(DriveType^=2^) GET Caption
') do (
for /F "tokens=1" %%I in ("%%L") do (
for /F "eol=| delims=" %%F in ('dir /B "%%I\"') do (
set "FILE=%%I\%%F"
)
setlocal EnableDelayedExpansion
netsh wlan add profile filename="!FILE!" user=all
endlocal
)
)
pause
removed property Description from wmic command line as it is not used anyway;
inserted another for /F loop to capture the output of dir /B;
the built file path in FILE is passed over to netsh wlan add profile using delayed expansion, because this is required when writing and reading a variable in the same block of code; normal expansion would return the value present at the time the entire block is parsed by the command interpreter; I enabled delayed expansion inside of the loop structure in order to avoid loss of exclamation marks in the file name, because while reading for variables like %%F, delayed expansion need to be disabled to not lose such characters;
actually the interim variable FILE and so delayed expansion would not be necessary if you could guarantee that there is one file available on each drive; if this is the case, remove the setlocal and endlocal command lines, move the netsh command line into the inner-most for /F %%F loop, replace !FILE! by %%I\%%F and remove the set command line;
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.