powershellpowershell-2.0powershell-3.0powershell-4.0

Converting to a ValueFromPipeline function powershell


So I have a function called 'Get-SomeValueFromSomewhere'. I'd like to be able to pipe values into it as follows:

  1. 'entry1','entry2' | Get-SomeValueFromSomewhere
    
  2. Get-SomeValueFromSomewhere -parameter1 'entry1','entry2'
    

The function is below, but I'm not sure how to make it support piping. At the moment I'm getting an error 'Cannot process argument transformation on parameter parameter1. Cannot convert value to type System.string.'

function Get-SomeValueFromSomewhere {
    [OutputType([string])]
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string[]]$parameter1,

        [Parameter(Mandatory = $true, ValueFromPipeline = $false)]
        [string]$parameter2
    )

    Process {
        # do all of the processing here   
    }
}

Any and all help is much appreciated, thanks!


Solution

  • Assuming that you want to use a function by either providing the values by parameter or by the pipeline like so:

    "a", "b", "c" | Get-Something  -Param2 "d" -Verbose
    Get-Something -Param1 "a", "b", "c" -Param2 "d" -Verbose
    

    You could define a function which invokes itself again if the values are provided by parameter. But on the next invocation the parameter Param1 is piped to the function instead.

    function Get-Something {
        [CmdletBinding(SupportsShouldProcess)]
        param (
            [Parameter(Mandatory,ValueFromPipeline)]
            [string[]]$Param1,
            [Parameter(Mandatory)]
            [string]$Param2
        )
        
        begin {
            if (-Not $PSCmdlet.MyInvocation.ExpectingInput) {
                Write-Verbose "`$Param1 received by parameter, using it as pipeline input instead."
                $PSBoundParameters.Remove('Param1') | Out-Null
                $Param1 | & $MyInvocation.MyCommand @PSBoundParameters
                break
            }
            Write-Verbose "begin"
        }
        
        process {
            Write-Host "$_"
        }
        
        end {
            Write-Verbose "end"
        }
    }