Vaccano
Vaccano

Reputation: 82291

Make a Powershell function work correctly as both Pipeline and normal invocation

Say I have the following Powershell function:

function AddGos
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline=$True)]
        [string[]] $dbScript
    )
    process
    {
        $dbScript + "GO"
    }
}

If I call this like this:

("one", "two", "three") | AddGos 

I get:

one
GO
two
GO
three
GO

But if I call it like this:

AddGos("one", "two", "three")   

Then I get this:

one
two
three
GO

This is because when you run as a pipeline it breaks up my array and calls the process section for each entry in the array. But when you call it normally it just passes in the array as a single object.

I can see a way to make this simple scenario support both, but when you start getting complex functions it could quickly get too complex to manage working for both scenarios.

How this is normally dealt with in the Powershell world?

Meaning to functions only support one way or the other? Or is there some easy way to work around this that I am missing? Or do function authors just work really hard to make it work either way?

Upvotes: 0

Views: 62

Answers (1)

Theo
Theo

Reputation: 61028

Add a foreach loop in the process block to handle both situations:

function AddGos {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline=$True)]
        [string[]] $dbScript
    )
    process {
        foreach ($item in $dbScript) {
            $item + "`r`nGO"
        }
    }
}

"one", "two", "three" | AddGos

AddGos "one", "two", "three"

Both calls will now give you the same result:

one
GO
two
GO
three
GO

P.S. you don't need the brackets around the array elements

Upvotes: 2

Related Questions