Solved Bat Script - Parsing a variable with a For command

February 15, 2013 at 16:43:10
Specs: Windows 7
I am trying to write a script to install the correct display driver. Long story short on newer systems when you add a dedicated card the onboard is no longer disabled so when I run this command

FOR /F "tokens=2 delims==" %%i IN ('wmic path win32_videocontroller get pnpdeviceid/value 2^>NUL ^| find /i "pnpdeviceid"') DO set vdcd=%%i

my vdcd variable is now set with the pnpdeviceid of the onboard, but when I add the wmic Where verb i get no result using this command

FOR /F "tokens=2 delims==" %%i IN ('wmic path win32_videocontroller Where DeviceID="VideoController1" get pnpdeviceid /value 2^>NUL ^| find /i "pnpdeviceid"') DO set vdcd=%%i

Running just
wmic path win32_videocontroller Where DeviceID="VideoController1" get pnpdeviceid
does result with the desired primary display adapter. I can make a mess of things and "MAKE" it work but I like to keep my scripts as clean as possible.. Making it work by writing the simple command to a txt file and then running a separate for command to read the txt document.


See More: Bat Script - Parsing a variable with a For command

Report •


✔ Best Answer
February 18, 2013 at 22:25:00
i did find a working work around and my script seems to be happy but im not there should be a simple solution using the orginal method just modified in some way

wmic path win32_videocontroller get deviceid, pnpdeviceid | for /f "tokens=2" %%a in ('find /i "videocontroller1"') do @echo %%a >null
set /p x= < null

im just echoing the output to a file and then reading it right back in redundent and messy but works



#1
February 15, 2013 at 21:23:10
when i took out the 2>nul: "invalid verb" when using "where". You might need to tone up on wmic, I am not proficient in its usage. I tried many variations with no success. "Where" is not actually a verb, afaik, but "get", which is, throws no error. "Where" clause threw one every time...

Report •

#2
February 15, 2013 at 22:58:55
if you run just this
wmic path win32_videocontroller Where DeviceID="VideoController1" get pnpdeviceid

it will display the pnpdevice id of contoller 1, its once i I add the for loop and the additional terms that the Where clause breaks the command


Report •

#3
February 16, 2013 at 15:10:56
Yes, the for-loop definitely interferes with wmic's syntax evaluation. I thought I might be onto something with:
wmic path win32_videocontroller get deviceid, pnpdeviceid
but again, inside the for-loop, it threw error "invalid 'get' expression". So, although I got rid of the "where", wmic just picked another element to attack. I did this as a workaround:
wmic path win32_videocontroller get deviceid, pnpdeviceid | for /f "tokens=2" %%a in ('find /i "videocontroller1"') do set x=%%a

Report •

Related Solutions

#4
February 18, 2013 at 08:28:39
Have you considered a saner language? VBScript works well with WMI, and it has fewer compatibility issues than batch.

How To Ask Questions The Smart Way


Report •

#5
February 18, 2013 at 19:16:50
That workaround most ceretinly did work and while its basically the same the re-arrangement does the trick ;)
Thank you very muhc nbrane :)

Razor the only reason I am messing with batch at the moment is they are easier for the less trained eye to understand what is happeneing. I write scripts to help make my and my fellow techs jobs easier since the person who is supposed to be doing that .. currently doesnt.. I am needless to say inline to take over now that our department has undergone some management changes. Right now the dummy who has the title of the job I do needs to understand what each of my scripts do before he will "allow" them to be posted on our tech tools drive. I already have to baby step him through these explaning a vbscript.. yea right.. plus im a lil vb rusty though I am brushing up again


Report •

#6
February 18, 2013 at 20:39:51
I may have been incorrect about it working, running just this as a bat file

@echo off
wmic path win32_videocontroller get deviceid, pnpdeviceid | for /f "tokens=2" %%a in ('find /i "videocontroller1"') do set x=%%a
echo %x%
pause

I get an output of this

G:\Drivers\Display>set x=PCI\VEN_10DE&DEV_104A&SUBSYS_35451458&REV_A1\4&14466D94
&0&0008
ECHO is off.
Press any key to continue . . .

for some reason at the do set x=%%a it is instead echoing set x=%%a and not setting a value at all... very strange indeed.


Report •

#7
February 18, 2013 at 22:21:11
Every time I deal with win-7, I find a new reason to hate it! mebbe try quotes, add (), and kill the "eject" (goto eof) to see what's going on here (also removed the spec of videocontroller, just in case, so all controllers will be reported, maybe).

@echo off
wmic path win32_videocontroller get deviceid, pnpdeviceid | for /f "tokens=*" %%a in ('find /i "videocontroller"') do (
set x="%%a"
echo %%a
pause
)
goto :eof

