Search code examples
powershellpipelinepowershell-cmdlet

ValueFromPipelineByPropertyName can I shift function next positional parameters?


Considering to functions designed to use values by property name, the second function have his first argument passed by pipeline. Can I use positional parameter for this second function?

Example:

function Get-Customer {
    [CmdletBinding()]
    Param(
        [string]$CustomerName = "*"
    )
    Process {
        # real process iterate on fodlers.
        New-Object PSObject -Property @{
            CustomerName = $CustomerName;
        }
    }
}

function Get-Device {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipelineByPropertyName)]
        [string]$CustomerName = "*",
        [string]$DeviceName = "*"
    )

    Process {
        # real process iterate on fodlers.
        New-Object PSObject -Property @{
            CustomerName=$CustomerName;
            DeviceName=$DeviceName
        }
    }
}

You can use it like:

Get-Customer "John" | Get-Device
Get-Customer "John" | Get-Device -DeviceName "Device 1"

But can you do this (actually with provided code it doesn't work)?

Get-Customer "John" | Get-Device "Device 1"

Solution

  • You need to define $DeviceName as the first positional parameter for that to work:

    function Get-Device {
        [CmdletBinding()]
        Param(
            [Parameter(ValueFromPipelineByPropertyName)]
            [string]$CustomerName = "*",
    
            [Parameter(Position=0)]
            [string]$DeviceName = "*"
        )
    
        Process {
            # real process iterate on fodlers.
            New-Object PSObject -Property @{
                CustomerName = $CustomerName;
                DeviceName   = $DeviceName
            }
        }
    }