Deciphering my PowerShell FAIL...

So, I've been prepping some new materials for this training kit that I offer at conferences and classes I teach at, and I constructed a statement that I thought would be super-cool - and it super-failed. Here's how I went about deciphering my problem - or at least identifying what the problem is, if not the solution (yet).

Don Jones

April 20, 2010

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

So, I've been prepping some new materials for thisUSB flash drive training kit that I offer at conferences and classes I teach at, and I constructed a statement like this:
Import-Module ActiveDirectoryGet-ADComputer -filter * -searchbase 'ou=domain controllers,dc=company,dc=pri' | Select-Object @{'Label'='ComputerName';Expression={$_.Name}}
The practical upshot of this is to retrieve all the domain controllers from the domain, and then remap their "Name" property to be a "ComputerName" property. Why? Well, because cmdlets like Invoke-Command can bind pipeline input ByPropertyName, meaning that - I thought - if I piped in objects having a ComputerName property, they'd attach themselves to the cmdlet's -computerName parameter. So this:
Import-Module ActiveDirectoryGet-ADComputer -filter * -searchbase 'ou=domain controllers,dc=company,dc=pri' | Select-Object @{'Label'='ComputerName';Expression={$_.Name}} |Invoke-Command -script { Get-Service }
Would invoke the Get-Service command on every domain controller in the domain. Or at least, it would in my perfect little world. As-is, it spit out a bunch of errors.
Well, turns out there's a trick to parameter binding that you should be aware of. True, Invoke-Command does bind pipeline input to -computerName ByPropertyName - so as far as it goes, my theory was right. But it also binds the -inputObject parameter ByValue, accepting a value of Object. The -inputObject parameter accepts stuff that you want passed into whatever command/script you're executing.
In plain English? My computer objects were being piped to Invoke-Command, but because ByValue binding happens first, my objects were being snatched up by -inputObject and being sent to that Get-Service cmdlet as its pipeline input. Get-Service didn't really know what to do with them, so it all exploded on me. Rats.
So I'm still wrapping my head around these facts: 

  1. ByValue parameter binding always happens before ByPropertyName binding.

  2. -inputObject binds pipeline input ByValue, accepting anything of the Object type.

  3. All objects derive from the Object type, so -inputObject will bind anything.

So it seems as if -inputObject will always grab whatever you pipe to Invoke-Command. Now, here's the trick: Provided those objects can be safely used by whatever command you're invoking, those objects can also contain other miscellaneous properties that will bind, ByPropertyName, to Invoke-Command's parameters. For example, Get-Service will bind a Name property. So if I piped in an object having both a Name property and a ComputerName property, then something seems to work:


Import-Module ActiveDirectory

Get-ADComputer -filter * -searchbase 'ou=domain controllers,dc=company,dc=pri' |

Select-Object Name,@{'Label'='ComputerName';Expression={$_.Name}} |

Invoke-Command -script { Get-Service }


This still weirds be out a little. It seems to negate the value of having Invoke-Command's -computerName parameter bind input at all, since anything piped in will bind to -inputObject first. But surely someone thought of that, so it's obviously something I'm missing.


Needless to say, I'm tabling this particular example for right now until I can wrap my head around it. I have e-mails out to some of the other PowerShell MVPs, so we'll see what they say. I'm interested in your input, too - what am I missing? How can I successfully use pipeline binding with the -computerName parameter of Invoke-Command? Drop a comment if you know the trick - and if I discover it, I'll be sure to follow-up.

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