Function Help: Default param value with pipelining

Welcome Forums General PowerShell Q&A Function Help: Default param value with pipelining

This topic contains 3 replies, has 2 voices, and was last updated by

 
Member
4 years, 7 months ago.

  • Author
    Posts
  • #14483

    Participant
    Points: 158
    Helping Hand
    Rank: Participant

    Basically, the scenario is user is providing a CSV. We'll say there are two params First and Second. If the user does not provide a Second param in the CSV, the goal is to use the default function param. So, the function:

    Function Test-It{
    Param(
    [Parameter(Mandatory=$false,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
    HelpMessage='The first parameter')]
    [AllowNull()]
    [AllowEmptyString()]
    [string]$First ="FirstDefault",
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
    HelpMessage='The second parameter')]
    [AllowNull()]
    [AllowEmptyString()]
    [string]$Second ="SecondDefault" )

    begin{}
    process{
    Write-Host ("First: {0}" -f $First)
    Write-Host ("Second: {0}" -f $Second)
    }
    end{}
    }

    If I do Test-It -First "Whatever", the default works correctly. If I pass both params over the pipeline:

    $parameters = New-Object -TypeName PSObject -Property @{
    First = "Hello"
    Second = "Rob"
    }

    Clear-Host
    $parameters | Test-It

    Returns:
    First: Hello
    Second: Rob

    But if I only pass one parameter over the pipeline:

    $parameters = New-Object -TypeName PSObject -Property @{
    First = "Hello"
    }

    Clear-Host
    $parameters | Test-It

    Then it returns like this when I expect Second: SecondDefault:

    First: Hello
    Second: @{First=Hello}

    How do input default params are utilizing when using the pipeline?

  • #14484

    Member
    Points: 0
    Rank: Member

    Try getting rid of the "ValueFromPipeline" attributes, and just stick with ValueFromPipelineByPropertyName.

  • #14485

    Participant
    Points: 158
    Helping Hand
    Rank: Participant

    Ok, that did work. When you use the ValueFromPipeLine, is that insinuating that everything the function will need is coming from the pipleline. I'm trying to understand this behavior so I know when and when not to use that parameter option. Can you elaborate? Thank you for the quick response.

  • #14486

    Member
    Points: 0
    Rank: Member

    Pipeline input works in one of 4 ways (attempted in this order, if I remember correctly): By Value (no coercion), By Property Name (no coercion), By Value (with coercion), By Property Name (with coercion). You've defined your two input parameters to be of type [String], but piped in a PSObject. By Value (no coercion) doesn't work, because the type of the input object doesn't match either parameter. By Propety Name (no coercion) works, for whichever properties exist as Strings on your input object. By Value (with coercion) will ALWAYS succeed for any remaining unbound String parameters, because every object can be represented as a string via the Object.ToString() method. That's where your function was running into a problem.

    Having ValueFromPipeline applied to multiple parameters in the same parameter set is usually pointless. Typically, you'll see one parameter with ValueFromPipeline (and possibly ValueFromPipelineByPropertyName as well), and any number of other parameters with ValueFromPipelineByPropertyNaem only.

The topic ‘Function Help: Default param value with pipelining’ is closed to new replies.