Batch file to collect UUID and Serial number - batch-file

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%"

Related

How to set multiple variables from output in for /f loop in batch script? [duplicate]

This question already has an answer here:
Variables are not behaving as expected
(1 answer)
Closed 2 years ago.
I'm trying to write a script but I'm really bad at writing the batch scripts. I'm trying to create a script that recognizes local hard drives and puts the letter of those hard drives in a variable, and after that I use that variable in another for loop to decrypt the hard drive if it's encrypted.
Example:
:check
for /f "tokens=2 delims==" %%d in ('wmic logicaldisk where "drivetype=3" get name /format:value') do (
set vvv=%%d
for /f "tokens=1,*" %%A in ('manage-bde -status %vvv% ^| findstr Conversion') do set var1=%%B
Rem Try to find if value is Encrypted or not
echo %vb1%|find "Encrypted" >nul
if errorlevel 1 ( goto :check) else ( goto :decrypt_c))
#Echo Off
:check
for /f "tokens=2 delims==" %%d in ('wmic logicaldisk where "drivetype=3" get name /format:value') do (
echo %%d
manage-bde -off %%d )
pause
That code works fine until echo %%d, when I try to put it into manage-bde command does not work...When I have for example 3 hard drives, I will do loop and turn off BitLocker for all partitions. Thanks!
Perhaps you'd be better off using the Win32_EncryptableVolume Class.
This example will create variables, e.g. %EncryptedDriveLetter[1]%, %EncryptedDriveLetter[2]%, %EncryptedDriveLetter[3]% etc., with the respective content of e.g. C:, E:, F:
#Echo Off & SetLocal EnableExtensions DisableDelayedExpansion
For /F Delims^== %%G In ('2^> NUL Set EncryptedDriveLetter[')Do Set "%%G="
For /F Delims^= %%G In ('^""%SystemRoot%\System32\wbem\WMIC.exe" ^
/NameSpace:\\root\CIMv2\Security\MicrosoftVolumeEncryption Path ^
Win32_EncryptableVolume Where ^
"ConversionStatus!='0' And EncryptionMethod!='0' And VolumeType<'2'" ^
Get DriveLetter 2^> NUL ^| "%SystemRoot%\System32\find.exe" ":"^"'
)Do (Set /A i+=1 & SetLocal EnableDelayedExpansion
For %%H In (!i!) Do EndLocal & Set "EncryptedDriveLetter[%%H]=%%G")
Set EncryptedDriveLetter[ & Pause
Notes: This must be run 'As administrator', and the last line is included just to provide some visual output. You would of course, replace that, with the rest of your script.
Just to be sure that you understand why I provided this methodology; if you were simply wanting to decrpt the encrypted drives, you don't need a for loop, or variables or manage-bde. You would just change the Get method to Call and use Decrypt.
For example:
#"%SystemRoot%\System32\wbem\WMIC.exe" /NameSpace:\\root\CIMv2\Security\MicrosoftVolumeEncryption Path Win32_EncryptableVolume Where "ConversionStatus!='0' And EncryptionMethod=!'0' And VolumeType<'2'" Call Decrypt
Just to mention, if the protection status prior to decryption was 1, i.e. Protection On, upon successful completion the protection status will be changed to 0, i.e. Protection Off.

Eliminate the extra spaces from WMIC

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

how to assign device id (COMn or LTPn) in a variable in batch script

The device ID for printer I am getting and assigning it to a variable printerPort
for /f "tokens=* skip=1" %%a in ('wmic path Win32_SerialPort get DeviceID') do set printerPort=%%a
echo %printerPort%
Output :
set printerPort=COM1
set printerPort=
echo
How to get device Id COM1 in variable printerPort?
There are two mentions with your question, the first is that the output you have given does not match what your code will output. The second is that WMIC outputs with a non standard line feed/carriage return sequence, the most efficient way to counter this is to pass the result through another loop.
Either like this:
#Echo Off
For /F "Skip=1Delims=" %%A In ('WMIC Path Win32_SerialPort Get DeviceID'
) Do For /F "Tokens=*" %%B In ("%%A") Do Set "printerPort=%%B"
Echo %printerPort%
Or sometimes, (in this case), like this:
#Echo Off
For /F "Skip=1Delims=" %%A In ('WMIC Path Win32_SerialPort Get DeviceID'
) Do For %%B In (%%A) Do Set "printerPort=%%B"
Echo %printerPort%
The output is just the commands in your batch file being echoed. You can see the loop runs twice. You need to come out after the first line:
for /f "tokens=* skip=1" %%a in ('wmic path Win32_SerialPort get DeviceID') do (
set printerPort=%%a
goto exit1
)
:exit1
echo %printerPort%

Batch file get result into runtime variable

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

Redirect output of batch command to an if statement (and string error?)

After a bit of research I've found what looks to be a good work around for getting the output of a batch command and setting it to a variable. I've used a bit of example code from a blog: Just Geeks to start. My eventual goal is to detect the model of computer the script is run on and do something based on which model. After a bit of modification I have:
FOR /F "tokens=* skip=1 delims=" %%A in ('wmic csproduct get name') do (
if %%A == "Vostro 430" goto vostro430
if %%A == "Optiplex 380" goto optiplex380
)
exit
:vostro430
REM do some stuff here
:optiplex380
REM do some stuff here
Its useful to note that wmic csproduct get name > sometextfile.txt on a Vostro 430 (dell computer model) a text file that looks like this:
Name
Vostro 430
So the code above "should" ignore the first line and compare "Vostro 430" in the if statements and then jump to one of the lables. It seems that I have some error though if I echo the out the batch script I can see that it is evaluating %A as a blank:
== "Vostro 430" goto vostro430
== "Optiplex 380" goto optiplex380
Any ideas where I messed up? I suspect some sort of string or syntax issue but I haven't been able to pin it down.
As aphoria pointed you need quotes around the %%A.
But the main problem is the output of the wmic command,
as it outputs in unicode format.
Try this code to see the effect
FOR /F "tokens=* skip=1 delims=" %%A in ('wmic csproduct get name') do (
echo .............1%%A2
)
The output will be something like
2............1TravelMate 7720
2............1
What happens here? The lines are appended with a <CR> character, so the 2 will be print at position 1 of the line.
You can avoid this with simply removing the last character from %%A
setlocal EnableDelayedExpansion
FOR /F "tokens=* skip=1 delims=" %%A in ('wmic csproduct get name') do (
set "line=%%A"
set "line=!line:~0,-1!"
echo "!line!"
)
Or you use the TYPE command to normalize the output
wmic csproduct get name > wmicOutput.tmp
FOR /F "tokens=* skip=1 delims=" %%A in ('type wmicOutput.tmp') do (
echo Works too "%%A"
if "%%A"== "Vostro 430" goto :Vostro
)
Try adding quotes around %%A...like this:
if "%%A" == "Vostro 430" goto vostro430
if "%%A" == "Optiplex 380" goto optiplex380
The standard way to get a whole line in for /F command is via tokens=* or delims=", but not both. Use only delims this way:
FOR /F "skip=1 delims=" %%A in ('wmic csproduct get name') do ( ...
Also, you must add quotes in %%A value for the correct comparison in the if command, as aphoria said.

Resources