powershell

Powershell Array parameter from pipline


I'm trying to duplicate a typical powershell -Computername parameter that's available from the pipeline and as a normal parameter using CmdletBinding and ValueFromPipeline. My challenge is that I'm getting different results from specifying the parameter versus piping in values.

My code looks like this:

[CmdletBinding()]
param(
    [parameter(Mandatory=$true, ValueFromPipeline=$true)] [string[]]$ComputerName
 )

BEGIN {  "Begin script`n-----" }

PROCESS { 
    "  `$ComputerName '$ComputerName'"
    "  `$_ '$_'"
    "  +++ Count: " + $ComputerName.Count
    foreach($computer in $ComputerName) {
        "    `$computer '$computer'"
    }
    "  -----"
}

END { "Complete" }

When I run this using a pipeline, I get this:

PS> (1, 2, 3) | .\BPEParamTest.ps1
Begin script
-----
  $ComputerName '1'
  $_ '1'
  +++ Count: 1
    $computer '1'
  -----
  $ComputerName '2'
  $_ '2'
  +++ Count: 1
    $computer '2'
  -----
  $ComputerName '3'
  $_ '3'
  +++ Count: 1
    $computer '3'
  -----
Complete

However, when run with a parameter, I get different results:

PS> .\BPEParamTest.ps1 -ComputerName (1, 2, 3)
Begin script
-----
  $ComputerName '1 2 3'
  $_ ''
  +++ Count: 3
    $computer '1'
    $computer '2'
    $computer '3'
  -----
Complete

Solution

  • I always use the following construction. This works for arrays in a parameter as well as from the pipeline:

    [CmdletBinding()]
    param(
        [parameter(Mandatory=$true, ValueFromPipeline=$true)] [string[]]$ComputerName
     )
    
    process {
      foreach($computer in $computername){
          #do the stuff
      }
    

    Full explanation: The process block is run once for each item in the pipeline, so that's how it handles lists on the pipeline (i.e. $computername is set to each item in turn). If you pass the values as a parameter, the $computername is set to the list which is why there's a loop.