PowerShell Welcome to this addition of the PowerShell ABC's where you'll find 26 posts detailing a component of the PowerShell scripting language, one letter at a time.  Today's letter is the letter "B".  For "B" I've opted to go with a keyword that you likely don't know about but can allow you write script level functions that behave like compiled Cmdlets.  The word for today is "begin"

beginMost PowerShell users write script level functions as standalone statements that work on values in the pipeline but since functions run all at once, they cannot do streaming processing.  Filters can be used run for each input object coming from the pipeline but they have problems with setting up initial values for variables or performing some processing after all the objects have been received.  For all you Cmdlet writers out there, you may be wanting to be able to create a script level function that behaves like a Cmdlet in that it allows for initialization before the first pipeline object is available, an ability to process each object in the pipeline independently, and perform some finalization after all the pipeline objects have been processed.  This can be achieved with the begin, process, and end keywords!  Since the begin keyword isn't that useful without process and end, I'll throw those in here to give you a bonus 3-for-1 special today.

The complete function definition syntax for a function in PowerShell that will have a Cmdlet-like behavior is as follows:

function  (  )
{
begin {

}
process {

}
end {

}
}

To illustrate how the processing occurs, here is a sample function named MockCmdlet:

function MockCmdlet ($val)
{
    begin {
        $count = 0;
        Write-Host "(  begin) : Count = $count; val = $val";
    }
    process {
        $count++;
        Write-Host "(process) : Count = $count; val = $val; `$_ = $_";
    }
    end {
        Write-Host "(    end) : Count = $count; val = $val";
    }
}

This function takes as input a variable $val.  In the begin block, the counter variable $count is initialized to 0 and the values of the $count and $val variables are written to the console.  In the process block, the $count variable in incremented and the previous two values along with the value of the current pipeline value stored in $_ is written to the console.  And finally, in the end block, the values of $count and $val are written again.  

The following example usage illustrates how the processing of each of these blocks occur.  In this example, I pass in an array of size three with the values 1, 2, and 3 through the pipeline while supplying the value of 5 in the function parameter list.  You'll see that the begin block is processed once, the process block is processed once for each value in the pipeline, and the end block is processed once. 

PS> 1, 2, 3 | MockCmdlet 5
(  begin) : Count = 0; val = 5
(process) : Count = 1; val = 5; $_ = 1
(process) : Count = 2; val = 5; $_ = 2
(process) : Count = 3; val = 5; $_ = 3
(    end) : Count = 3; val = 5

So, if you find yourself wishing you had initialization and termination behavior in your script functions you'll now have the tools you need to make your own function with Cmdlet type behavior.