hjorslev
hjorslev

Reputation: 33

Get value from pipeline with ValueFromPipelineByPropertyName

I have some issues getting a value from the pipeline using ValueFromPipelineByPropertyName.

When I run Get-Input -ComputerName 'PC-01' | Get-Data the cmdlet Get-Input should simply return the computer name "PC-01", whereas the Get-Data function should return "Value passed from Get-Input: PC-01". Instead, I get this error:

Get-Data : 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.
At line:1 char:33
+ Get-Input -ComputerName PC-01 | Get-Data
+                                 ~~~~~~~~
    + CategoryInfo          : InvalidArgument: (PC-01:PSObject) [Get-Data], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Get-Data

I have build these two small sample cmdlets just to get the hang of working with the pipeline.

function Get-Input {
    [CmdletBinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$ComputerName
    )

    Process {
        Write-Output -InputObject $ComputerName
    }
}

function Get-Data {
    [CmdletBinding()]
    Param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$ComputerName
    )

    Process {
        Write-Output -InputObject "Value passed from Get-Input: $($ComputerName)."
    }
}

If I change $ComputerName to $Name and run the following, it works:

PS C:\Users\frede> Get-Service -Name AdobeARMservice | Get-Data
Value passed from Get-Input: AdobeARMservice.

If I have grasped the concept of the pipeline in PowerShell, I should be able to run the following command Get-Input -ComputerName 'PC-01' | Get-Data and have the ComputerName passed to Get-Data.

Is there something I need to declare somewhere?

Upvotes: 3

Views: 6776

Answers (3)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174515

As the name (ValueFromPipelineByPropertyName) indicates, you're telling the parser to bind a value based on a property name.

The Get-Input function will need to output an object that has a property named ComputerName for this to work:

function Get-Input
{
    [CmdletBinding()]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [string]$ComputerName
    )

    process
    {
        Write-Output $(New-Object psobject -Propert @{ComputerName = $ComputerName})
    }
}

Now you can do:

Get-Input -ComputerName 'PC-01' |Get-Data

If you want Get-Data to support computer name input from Get-Service, you'll have to add an alias that matches the appropriate property name on the object types output by Get-Service, ie. MachineName:

function Get-Data
{
    [CmdletBinding()]
    param
    (
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [Alias('MachineName')]
        [string]$ComputerName
    )

    process
    {
        Write-Output -InputObject "Value passed from Get-Input: $($ComputerName)."
    }
}

And now both of these will work:

Get-Service -Name AdobeARMService |Get-Data
Get-Input -ComputerName PC-01 |Get-Data

Upvotes: 9

Drew
Drew

Reputation: 4020

You will need this bud.

ValueFromPipelineByPropertyName is for boolean ($True / $False) and isn't looking for your string.

[CmdletBinding()]
param
(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [string]$ComputerName
)

Upvotes: -2

Jannik.M
Jannik.M

Reputation: 1

you have to write also ValueFromPipeline=$true:

 Mandatory = $true,
 ValueFromPipeline=$true,
 ValueFromPipelineByPropertyName = $true

Greetings Jannik

Upvotes: -2

Related Questions