2

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.

Compo
  • 36,585
  • 5
  • 27
  • 39
Proximus
  • 21
  • 2

4 Answers4

4

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.

Compo
  • 36,585
  • 5
  • 27
  • 39
3

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

Nico Nekoru
  • 2,840
  • 2
  • 17
  • 38
JosefZ
  • 28,460
  • 5
  • 44
  • 83
  • 1
    Well, I wouldn't call it a `wmic` bug, because it actually happens when using `for /F` to convert the Unicode output to ASCII/ANSI. Anyway, you don't need the `find "="` when you've got two `for /F` loops. The most general method is to use `"delims="` for the outer loop and `"tokens=1* delims=="` for the inner one, so you avoid trouble in case there are leading spaces in the value (although quite unlikely); but this would still lose leading `=`-signs (although even more unlikely)... – aschipfl May 19 '20 at 20:20
0

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

Nico Nekoru
  • 2,840
  • 2
  • 17
  • 38
  • With regards to not being able to set a variable as a command and have it become / generate the output, you are mistaken. Batch macro's can facilitate this, however it's more complicated and takes a higher level of understanding of batch scripting to construct such macro's. Additionally, the circumstances in which it's appropriate are somewhat Niche. – T3RR0R May 19 '20 at 19:30
  • Sorry Neko, but your posted output is not possible from your posted solution. Your output would be `Vendor=Microsoft`. Your variable `%var%` will contain the following string, `Vendor=Microsoft`, and I'm sure that the OP would like it to contain, in this case `Microsoft Corporation`. – Compo May 19 '20 at 20:09
  • @Compo Why is it not possible? It worked for me, is there a certain setting on your computer that doesn't allow this to be possible? Or is it something or my computer? – Nico Nekoru May 19 '20 at 20:11
  • Nevermind, I found the error, edited and works now – Nico Nekoru May 19 '20 at 20:19
  • @NekoMusume, sorry, but that's still not correct. Your variable content will still be `Vendor=Microsoft Corporation`, you'd want to change `tokens=*` to `Tokens=1*` and then use `%%j` for your variable value instead of `%%i`. – Compo May 19 '20 at 20:25
  • Was the variable being `Vendor=Microsoft Corporation` not intended? – Nico Nekoru May 19 '20 at 20:28
  • Well @NekoMusume, only the OP can answer that, but generally especially with a variable named using a known name, there'd be no need for the string value to also carry the `Vendor=` part. – Compo May 19 '20 at 20:46
  • I see, I will add your suggestion in another section as well – Nico Nekoru May 19 '20 at 20:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/214212/discussion-between-neko-musume-and-compo). – Nico Nekoru May 19 '20 at 20:57
  • With regards your latest edit, @NekoMusume, I didn't suggest `2*`. Also using your example, if the vendor string included a `=` character, it wouldn't capture the entire string, just that up to the included `=`, everything else after the `=` would be assigned to `%%k`. – Compo May 19 '20 at 21:01
  • It worked for me and I don't think `*1` works for my for loop – Nico Nekoru May 19 '20 at 21:04
  • "vendor" is 6 characters, = is 1 – Nico Nekoru May 19 '20 at 21:04
  • I didn't type or suggest `*1`, @NekoMusume, please read [my comment](https://stackoverflow.com/questions/61898371/having-trouble-storing-output-of-wmic-csproduct-get-vendor-formatlist-finds#comment109483665_61898597) again! – Compo May 19 '20 at 21:50
  • @Compo I changed it so it doesn't say you suggested it . Try my exact code, `1*` tokens doesn't work – Nico Nekoru May 19 '20 at 22:21
  • @NekoMusume, I don't believe that `for /f "tokens=2* delims==" %%j in (' wmic csproduct get vendor /format:list ^| findstr /c:"=" ') do (set var=%%~j)` works for you, but my suggestion with your variable now changed from `%%i` to `%%j`, `for /f "tokens=1* delims==" %%j in (' wmic csproduct get vendor /format:list ^| findstr /c:"=" ') do (set var=%%~k)` doesn't initially define the variable with the same content, only without possibly removing any string value containing a `=` character and those which follow it.. – Compo May 20 '20 at 00:45
0

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
T3RR0R
  • 2,747
  • 3
  • 10
  • 25