PowerShell Tip: Querying Multiple Computers with WMI

I found myself having to grab a bunch of information from several servers today. They're all domain controllers, and I actually have several text files that list all of my servers holding various roles. There's a DomainControllers.txt file, a DNSServers.txt file, and so on. Each file includes one computer name per line, and it's just the computer names in there - nothing else.

Don Jones

April 18, 2010

2 Min Read
ITPro Today logo in a gray background | ITPro Today

I found myself having to grab a bunch of information from several servers today. They're all domain controllers, and I actually have several text files that list all of my servers holding various roles. There's a DomainControllers.txt file, a DNSServers.txt file, and so on. Each file includes one computer name per line, and it's just the computer names in there - nothing else.
I used to run a command like this in PowerShell:
Get-Content DomainControllers.txt | ForEach-Object { Get-WmiObject Win32_BIOS -computerName $_ }
That worked... but yuck. Anytime you see "ForEach-Object," you have to wonder if you're working too hard - because about 90% of the time, there's an easier, more understandable way. Throwing that $_ in there is especially confusing. What I REALLY wanted to do was this:
GC DomainControllers.txt | Gwmi -class Win32_BIOS
GC is an alias for Get-Content, and Gwmi is an alias for Get-WmiObject, but this command won't work. I initially hoped that it would take the computer names I was piping in and "attach" them to the -computerName parameter - something called parameter binding - but Get-WmiObject wasn't written that way for some reason. Oversight, perhaps. 
But you CAN do this:
Gwmi Win32_BIOS -comp (gc domaincontrollers.txt)
"-comp" is just shorthand for -computerName; you only have to type enough of a parameter name to distinguish it from others. See those parentheses? They're forcing PowerShell to execute Get-Content first, and the parenthetical expression is then replaced by its results - in other words, it's feeding the computer names from the file into the -comp parameter. 
The downside of this technique is that Get-WmiObject contacts computers sequentially, so it can take a while to run. Add the -AsJob parameter, though, and it'll run in the background. Use Get-Job to watch the job status, and Receive-Job to get the results - which will include a __SERVER property so that you can tell which results came from which computer. 

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like