Powershell Type Question

Am I correct in my conceptual understanding described below?
I was confused about how to interpret a note about collections in Powershell as a parameter.

Concept Collection Paramaters
An argument being fed into a parameter, that is a collection parameter, must be of the same type. I must convert my gigantic string of computer names into an array list of computer names or a hashtable key (computername), Value (comp1). I should not try to pipe or otherwise feed a collection into a scalar (single instance?) parameter type.

Not quite. Pipeline handling works a bit differently. If you have a cmdlet or function that has a pipeline parameter it can be irrelevant that it’s a scalar parameter, provided the code is designed properly. As a quick example:

function Get-Scalar {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [int]
        $Value
    )
    process {
        $Value
    }
}

function Get-Array {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [int[]]
        $Value
    )
    process {
        $Value
    }
}

1..10 | Get-Scalar

1..10 | Get-Array

The only difference between the two is that (again, depending on how the internals are coded) the latter function might be able to handle Get-Array -Value (1…10) as well. In this case, I haven’t coded for that possibility, so it would be more sensible to type it as [int].

Your rule of thumb is Get-Help <command></command> -Parameter * – if the parameter you’re interested in indicates that it can take pipeline input ByValue then you can pipe any amount of items directly in. If it only takes it ByPropertyName then it will retrieve the value from a property<command></command> of an object<command></command> piped in, rather than using the whole piped in item.

And while it’s generally best to keep things the same type for maximum predictability, there are a lot of cases where PowerShell will happily convert your types for you, even with arrays:

$array = 1..10
$array.GetType() # -> [int[]]

$array2 = [string[]]$array
$array2.GetType() # -> [string[]]

 

That makes sense, thank-you!