Batch WMIC redirecting output and wrapping into variable

大憨熊 提交于 2019-11-28 11:45:25

WMIC is returning two lines, one with the printername, and one empty.
The solution to this is to test for empty lines.

ECHO Gathering Installed Printer Information...
FOR /F "tokens=1 skip=1" %%A IN ('WMIC PRINTER WHERE "Servername like "%%printaz1%%"" get sharename') DO if not "%%A"=="" SET PRINTERNAME=%%A
ECHO %PRINTERNAME%
Nico

what you are looking for is this:

for /f "skip=2 tokens=2 delims=," %%A in ('WMIC PRINTER WHERE "Servername like "%%printaz1%%"" get sharename /format:csv') DO SET PRINTERNAME=%%A
ECHO %PRINTERNAME%

Explanation:

The unicode output of wmic includes a carriage return which is captured by the FOR /F which is what you do not want, as it means the 'enter' becomes part of your variable (%%A) and it also contains an empty line, which again will be outputted to %%A.

My example does the following: /format:cvs -- will output a comma seperated output so we can capture using the delimiter , skip=2 -- will skip the empty line at the beginning and skip the header row of the csv. tokens=2 -- the csv output contains the name,value as output, but you only want value, which is the second token.

by the way, because we no longer include space as a seperate it should even work with spaces in the value. give it a try.

I got around the UNICODE carriage return (which is really the problem here) like this:

@echo off
FOR /F "usebackq tokens=1,2 delims==" %%A IN (`wmic %* /VALUE ^| findstr "="`) DO (call :OUTPUT %%A "%%B")
exit /b

:OUTPUT
echo %1=%2

Save that as "wmi.bat" and execute your query like this:

wmi.bat printer where 'name like "HP%"' get name

My output looks like this:

Name="HP1C0BCA (HP Officejet Pro 276dw MFP)"
Name="HP Officejet Pro L7500 Series"
Name="HP Officejet Pro 276dw MFP PCL 6"

You can imagine how you can play with this. the "%%B" portion puts all of the output of /VALUE (including spaces) into the %2 %%A captures the object id, which becomes %1 which is handy if you use this to log all sorts of information from WMI. You don't have to worry about the Unicode carriage return anymore.

The big advantage of this approach is that you have a clever batch file which overcomes the limitations that wmic gives you when using it inside a script, and you can use it for anything. you can use the STDOUT of the batch file as the parameter for anything else, even as input to wmic!

js2010
@ECHO

ECHO Gathering Installed Printer Information...

FOR /F "tokens=1 skip=1" %%A IN ('WMIC PRINTER WHERE "Servername like "%%printaz1%%"" get sharename') DO (
  SET PRINTERNAME=%%A
  goto end
) 
:end
ECHO %PRINTERNAME%

The most secure and general variant is to nest another for /F loop, like this:

for /F "skip=1 usebackq delims=" %%A in (`
    wmic Printer where 'Servername like "%%printaz1%%"' get ShareName
`) do for /F "delims=" %%B in ("%%A") do set "PRINTERNAME=%%A"

The problem is the Unicode output of the wmic command and the poor conversion to ANSI text by for /F, which leaves some orphaned carriage-return characters, which in turn lets appear some additional lines as non-empty. The second for /F loop gets rid of these conversion artefacts.

I also replaced the tokens=1 option by delims= in order not to truncate the returned item at the first white-space.

Take also a look at the following related answers by user dbenham:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!