How do you edit a text outcome in a batch file - batch-file

Im new to learning to code batch files.
Basically I have this script
#echo off
echo.
echo Current Serials-
echo.
wmic bios get serialnumber
wmic diskdrive get serialnumber
wmic baseboard get serialnumber
pause
Which has this output
Current Serials-
SerialNumber
Insert Serial Number Here
SerialNumber
Insert Serial Number Here
Insert Serial Number Here
SerialNumber
Insert Serial Number Here
But I want the output to look like this
Current Serials-
Bios SerialNumber- Insert Serial Number Here
Diskdrive SerialNumber- Insert Serial Number Here, Insert Serial Number Here
BaseBoard SerialNumber- Insert Serial Number Here
So how do I do that?

The simplest approach is using a for /F loop to catch and split the output of wmic
#Echo off
Echo(Current Serial numbers:
For %%A in (Bios Diskdrive Baseboard) Do (
For /F "Skip=1 Delims=" %%G in ('WMIC %%A get serialnumber') Do (
For %%O in (%%G)Do Echo(%%A Serial Number: %%O
))

To process files, strings or command outputs, use a for loop. See for /? (then read it again - it's one of the mightiest commands in cmd. Any time you invest into understanding it is a good investment.)
#echo off
setlocal enabledelayedexpansion
set "drives=Diskdrive "
for /f %%a in ('wmic diskdrive get serialnumber^|findstr .') do set "drives=!drives!%%a, "
echo %drives:~0,-2%
As you are new to cmd, let me suggest SS64. Save it as favorite and visit it often.

You could probably do it in a single line from your batch-file, with the help of powershell:
#PowerShell -NoP "Write-Host Current Serials-`r`n`r`nBIOS - $(GCim CIM_BIOSElement).SerialNumber`r`nPrimary Disk - $(GCim CIM_DiskDrive -F \"DeviceID Like '%%PHYSICALDRIVE0'\").SerialNumber.Trim()`r`nMotherboard - $(Get-CimInstance -Query \"Select * From CIM_Card Where Name='Base Board'\").SerialNumber"

Because serialnumbers contains numeric, but the empty lines and the word Serianumber does not, I use findstr to determine which lines are serials and only echo them.
#echo off
for %%i in (Bios Diskdrive Baseboard) do (
for /f "delims=" %%a in ('wmic %%~i get serialnumber ^| findstr /r "[0-9]"') do echo %%~i Serialnumber- %%a
)

Just another option if you just want to use the standard output from the WMIC commands.
set /p ".=BIOS "<nul&wmic bios get serialnumber /value|more|findstr /I "serial"
set /p ".=DISKDRIVE "<nul&wmic diskdrive get serialnumber /value|more|findstr /I "serial"
set /p ".=BASEBOARD "<nul&wmic baseboard get serialnumber /value|more|findstr /I "serial"
Which would give you output like this.
BIOS SerialNumber=3ZB80R2
DISKDRIVE SerialNumber=0100_0000_0000_0000_8CE3_8E04_0016_7812.
BASEBOARD SerialNumber=/3ZB80R2/TW320709A3011C/
Or you could simplify it with a FOR command.
FOR %%G IN (BIOS DISKDRIVE BASEBOARD) DO set /p ".=%%G "<nul&wmic %%G get serialnumber /value|more|findstr /I "serial"

If you need to get all disk serial numbers on the same line also delimited by a comma...
#echo off
set "_str=SerialNumber"
echo\ & echo\Current Serials-
setlocal enabledelayedexpansion
set "_gets=Bios,DiskDrive,BaseBoard"
set "_wmic=%__AppDir__%wbem\wmic.exe"
echo\ & for %%i in (!_gets!)do for /f usebackq %%I in (`
!_wmic! %%i get %_str%^|%__AppDir__%Findstr.exe/v %_str%^|%__AppDir__%Findstr.exe .
`)do echo\%%i;|%__AppDir__%Findstr.exe /bl Bios; >nul && (echo\%%i !_str!- %%I
)|| if /i "%%~i" == "BaseBoard" (echo=!_sn!&& echo\%%~i !_str!- %%~I
)else if "!_sn!" == "" (set "_sn=%%~i !_str!- %%~I"
)else set "_sn=!_sn!, %%~I"
>con: %__AppDir__%TimeOut.exe -1|echo\Press any key to continue... & endlocal & goto :eOf
Results
Current Serials-
Bios SerialNumber- XTE03A187
DiskDrive SerialNumber- 50026B776605D1D3, ZDZ0QKMT
BaseBoard SerialNumber- S0AFF01XDTS
Press any key to continue...
In conventional layout:
#echo off
setlocal enabledelayedexpansion
echo\
echo\Current Serials-
echo\
for %%i in (Bios,DiskDrive,BaseBoard)do (
for /f usebackq %%I in (`%__AppDir__%wbem\wmic.exe %%i get SerialNumber^|%__AppDir__%Findstr.exe/v SerialNumber^|%__AppDir__%Findstr.exe .`)do (
echo\%%i;|%__AppDir__%Findstr.exe /bl Bios; >nul && (
echo\%%i SerialNumber- %%I ) || (
if /i "%%~i" == "BaseBoard" (
echo=!_sn!&& echo\%%~i SerialNumber- %%~I
) else if "!_sn!" == "" (
set "_sn=%%~i SerialNumber- %%~I"
) else (
set "_sn=!_sn!, %%~I"
)
)
)
%__AppDir__%TimeOut.exe -1
endlocal

Related

Batch Script is exporting weird characters

I am having an issue with a script. I will post it.
It runs fine till it gets to this line:
wmic diskdrive list full | findstr /B "Size=" >> %cd%ProductCodes\%Serial%\PCINFO.txt
This is what it sends to the file...
楓敺ㄽ㐲ㄱ㈱㤴㈹ര਍楓敺㈽㘵㔰㤲㘶〴ര਍
Any help would be appreciated
set drive=%cd:~0,3%
#echo off
for /F "skip=2 tokens=2 delims=," %%A in ('wmic systemenclosure get serialnumber /FORMAT:csv') do (set "serial=%%A")
mkdir %cd%ProductCodes\%Serial%
wmic path softwarelicensingservice get OA3xOriginalProductKey >> %cd%ProductCodes\%Serial%\Code.txt
wmic computersystem get model,manufacturer >> %cd%ProductCodes\%Serial%\PCINFO.txt
wmic cpu get name >> %cd%ProductCodes\%Serial%\PCINFO.txt
wmic ComputerSystem get TotalPhysicalMemory >> %cd%ProductCodes\%Serial%\PCINFO.txt
wmic diskdrive list full | findstr /B "Size=" >> %cd%ProductCodes\%Serial%\PCINFO.txt
cls
More %cd%ProductCodes\%Serial%\Code.txt
ECHO Open Windows Authentication?
Echo Y/N
SET /P M=Make Choice then press ENTER:
IF %M%==N GOTO :message
IF %M%==n GOTO :message
IF %M%==y GOTO :Start
IF %M%==Y GOTO :Start
:Start
start "C:\Windows\System32" slui.exe 3
pause
:message
CLS
ECHO Done!!
pause
Here is the requested output I get
Manufacturer Model
HP HP ZBook 15 G5
Name
Intel(R) Core(TM) i5-8300H CPU # 2.30GHz
TotalPhysicalMemory
16977272832
楓敺ㄽ㐲ㄱ㈱㤴㈹ര਍楓敺㈽㘵㔰㤲㘶〴ര਍
Have a look at this. I made quite a few changes, especially the way you accessed the format of wmic output formats. I also used choice instead of a bunch of if statements.
#echo off
for /f "tokens=2 delims==" %%A in ('wmic systemenclosure get serialnumber /FORMAT:list') do mkdir "%~dp0\ProductCodes\%Serial%" >nul 2>&1
for /f "tokens=2delims==" %%i in ('wmic path softwarelicensingservice get OA3xOriginalProductKey /format:list') do (echo %%i)>"%~dp0\ProductCodes\%Serial%\code.txt"
(wmic computersystem get model,manufacturer
wmic cpu get name
wmic ComputerSystem get TotalPhysicalMemory
wmic diskdrive get size
)> "%~dp0\ProductCodes\%Serial%\PCINFO.txt"
cls
More "ProductCodes\%Serial%\code.txt"
ECHO Open Windows Authentication?
choice /m "Open Authentication?"
if errorlevel 2 goto :message
goto :eof
:Start
start "C:\Windows\System32" slui.exe 3
pause
:message
cls
ECHO Done!!
pause
Side note on your original if %m%==y statements. You can use if /i to make the match case insensitive.. in other words, if /i "y"=="Y" will be true as well, but no longer relevant here if using choice.
You can give a try for this modification with piping the command More since the output of WMIC is UNICODE
#echo off
#for /F "skip=2 tokens=2 delims=," %%A in (
'wmic systemenclosure get serialnumber /FORMAT:csv'
) do (set "serial=%%A")
Set "LogFolder=%cd%ProductCodes\%Serial%"
MkDir "%LogFolder%">nul 2>&1
Set "Code=%LogFolder%\Code.txt"
Set "PCINFO=%LogFolder%\PCINFO.txt"
wmic path softwarelicensingservice get OA3xOriginalProductKey>"%code%"
(
wmic computersystem get model,manufacturer
wmic cpu get name
wmic ComputerSystem get TotalPhysicalMemory
wmic diskdrive list full ^| findstr /B "Size="
) | More>"%PCINFO%"
More "%Code%"
ECHO Open Windows Authentication?
Echo Y/N
SET /P M=Make Choice then press ENTER:
IF /I %M%==N GOTO :message
IF /I %M%==Y GOTO :Start
:Start
start "C:\Windows\System32" slui.exe 3
pause
:message
CLS
ECHO Done!!
pause

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

Speed up reading results in batch script

What I am trying to do, is speed up my reading results of batch file.
Am trying to get different values using netsh commands and then present them in my script console but it takes to long.
See below a small part of my script to get the idea. (this is just a small part, I'm actually getting around 50 different values and using more netsh commands)
Does anybody know a way to speed up the process?
.
.
.
netsh interface ipv4 show config %AdapterLAN% >temp
for /f "tokens=3" %%i in ('findstr "IP Address" temp') do set ip=%%i
echo. IP Address : %ip%
for /f "tokens=5 delims=) " %%i in ('findstr "Subnet Prefix" temp') do set mask=%%i
echo. Mask : %mask%
for /f "tokens=3" %%i in ('findstr "Gateway:" temp') do set gateway=%%i
echo. Gateway : %gateway%
for /f "tokens=1,5,6" %%a in ('findstr "DNS" temp') do set dns1=%%a&set dns5=%%b&set dns6=%%c
If "%dns1%"=="Statically" set dns=%dns5%
if "%dns1%"=="DNS" set dns=%dns6%
echo. DNS Server : %dns%
for /f "tokens=3" %%i in ('findstr "Gateway Metric" temp') do set GMetric=%%i
for /f "tokens=2" %%i in ('findstr "InterfaceMetric" temp') do set IMetric=%%i
set /a metricLAN=Gmetric + imetric
echo. Metric : %metricLAN%
for /f "tokens=3" %%i in ('find "DHCP enabled" temp') do set LANDHCP=%%i
If "%dns1%"=="Statically" set xx=Static
if "%dns1%"=="DNS" set xx=DHCP
If /i %LANDHCP%==No set LANDHCP=Static
if /i %LANDHCP%==YES set LANDHCP=DHCP
echo. Obtained IP : %LANDHCP%
echo. Obtained DNS : %xx%
for /f "tokens=3 delims=," %%a in ('getmac /v /fo csv ^| find """%AdapterLAN-without-Q%""" ') do set macLAN=%%a
echo. MAC-Addres : %macLAN%
del temp
.
.
.
netsh wlan show profile >temp
.
Do a similar process of getting values from another netsh command sent them
in the temp file …echo the one I want on the screen ..delete the file etc.
Next approach could be a bit faster (no temporary file(s), updated no multiple findstr):
#ECHO OFF >NUL
SETLOCAL enableextensions enabledelayedexpansion
set "AdapterLAN=wiredEthernet"
set "IMetric="
set "GMetric="
for /F "tokens=1,2* delims=:" %%G in ('
netsh interface ipv4 show config "%AdapterLAN%"^|findstr /N /R "^"
') do (
rem echo G="%%G" H="%%H" I="%%I"
if "%%I"=="" (
rem line 1 skip
rem line 2 = Configuration for interface
rem line 10 = DNS server #2 etc.
) else (
set "hh=%%H"
set "xx=!hh:IP Address=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "ip=%%i"
set "xx=!hh:Subnet Prefix=!"
if not "!hh!"=="!xx!" for /F "tokens=3 delims=) " %%i in ("%%I") do set "mask=%%i"
set "xx=!hh:Default Gateway=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "gateway=%%i"
set "xx=!hh:Gateway Metric=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "GMetric=%%i"
set "xx=!hh:InterfaceMetric=!"
if not "!hh!"=="!xx!" for /F "tokens=1*" %%i in ("%%I") do set "IMetric=%%i"
)
)
echo( IP Address : [%ip%]
echo( Mask : [%mask%]
echo( Gateway : [%gateway%]
set /a metricLAN=Gmetric + IMetric
echo( Metric : [%metricLAN%]
ENDLOCAL
goto :eof
Output:
==>D:\bat\SO\31356115.bat
IP Address : [192.168.1.100]
Mask : [255.255.255.0]
Gateway : [192.168.1.1]
Metric : [20]
==>
Edit
Here is another approach: unlike netsh, parsing the wmic command output seems to be a bit easier when used get verb together with /value switch as it's well defined and well structured. You could find here all the info as from netsh: next code snippet should read and make public a huge range of information about all enabled NIC adapter(s) in a defined local or remote computer:
#ECHO OFF >NUL
SETLOCAL enableextensions enabledelayedexpansion
set "NetCount=0"
set "compName=%computername%" :: local or remote computer name
set "compIDXs="
for /F "tokens=2 delims==" %%N in ('
wmic /node:"%compName%" NIC where "NetEnabled=TRUE" get InterfaceIndex /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%n in ("%%N") do (
for /F "tokens=*" %%G in ('
wmic /node:"%compName%" NIC where "InterfaceIndex=%%n" get /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%g in ("%%G") do set "_%%n%%g"
for /F "tokens=*" %%I in ('
wmic /node:"%compName%" NICCONFIG where "InterfaceIndex=%%n" get /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%i in ("%%I") do set "_%%n_%%i"
set /A "NetCount+=1"
set "compIDXs=!compIDXs! "%%n""
)
set _
rem sample of it:
echo compName=%compName% NetCount=%NetCount% compIDXs=%compIDXs%
for %%x in (%compIDXs%) do (
echo enabled InterfaceIndex=%%~x NetConnectionID=!_%%~xNetConnectionID!
for /F "tokens=1,2 delims={}," %%i in ("!_%%~x_IPAddress!") do echo ipv4=%%~i ipv6=%%~j
)
Read Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem to see why any wmic command output is parsed via a couple of nested for loops.

Get cpu utilization percentage using batch script

I have executed the below command in command prompt.
Input:
C:\>#for /f "skip=1" %p in ('wmic cpu get loadpercentage') do #echo %p%
8%
%
I have written the code to get only 8% in batch script like below,
call :Harddisk
call :CPU
Echo ^</TABLE^> ^</BODY^> ^</HTML^> >> %opfile%
pause
exit /b
:CPU
set wmih=#for /f skip=1 %p in ('wmic cpu get loadpercentage') do #echo %p% |Find /c /v ":"
ECHO wmih
for /f "tokens=1,2,3,4,5" %%a in ('"%wmih%"') do (
Echo ^<TR^> ^<TD^> >> %opfile%
Echo CPU Utilization: %%a >> %opfile%
Echo ^</TD^> ^</TR^> >> %opfile%
)
exit /b
I'm not getting proper output. Please help me to sort it out.
Thanks!!!
for /f "tokens=2 delims==" %%i in ('wmic cpu get loadpercentage /value ^|find "="') do echo set p=%%i
set p=%p:~0,-1%
echo %p%
Just to keep your structure
:CPU
set "wmih=#for /f "usebackq skip^^^=2 tokens^^^=2 delims^^^=^^^," %%p in (`wmic cpu get loadpercentage^^^,version /format^^^:csv`) do #echo(%%p%%"
ECHO %wmih%
for /f "tokens=1,2,3,4,5" %%a in ('"%wmih%"') do (
>>%opfile% Echo ^<TR^> ^<TD^>
>>%opfile% Echo CPU Utilization: %%a
>>%opfile% Echo ^</TD^> ^</TR^>
)
To be able to store the command inside a variable and then pass it to the for command, that will spawn another cmd instance to execute the command, you need a lot of scape characters just to handle the command execution.
It can be made easier
:CPU
for /f "skip=2 tokens=2 delims=," %%a in (
'wmic cpu get loadpercentage^,version /format^:csv'
) do (
>>%opfile% Echo ^<TR^> ^<TD^>
>>%opfile% Echo CPU Utilization: %%a%%
>>%opfile% Echo ^</TD^> ^</TR^>
)
In both cases, to remove the aditional CR character at the end of the retrieved value, the query request the output in csv format with an aditional field, so, the needed data is not at the end of the line and the value will not include the ending CR

How to get serial number from bios and compare it with a set of other serial number using Windows batch command?

I have a list of 100+ serial number.
What I want to do is: checking if the serial number of the computer I'm working on is in the list.
Is it possible to do this in Windows batch script ?
no need to iterate through every line in the file:
#echo off
for /F "tokens=2 delims==" %%s in ('wmic bios get serialnumber /value') do (
findstr "%%s" serials.txt
)
if %errorlevel%==0 ( echo Serialnumber found ) else ( echo Serialnumber not listed )
This command-line show the BIOS SerialNumber in my computer (Windows 8):
for /F "skip=1 tokens=3" %s in ('wmic bios list BRIEF') do echo %s
You may test it and adjust it until get what you want. For example:
#echo off
for /F "skip=1 tokens=3" %%s in ('wmic bios list BRIEF') do set serial=%%s
for /F "delims=" %%s in (serialList.txt) do if "%%s" equ "%serial%" goto found
echo Not found
goto :EOF
:found
echo OK
EDIT: I modified the program in order to include the serial numbers in the Batch file; I also used the modification in wmic parameters suggested by Stephan:
#echo off
for /F "tokens=2 delims==" %%s in ('wmic bios get serialnumber /value') do set serial=%%s
for %%s in (serial0 serial1 serial2 serial3 serial4 serial5 serial6 serial7 serial8 serial9
ser90 ser91 ser92 ser93 ser94 ser95 ser96 ser97 ser98 ser99 ser100 ser101) do (
if "%%s" equ "%serial%" goto found
)
echo Not found
goto :EOF
:found
echo OK
No need for a FOR loop if you use your list as the search strings and WMIC BIOS output as the target. I believe the serial number is always 10 characters, so no /I option is needed. But if the serial number length can vary, then the /I option is required due to a FINDSTR bug: Why doesn't this FINDSTR example with multiple literal search strings find a match?
wmic bios get serialNumber|findstr /blg:list.txt&&echo number found||echo number not listed
You can suppress the output of the serial number to the screen by redirecting the FINDSTR output to nul using >nul.

Resources