Process Block and a foreach within

This topic contains 3 replies, has 2 voices, and was last updated by Profile photo of Chris Burns Chris Burns 3 weeks, 2 days ago.

  • Author
    Posts
  • #67702
    Profile photo of Chris Burns
    Chris Burns
    Participant

    Can anyone advise why?

    Lets say i create an Advanced function that accepts pipeline input for computers...
    Within the process block i have a foreach which iterates over the computers..

    If process will loop for each computer, then in my mind the foreach will also loop twice per pass.

    How does powershell know not to loop four times...

    Watching Jeffery Snover on the Advanced functions MVA course and i am scratching my head... if anyone can explain i would be very thankful.

    Chris

  • #67704
    Profile photo of Chris Burns
    Chris Burns
    Participant

    here is an example

    function Get-ServiceState
    {
    [CmdletBinding(SupportsShouldProcess=$true)]

    Param
    (
    # Param1 help description
    [Parameter(Mandatory=$true,
    ValueFromPipeline=$true,
    ValueFromPipelineByPropertyName=$true,
    Position=0)]
    [Alias("sv")]
    [String[]]$Service
    )

    Begin
    {
    Write-host "Setting Up"
    }
    Process
    {

    write-host $Service

    }
    End
    {
    }
    }

    passing variables like this
    $records = @('BITS','Browser')
    $records | get-servicestate

    produces a very different output to

    get-servicestate -Service Bits,Browser

    What is the best way to deal with these two methods to achieve the same thing?

    I assume using foreach ($s in $Service) { }

    Thanks for your help

  • #67705
    Profile photo of Dudebro
    Dudebro
    Participant

    When you pipe a collection of objects to the function, the Process block runs once for each of the objects. When you pass the collection by parameter, the process block runs one time for the whole collection.

    You could do something like this:

    Function Write-CoolMessage
    {
        [CmdletBinding()]
    
        Param
        (
            [Parameter( ValueFromPipeline )]
            [String[]]
                $Message
        )
    
        Process
        {
            $Message | ForEach-Object {
                Write-Host "COOL: $_" -ForegroundColor "Green"
            }
        }
    }
    

    The following commands will return the same result:

    "Message1", "Message2" | Write-CoolMessage
    Write-CoolMessage -Message "Message1", "Message2"
    
    • #67707
      Profile photo of Chris Burns
      Chris Burns
      Participant

      Sir,

      You are an absolute star.... I understood that the process ran for each entry passed, but for the life of me i couldn't figure out how to run the foreach once and deal with both types of input....

      Your solution is exactly what i needed to understand how to deal with these two scenarios....

      Thank you ever so much....

      Chris

You must be logged in to reply to this topic.