I recently wrapped up a public class in Seattle (hey, would y'all be interested in knowing when I have a class I'm teaching? Drop a comment and let me know - I could do a monthly schedule round-up here) and one of the tricky bits we ran across involves the Get-WmiObject cmdlet.
We were on the first day of class, when you tend to use Get-Process, Get-Service, and Get-EventLog a lot - simply because they're built-in, pretty straightforward, and exhibit a lot of the special features of more complex cmdlets, without themselves being quite so complicated.
All of those three cmdlets have a -computerName parameter, which accepts pipeline input by property name (I covered this at http://www.windowsitpro.com/blogs/PowerShellwithaPurpose/tabid/2248/entryid/12801/Default.aspx if you want a quick review). In other words, you can pipe an object that has a ComputerName property to any of these cmdlets, and they'll bind that property to the -computername parameter. Well, normally; there are some tricks about pipeline parameter binding that I covered in the previous article.
It was probably pretty natural for folks to try the same trick with Get-WmiObject - and they were disappointed when it didn't work. A quick review of the help, however (Help Get-WmiObject -full), revealed that the -computerName parameter for this particular cmdlet doesn't bind pipeline input ByPropertyName, so the trick isn't supposed to work.
Why not? Well, the easy answer is because Microsoft forgot to hook it up. Hey, they're only human, after all - mistakes happen. In fact, Get-WmiObject doesn't accept ANY pipeline input, although again I can't say exactly why that was the decision.
The point, however, is that there's usually a way around it. If you're reading computer names from a text file, with one computer name per line, here's the workaround (using Win32_BIOS as an example class to query):
Get-WmiObject Win32_BIOS -computername (gc computers.txt)
The parentheses cause the Get-Content (gc) command to execute first, and send its output to -computerName. But what if you want to get computer objects from Active Directory, and select their Name property to become the input to -computername?
Get-WmiObject Win32_BIOS -comp (Get-ADComputer -filter * -searchbase 'ou=domain controllers,dc=company,dc=pri'|select –expand Name)
This time, the parentheses include a whole sub-pipeline. It's getting specified computer objects (domain controllers), and selecting just their Name property. The -expand switch tells the shell to expand that property into its values, so that the result of this parenthetical expression is a set of values - computer names - rather than objects having a Name value, which -computername wouldn't know what to do with.
This is one of the great tricks of PowerShell: Even when things don't line up exactly as you might expect, there's nearly always a way around it.
Want more PowerShell articles, along with FAQs and more? Visit http://windowsitpro.com/go/DonJonesPowerShell.