StackExchangeGuy
StackExchangeGuy

Reputation: 789

Function with two "accept from pipeline" parameters

I want a function to allow me to pass in either a device ID or a display name, and to do stuff with it.

In the following example, I pass in a customer PowerShell object that only contains a device ID ($obj.ID | Test-Function), but both $DisplayName and $Id end up with that value.

How do I force the value into the correct parameter?

function Test-Function {
[CmdletBinding()]
    Param (
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true
        )]
        [string]$DisplayName

        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true
        )]
        [string]$Id
    )
    Begin {
        #Code goes here
    }
    Process {
        Write-Host "displayname is: $DisplayName" -ForegroundColor Green
        Write-Host "displayname is: $Id" -ForegroundColor Green        
    }
}

Upvotes: 3

Views: 423

Answers (2)

TWEESTY
TWEESTY

Reputation: 57

Just remove ValueFromPipeline and set $false for Mandatory attributes , so the correct solution is:

function Test-Function {
[CmdletBinding()]
    Param (
        [Parameter(
            Mandatory=$false,
            ValueFromPipelineByPropertyName=$true
        )]
        [string]$DisplayName,

        [Parameter(
            Mandatory=$false,
            ValueFromPipelineByPropertyName=$true
        )]
        [string]$Id
    )
    Begin {
        #Code goes here
    }
    Process {
        Write-Host "displayname is: $DisplayName" -ForegroundColor Green
        Write-Host "displayname is: $Id" -ForegroundColor Green        
    }
}

Upvotes: 3

Martin Brandl
Martin Brandl

Reputation: 58931

You can solve this with ParameterSets. Notice I also fixed a comma in your code and the Write-Host output:

function Test-Function 
{
[CmdletBinding()]
    Param (
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='DisplayName'
        )]
        [string]$DisplayName,


        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            ParameterSetName='Id'
        )]
        [string]$Id
    )
    Begin {
        #Code goes here
    }
    Process {
        Write-Host "displayname is: $DisplayName" -ForegroundColor Green
        Write-Host "Id is: $Id" -ForegroundColor Green        
    }
}

Lets give it a try:

[PsCustomObject]@{Id = "hello"} | Test-Function

Outputs:

displayname is: 
Id is: hello

and

[PsCustomObject]@{DisplayName = "hello"} | Test-Function

outputs

displayname is: hello
Id is: 

Upvotes: 3

Related Questions