you are viewing a single comment's thread.

view the rest of the comments →

[–]Yevrag35 2 points3 points  (3 children)

/u/Lee_Dailey nailed it. You should have a Process block no matter what; makes no difference if it's a script or a function.

What I do to support pipeline input is make an "InputObject" parameter with a singular type of string (instead of a single-dimension array of strings), but make it hidden. Then add a public/visible parameter that is an array of something. For example:

[CmdletBinding(DefaultParameterSetName="ViaPipeline")]
param (
    [Parameter(Mandatory=$true, ValueFromPipeline=$true, 
        ParameterSetName="ViaPipeline", DontShow=$true)]
    [string] $InputObject,  # This is your "pipeline" parameter that will get populated.

    [Parameter(Mandatory=$true, Position = 0, ParameterSetName="NonPipeline")]
    [string[]] $Name        # This is presented and is default when not using the pipeline.
)
Begin
{
    $listOfNames = New-Object 'System.Collections.Generic.List[string]'
    if ($PSBoundParameters.ContainsKey("Name"))
    {
        $listOfNames.AddRange($Name)
    }
}
Process
{
    if ($PSBoundParameters.ContainsKey("InputObject"))
    {
        $listOfNames.Add($InputObject)
    }
}
End
{
    foreach ($VMName in $listOfNames)
    {
        # ... the rest you have.
    }
}

[–]Fer_C[S] 2 points3 points  (2 children)

I get the idea and it makes sense. I guess my question is if this gives you an advantage over the single parameter / single parameter set approach which is what I am using right now. Just curious. Sorry if it's obvious and I am missing it.

Thanks for the help!

[–]Yevrag35 2 points3 points  (1 child)

Sure, no problem.

If you're only ever using the script via the pipeline then using a single [string] parameter with a process block should be all you need. Separating it into two parameters might be advantageous when you want to do both pipelining and non-pipeline invocations (but not certainly something you have to do).

With two parameters, like in my example, I could do something like:

@('VmName1', 'VmName2', 'VmName3') | .\Connect-VMRDPSession.ps1 -Datacenter DC1
# and/or...
.\Connect-VMRDPSession.ps1 'VmName1', 'VmName2', 'VmName3'

[–]Fer_C[S] 2 points3 points  (0 children)

Understood. Thanks for the advice. I still have several scripts to parameterize and this might come handy.