I have been naïvely assuming that an object passed to a commandlet using PowerShell's pipeline parameter binding is treated the same as passing it using named parameters. However, the following script seems to demonstrate there is a difference:
Function Process-xMsmqQueue{
[CmdletBinding()]
Param(
[Parameter()]$obj,
[Parameter(
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True)]
[System.Messaging.MessageQueue]$queue
)
Write-Host $obj
}
New-MsmqQueue 'xTest1' -ErrorAction Ignore
[System.Reflection.Assembly]::LoadWithPartialName('System.Messaging') | Out-Null
New-Object System.Messaging.MessageQueue('.\private$\xTest1') -OutVariable q
$first = 'first'
$second = 'second'
$q | Process-xMsmqQueue -obj $first
Process-xMsmqQueue -queue $q -obj $second
I expected this script to print first
and second
. Instead, it throws ParameterArgumentTransformationError
on the last line:
The difference in treatment of the $queue
parameter only seems to manifest for some object types. For example, replacing [System.Messaging.MessageQueue]
with [System.String]
and passing a string to $queue
yields no errors.
My Questions:
- Why is the
System.Messaging.MessageQueue
object treated differently when passed using the pipeline versus named parameters? - Why isn't
System.String
affected by the difference? - How can I change this script to make passing by named parameter work for
-queue
?