Here we passed three valid, online computer names to
Get-Service via the PowerShell pipeline.
The problem is that we want these services to bind to the –ComputerName parameter, which we
already know they will not. Read one of
the three error messages. Get-Service is actually looking for
services named DC1, SVR1 and SVR2.
What? Remember, the –Name parameter accepts strings and that
is what we sent it. OK, let’s create an
object that has a ComputerName
property and pipe it to Get-Service
and attempt to use the ByPropertyName passing that the –ComputerName parameter is advertising.

First, we are going to grab the ActiveDirectory computer
object from the database. We are going
to specify only the computer name DC1 to keep this simple.

Get-ADComputer–Filter
{name-eq"DC1"}

DistinguishedName : CN=DC1,OU=Domain
Controllers,DC=PowerIT,DC=com

DNSHostName :
DC1.PowerIT.com

Enabled :
True

Name : DC1

ObjectClass :
computer

ObjectGUID :
14313c03-ecb8-4126-b180-89619742922a

SamAccountName :
DC1$

SID :
S-1-5-21-31908143-1805627216-1122469826-1000

UserPrincipalName :

As you can see, this object does not have property call ComputerName so we cannot pass it to Get-Service. We can send it to SelectObject and rename the Name property to ComputerName.

You can see from the output that we have a new property call
ComputerName and its value came from
the objects Name property. Now we have met the criteria for passing the
computer name DC1 to the –ComputerName
parameter of Get-Service, let’s give it a try.

Um… What? The Get-Service cmdlet is once again
looking for a service called DC1
instead of binding DC1 as the argument for –ComputerName. This is the tricky part about ByValue. It can
cause some odd behaviors.

I have looked at a lot of discussions on why this is
happening. So far, there are a lot of
theories. One work around is to explicitly ask for all services by adding –Name *. Take a look.

There is a rule in PowerShell piping that you cannot pass
input to a parameter and call it at the same time. In the example below, we are piping the
string“Bits”to Get-Service. This
normally works, but we are also explicitly using the –Name parameter of Get-Service
at the same time.

PS C:\> "Bits" | Get-Service -Name
"Bits"

Get-Service : The input object cannot be bound to any parameters for
the command either because the command does not take

pipeline input or the input and its properties do not match any of
the parameters that take pipeline input.

This is a no go. In
the above example that worked, my best guess is that since ByValue is tried
first and we are not explicitly using the –Name
parameter, the ByPropertyName parameter of –ComputerName
now has a chance to accept the pipeline input.

To put this theory to the test, I utilized Trace-Command. Get ready, there is a lot of information
coming. I added my notes to the output with a dark green background that looks
like this:

Again, a lot of information. In short I can only assume that
there is a coding error in either how PowerShell handles ByValue passing or the
programmer of the cmdlet did not do a thorough debugging. This is an example as
to why you should always test your code thoroughly before making a public
release.