Powershell begin Process End output

Faris Malaeb 1 Reputation point
2020-08-31T10:07:58.093+00:00

hi,
I have the following simple script, this is not running in a function, its running direct in the script

  [CmdletBinding()]
   Param(
     [Parameter(ValueFromPipeline=$True)]
     [String[]]$Computers
   )

   Begin {
      Write-host "Starting Point" -ForegroundColor Yellow

   }

   Process {
   Write-Host $Computers.GetType() -ForegroundColor Red
      Write-Host $Computers

   }

   End {
      Write-host "Remove Variable" -ForegroundColor Yellow

   }

But I don't understand the behavior of the output if the script executed like the following

**.\TestPipline.ps1 -Computers "1","2"**

The output is Starting Point
System.String[]
1 2
Remove Variable

If the script executed like the following "1","2" |.\TestPipline.ps1

The result is displayed correctly, which is like this

Starting Point
System.String[]
1
System.String[]
2
Remove Variable

Notice that in the first execution, the 1 and 2 are passed as a single line(object), but on the second execution, the 1 first passed and processed and then 2.
what I am missing here, how to make 1 and 2 always passed and processed separately

Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,558 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. SChalakov 10,391 Reputation points MVP
    2020-08-31T11:33:19.53+00:00

    Hi @Faris Malaeb ,

    both of those sources explain why the behavior is different in both cases:

    Advanced PowerShell Functions: Begin to Process to End

    and also here

    Understanding PowerShell Begin, Process, and End blocks

    ----------

    (If the reply was helpful please don't forget to upvote or accept as answer, thank you)
    Regards,
    Stoyan

    0 comments No comments

  2. Rich Matheisen 46,896 Reputation points
    2020-08-31T14:40:04.667+00:00

    When you pipe an array into a script/function, each element of the array is sent into the pipe individually. When you use that array as a parameter, the entire array is used as a single object. You can get the behavior you want like this:

    [CmdletBinding()]
        Param(
          [Parameter(ValueFromPipeline=$True)]
          [String[]]$Computers
        )
    
        Begin {
           Write-host "Starting Point" -ForegroundColor Yellow
    
        }
    
        Process {
            $Computers |
                ForEach-Object{
                    Write-Host $_.GetType() -ForegroundColor Red
                    Write-Host $_
                }
        }
    
        End {
           Write-host "Remove Variable" -ForegroundColor Yellow
    
        }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.