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.
April 18, 2010
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.
About the Author
You May Also Like