I'm creating a script to automatic update BIOS firmware for our Dell PC. We have multiple model here, so I need to check the model
C:\Users\me>wmic csproduct get name
Name
OptiPlex 3020
And also bios version
C:\Users\me>wmic bios get smbiosbiosversion
SMBIOSBIOSVersion
A09
Now I will put the bios updater somewhere on our network with filename format model_version.exe.
How should I do to get the model and version in to 2 variables and in the end I just run
//path/to/the/updater/"%model%_%version%.exe" /s /r
to update the bios automatically, if the PC already on the latest bios version, just skip the script?
Thank a lot for your help.
I recently had this same issue, needing to update a bunch of Acer laptops BIOS to fix the trackpads. Here is the solution I came up with, using the linked Batch file set wmi output as a variable from JosefZ's comment on your question.
By using /value switch of wmic we can get the wmic output on one line and then use 'for' with delims to tokenize it (split into two variables) and store the 2nd token as our desired variable.
Check if the file exists, then pass through to the "start" command so the bat file won't exit until after it has run the updater. (This is useful if combining with pushd to access a network path so the drive letter doesn't drop out)
for /f "tokens=2 delims==" %%f in ('wmic csproduct get name /value ^| find "="') do set "model=%%f"
for /f "tokens=2 delims==" %%f in ('wmic bios get smbiosbiosversion /value ^| find "="') do set "version=%%f"
IF EXIST "\\path\to\the\updater\%model%_%version%.exe" start "" /WAIT "\\path\to\the\updater\%model%_%version%.exe" /s /r
Related
Stack community good day! Thank you in advance for your time
I would like to create a bat file in order to autocreate an iso file from the DVD drive. So the logic will be:
Find which is the CD/DVD drive (from many drives)
And use that result as a variable (of the drive: for example F:) which will be executed in the following command:
cdbxpcmd.exe --burn-data -folder:F:\ -iso:C:\donalds.iso -format:iso
So in the previous command, the F:\ will be the variable, lets say %input%:\ which the program cdbxpcmd will use in order to create an iso from that drive.
I have found the following script that finds the drive letter,
from here: https://itectec.com/superuser/windows-how-to-detect-dvd-drive-letter-via-batch-file-in-ms-windows-7/
#echo off
setlocal
for /f "skip=1 tokens=1,2" %%i in ('wmic logicaldisk get caption^, drivetype') do (
if [%%j]==[5] echo %%i
)
endlocal
Do you believe that we could combine them? And how? Any suggestions?
You could use cdbxpcmd.exe itself to locate your drive:
Two line batch-file example:
#Set "CDBXP=C:\Program Files\CDBurnerXP\cdbxpcmd.exe"
#For /F "Tokens=2 Delims=()" %%G In ('^""%CDBXP%" --list-drives^"') Do #"%CDBXP%" --burn-data -folder:%%G -iso:"C:\donalds.iso" -format:iso
Just change the location where you have your cdbxpcmd.exe command line utility between the = and the closing " on line 1.
Alternatively, you could still use WMI, but personally, I would not use Win32_LogicalDisk, I would instead use Win32_CDROMDrive, which could verify both that a CDROM disk is loaded, and that it contains readable data.
Single line batch-file example:
#For /F Tokens^=6^ Delims^=^" %%G In ('%SystemRoot%\System32\wbem\WMIC.exe Path Win32_CDROMDrive Where "MediaLoaded='True' And DriveIntegrity='True'" Get Drive /Format:MOF 2^>NUL') Do #"C:\Program Files\CDBurnerXP\cdbxpcmd.exe" --burn-data -folder:%%G\ -iso:"C:\donalds.iso" -format:iso
Just change the location where you have your cdbxpcmd.exe command line utility, remembering to leave the doublequotes in place for best practice.
This question already has answers here:
Batch WMIC redirecting output and wrapping into variable
(5 answers)
Closed 2 years ago.
Thank you for checking out my question.
I am trying to:
get the output of a wmic query into a variable
Here is some background information for why I need to get this accomplished.
The policy at my job requires that laptops and tablets equipped with webcams have them disabled in the BIOS.
Now that we are teleworking we have a need to enable the webcams in the BIOS.
We have tools that can be used to enable BIOS features while the system is running.
I want to write a script that will psexec into a machine, fetch the vendor information and store it in a variable that can be accessed later in the script once psexec exits.
I can write the rest of my script without issue I think, however I'm having trouble figuring out how to store the results of the following command in a variable:
wmic csproduct get vendor /format:list | findstr/c=
For example, the output of that command on my machine is:
Vendor=Dell Inc.
I want to capture the output and store it in a variable for later use in the script I'll be writing so that I can process vendor specific BIOS manipulation.
I have tried
set sysvend=wmic csproduct get vendor /format:list | findstr/c=
But when I echo %sysvend% to see if it worked I get the following instead of what I wanted:
wmic csproduct get vendor /format:list | findstr/c=
If anyone knows how to do this I would greatly appreciate the help. I am open to other alternatives for determining the vendor.
Even easier than using find or findstr and without the problematic 0x0D0D0A line endings:
#Echo Off & SetLocal EnableExtensions
For /F Tokens^=6Delims^=^" %%G In (
'%__APPDIR__%wbem\WMIC.exe CSProduct Get Vendor /Format:MOF 2^>NUL'
) Do Set "vendor=%%G"
This solution also prevents unwanted trailing characters with the vendor name string, which can be a common occurrence.
There is a known wmic bug, so you need to parse wmic output using two nested loops, e.g. as follows:
FOR /F "tokens=1* delims==" %%s IN ('
wmic csproduct get vendor /value ^| find "="
') DO for /F "tokens=*" %%i in ("%%t") do SET "vendor=%%i"
Here the for loops are
%%s to retrieve the vendor value;
%%i to remove the ending carriage return in the value returned (wmic behaviour): each output line ends with 0x0D0D0A (CR+CR+LF) instead of common 0x0D0A (CR+LF).
See Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem
Answer posted to demonstrate the command can be assigned and executed as a variable, Contrary to Neko's answer, as per the OP's question.
#Echo Off
Set Get.Vendor=^>"%TEMP%\Vendor.log" (wmic csproduct get vendor /value ^|
findstr /c:=) ^&^& (For /F "UsebackQ Tokens=2* Delims==^EOL" %%A In ("%TEMP%\Vendor.log") Do For /F "Delims=" %%T In ("%%A") Do Set "Vendor=%%~T") ^&^& Echo.!Vendor!
Setlocal EnableDelayedExpansion
%Get.Vendor%
pause
Use for %%i in (wmic csproduct get vendor /format:list ^| findstr/c=) do (set var=%%~I)
What this does is that the for loop variable %%i becomes the output of the command in the for loop which allows you to set another variable the for loop variable. You need the caret (^) before the | in the for loop since if you didn't, the command would pipe out of the for loop and not execute in the for loop. You could also just surround the command with double quotes (") and you wouldn't need to escape the pipe. As a result of the command, %var% would become equal to the output of your wmic command.
The final command will be:
#echo off
for /f "tokens=* delims==" %%i in (' wmic csproduct get vendor /format:list ^| findstr /c:"=" ') do (set var=%%~i)
echo %var%
rem echoing var to make sure the variable is what you wanted
Output for me:
Vendor=Microsoft Corporation
If you want the output to be Microsoft Corporation specifically, you can add:
set var=%var:~7%
to remove the first 7 characters. You can also change tokens to 2* instead of *. :
for /f "tokens=2* delims==" %%j in (' wmic csproduct get vendor /format:list ^| findstr /c:"=" ') do (set var=%%~j)
Outputs:
Microsoft Corporation
Notes:
In batch-files, unlike powershell, you cannot set a variable as a command and have it become the output which is why the conventional way to set output of a command to a variable is using the for loop. Also, just preference, I would suggest using the /value switch rather than /format:list.
Tested and works for me
I have been fighting with this for 2 hours now. I need to set a variable from a second line output of a command. I found this code here at stackoverfglow:
for /f "skip=1delims=" %%a in (
'%SystemRoot%\System32\wbem\wmic.exe CSPRODUCT GET NAME'
) do set sid=%%a&goto next
The output for wmic.exe CSPRODUCT GET NAME is:
Name
PowerEdge T610
but when I run the batch file I get:
>set sid=PowerEdge T610
T610 was unexpected at this time.
I tried putting quotes everywhere.
I'm doing this script to check if the computer is a VirtualBox o VMware machine, the idea is to set a variable with the output of that command then compare it to "VirtualBox". But physical computers have product name with spaces.
THANKS!
I would offer the following method, as it will capture the full string without any potentially unwanted trailing space characters:
#For /F Tokens^=6Delims^=^" %%G In ('""%__AppDir__%wbem\WMIC.exe" CSProduct Get Name /Format:"MOF" 2>Nul"')Do #Set "SID=%%G"
Note: If you are using Windows 7, the use of some output formats may be broken, as the relevant .xsl stylesheets are located inside a language specific subdirectory which is not read by default. This issue can be worked around, by copying/moving or creating links to, all of the .xsl files one level higher, i.e. inside the wbem directory. (see potential alternative fix at the foot of this answer)
Alternatively, you could omit the for-loop completely, and instead of defining a variable, just use conditional statements:
#("%__AppDir__%wbem\WMIC.exe" CSProduct Where "Name Like '%%VirtualBox%%' Or Name Like '%%VMWare%%'" List Instance /Format:"List" 2>NUL|"%__AppDir__%find.exe" "__">NUL&&(Echo Virtual)||Echo Physical)&Pause
Note: In this example please ensure that you replace VirtualBox and/or VMWare as/if necessary. You can obviously replace the respective Echo commands with your chosen commands after testing.
Alternatively, for the actual process you need it for, based upon your comments, the following should also suffice:
#("%__AppDir__%wbem\WMIC.exe" ComputerSystem Where "Model Like '%%Virtual%%'" Get /Value 2>NUL|"%__AppDir__%find.exe" "=">NUL&&(Echo Virtual)||Echo Physical)&Pause
This should pick up a Hyper-V machine, (Model:Virtual Machine), a VMware machine, (Model:VMware Virtual Platform), and an Oracle VM, (Model:VirtualBox).
Here is a modified batch-file, which is intended to fix the potential Format issue in windows-7, as mentioned in my first example above:
#Echo Off
Set "XSL=MOF"
For /F "Delims==" %%G In ('"Set SID 2>NUL"')Do Set "%%G="
For /F "EOL=MDelims=" %%G In (
'""%__AppDir__%wbem\WMIC.exe" OS Get MUILanguages,Version 2>NUL"'
)Do For /F Tokens^=2^,4-5Delims^=.^"^ %%H In ("%%G"
)Do If %%I Equ 6 If %%J Equ 1 (Call :Target "%__APPDIR__%wbem\%%H\%XSL%"
)Else Call :Target "%XSL%"
Set SID 2>NUL&&Pause
GoTo :EOF
:Target
For /F Tokens^=6Delims^=^" %%G In (
'""%__AppDir__%wbem\WMIC.exe" CSProduct Get Name /Format:"%~1" 2>Nul"'
)Do Set "SID=%%G"
Line 9 is where you'd place your code, replacing mine which was added just for demonstration purposes.
I have been banging my head against the wall trying to figure this out. First, to answer what I'm sure will be asked, yes, I need to use a batch script. I'm sure that this is much easier in PowerShell or another language, but it needs to be a Windows Batch Script (CMD).
I am trying to re-design this script to be used on new systems and older systems within our company. The newer systems use Windows Server 2012, while the older systems use Windows Server 2008. Both systems will have 2 hard drives, but the difference between the 2 is the use of the second hard drive. On the older systems, the 2nd drive is used as a backup drive. On the newer system it is not.
In layman's terms, here is what I am looking to do:
IF ANY DISK VOLUME includes "Backup" in it's name (Caption)
SET %buletter% to the Drive Letter
SET other variables
ELSE
SET the backup location to something else
SET other variables
I've been able to pretty easily able to find how to find the name of the disk volume with the following:
FOR /f %%b IN ('wmic volume get DriveLetter^, Label ^| find "%lookfor%"') DO Stuff
But I haven't figured out how to wrap the FOR statement in an IF statement.
Any help is appreciated.
Thanks
Try this:
for /f "usebackq skip=1" %%p in (`wmic volume where "label like '%%Backup%%'" get Driveletter`) do echo Backup Drive is %%p
The only issue - it will give an empty string on a last iteration.
You don't have to use an IF initially,
you can use find and use conditional execution on success && or fail || or
initializing a var and using a for /f to eval the output - and afterwards check if the var is defined.
I'd exclude the first disk by checking for BootVolume in an extended where clause
:: Q:\Test\2019\01\25\SO_54366874.cmd
#Echo off
Set "BackUpDrive="
for /f "usebackq tokens=1,2*" %%A in (`
wmic volume where 'DriveType^="3" AND BootVolume^="FALSE" AND Label like "%%Backup%%"' get DriveLetter^,Label 2^>NUL ^| find ":"
`) Do Set "BackUpDrive=%%A"
If defined BackUpDrive (
Echo Drive with label Backup found: %BackUpDrive%
Rem other commands
) Else (
Echo no drive with label Backup found
Rem other commands
)
Sample output here:
> Q:\Test\2019\01\25\SO_54366874.cmd
Drive with label Backup found: D:
Using the idea from #mirGantrophy of checking the OS Version, this is what I came up with.
SET Version=
FOR /F "skip=1" %%v IN ('wmic os get version') DO IF NOT DEFINED Version set Version=%%v
FOR /F "delims=. tokens=1-3" %%a in ("%Version%") DO (
SET Version.Major=%%a
SET Version.Minor=%%b
SET Version.Build=%%c
)
IF %Version.Major% LSS 10 GOTO Win2008
IF %Version.Major%==10 GOTO Win2012
:Win2008
FOR /F %%p IN ('wmic logicaldisk where "VolumeName='%lookfor%'" get Caption ^| find ":"') DO (
SET buletter=%%p
SET bootdrvltr=C:
)
GOTO SetLocalDrv
:Win2012
SET buloc=C:\Archive
SET bootdrvltr=D:
GOTO SetLocalDrv
:SetLocalDrv
SET localdrv=%bootdrvltr%\Bootdrv
So I'm making an installer which installs in a specific file that would be located in one of multiple drives, and the file could be in any drive (C:\, E:\, D:\, etc.). So for example: I want to install ZK47 in E:\KNX\44C, but I want the system to automatically find the file KNX without going to E:\ and without user input.
look in all harddisks (Mediatype=12) if the folder exists:
for /f "tokens=2 delims==:" %%i in ('wmic logicaldisk where mediatype^=12 get caption /value') do if exist %%i:\KNX\44C echo found on drive: %%i:
for /f %%i in ('command') do ... is a common way to process the output of a command.
wmic logicaldisk get caption lists all existing drive letters.
where mediatype=12 tells it to list only harddisks (inside the for construct you have to escape the = with a caret ^).
/value defines the output format.
"normally" you would use "tokens=2 delims==" to get the string after = (C:). By using : as additional delimiter I avoid dealing with the ugly line endings of wmic.