I'm clueless. this cruft worked when i posted, now it doesn't. The pauses don't pause, i get () echoed, it's a crock. win-7 should be sent to hell where it belongs.


Report •

#8
February 18, 2013 at 22:25:00
✔ Best Answer
i did find a working work around and my script seems to be happy but im not there should be a simple solution using the orginal method just modified in some way

wmic path win32_videocontroller get deviceid, pnpdeviceid | for /f "tokens=2" %%a in ('find /i "videocontroller1"') do @echo %%a >null
set /p x= < null

im just echoing the output to a file and then reading it right back in redundent and messy but works


Report •

#9
February 18, 2013 at 22:30:48
Ha ha! yeh, as usual, Razor was right, about wmic and vbscript solution. I'm gonna hav to experiment with this, just to appease my curiosity... Glad it works!
ps: might be a unicode issue, since wmic output is unicode, but again, I'm clueless

Report •

#10
February 18, 2013 at 22:33:51
oh im sure it would run as expected in VB but there is no real reason it shouldnt also work in bat.. oh well i have my work around so im good.. unless someone out there has some amazing revolution lol

Report •

#11
February 19, 2013 at 07:18:35
So let's talk WMI. It's the primary way scripts get information from Windows.

For CMD, WMIC was included as part of Win2K's resource kit. It was then added to WinXP Pro, but it required administrative privileges to run. This means you could not reliably run it until Vista. Even if you could run it on WinXP, the formatting characters changed between versions, so you can't reliably use it in a batch script in a mixed WinXP - Win7 environment. Still, if you're using batch, it is your only choice. Getting the command to work in a FOR loop requires you to know too much about CMD's tokenization, or use temporary files. Neither are ideal.

for /f "usebackq" %a in (`wmic path win32_videocontroller where deviceid^='VideoController1' get pnpdeviceid ^| findstr "."`) do set vid=%a
@echo %vid%

Now we get in the languages that were actually designed. VBScript/JScript could be found on Win98 machines, meaning it's more compatible than modern Batch, which is restricted to the WinNT line. Currently being phased out for the hot new thing, PowerShell. VBScript was originally going to compete with JavaScript, and be used to push Netscape out of the market. Netscape died, but so did VBScript as an Internet script language. A fair trade.
Set vid = GetObject("winmgmts:Win32_VideoController.DeviceID=""VideoController1""")
WScript.Echo vid.PNPDeviceID

Finally, we end up with PowerShell. Included with Vista / Win2K3 SP2(?), it was going to replace CMD and include 100% batch compatibility. This idea was quickly dropped once the PowerShell team actually looked at CMD. Being new, it already has its fair number of version differences, but backward compatibility was a design concern so a script that works in v1.0 (Vista) should run fine on v2.0 (Win7), and presumably v3.0 (Win8) as well. Also, don't be fooled! PowerShell claims it's a shell; it's not. It's a scripting environment that defaults to not running scripts. A committee design if I ever saw one. Finally its script editor, PowerShell ISE, is not 100% compatible with the actual intended execution environment, so watch out for that. I'm told Version 3 fixes at least a few of these compatibility problems, so that's good. Nice language, though. The documentation is built into it, so you don't need to dig around the TechNet/MSDN site.
$vid = Get-WmiObject win32_videocontroller -Filter "deviceid='VideoController1'" 
$vid.PNPDeviceID

How To Ask Questions The Smart Way


Report •

#12
February 19, 2013 at 10:38:37
@Razor: thanks for the background on wmic and scripts, I got a lot out of it. I thought of going using vbscript, but i don't know the (complicated, imo) syntax for getting around in wmic. I guess there's documentation to be googled, but maybe you know a good site off-hand?
Also, i tried the "usebackq", but i didn't know to escape the = and I kept the dbl-quotes around "videocontroller1", so i guess that's what failed me.
I sure hope "they" don't phase out vbscript, but i guess I could learn javascript if they do. I sound like a stuck record, but it seems like whenever i get comfortable with one thing, they take it away and give me something I don't like. (but then again, i hated xp when it first came out, like I hate seven now. Now xp is my vastly-preferred platform.)

Report •

#13
February 19, 2013 at 12:35:52
Wmic mostly just gives you access the the various WMI objects. It has a lot of shortcuts to the common WMI objects. For example, wmic volume is equivalent to wmic path win32_volume. The 'get' clause are the properties you want, and the 'where' clause is the object filter. WMI tries to come off as a relational DB, so it's okay to think of it as one (except those times when it's not).

The real question is where can you find documentation on the WMI classes, and well, that's what MSDN is for.

By JavaScript, do you mean JScript? That's in the same boat as VBScript. Its successor is PowerShell for Windows manipulation, and JavaScript for web pages. If you're trying to stay at least with the curve, start poking around the PowerShell ISE.

How To Ask Questions The Smart Way


Report •

Ask Question