Skip Process and End Blocks

I started to reply to this recent Tweet on Twitter when I stopped and jumped into a new post here instead. It’s been awhile, but I’ve found a Tweet I couldn’t reply to in the allotted characters allowed by Twitter (these days). This isn’t to say I reply to everything. It does say however, that I’m intrigued by the Twitter, posed question. Here’s that Tweet now. Well, mostly. It was deleted at some point after I started this post, so here’s the text that was that Tweet.

“Is there a fast way to return from Function from within Begin {}
without having to go thru Process/End ? #PowerShell”

— (Name and handle removed) October 16, 2018

My first thought here was, why would Process and End take so long to finish that someone wouldn’t want them to execute? In my world, we put as little code into our functions as possible. I’ve said it multiple times already, but I’d rather have five, 20 line functions, before I had one, 100 line script. This makes troubleshooting so much easier. If I can immediately remove 60, or 80, lines in which to deal with, then I’m all for it. Well, I’m not in charge of everyone’s functions and scripts, so I quickly pushed that thought away. This and that fact that there wasn’t a mention of too much code in the Process and End blocks.

Next, I recalled what I’ve done a few times. In some tooling I’ve written in the past, I’ve created a variable that only when True ($true), would it allow the code to fully enter into the Process/End block. Something like the below example, which uses the same variable to determine whether the blocks, other than the Begin block, are executed.

Here’s how this works: The below Limit-BlockUsageOne function chooses a random number — either 1 or 2 — inside the Begin block. If the numeric value is 1, as stored in $RandomNumber, we will enter the Process and End blocks. If it’s 2, we will only enter the two additional blocks long enough to know we won’t run any additional code from inside those two blocks. We can’t completely avoid them, or skip them, but we can get close.

Clear-Host
Function Limit-BlockUsageOne {
    [CmdletBinding()]
    Param (
    )

    Begin {
        $RandomNumber = Get-Random -Minimum 1 -Maximum 3
    } # End Begin
    Process {
        If ($RandomNumber -eq 1) {
            "Inside the Process block."
        } # End If.
    } # End Process.
    End {
        If ($RandomNumber -eq 1) {
            "Inside the End block."
        } # End If.
    } # End End.
 } # End Function: Limit-BlockUsageOne

1..10 | ForEach-Object {
    "-----Execution # $_-----"
    Limit-BlockUsageOne
}

So again, while we do enter the Process and End blocks, we leave almost instantly when the value stored in the $RandomNumber variable is a 2. Here’s some random results, based on the Get-Random cmdlet, which is used inside the Limit-BlockUsageOne function.

-----Execution # 1-----
-----Execution # 2-----
-----Execution # 3-----
-----Execution # 4-----
Inside the Process block.
Inside the End block.
-----Execution # 5-----
Inside the Process block.
Inside the End block.
-----Execution # 6-----
-----Execution # 7-----
-----Execution # 8-----
Inside the Process block.
Inside the End block.
-----Execution # 9-----
Inside the Process block.
Inside the End block.
-----Execution # 10-----
Inside the Process block.
Inside the End block.

Another thought, because there was at least a couple, was to make use of the break command within the Begin block. Part of me wonders if this option is why the Tweet was deleted — did he figured out the answer to his own question? In this next example, we simply exit the function the moment after we write the “Begin” string. Simple.

Function Limit-BlockUsageTwo {
    Begin {
        'Begin.'
        break
    }
    Process {
        'Process'
    }
    End {
        'End.'
    }
} # End Limit-BlockUsageTwo.

The output of the above function is always going to be the string “Begin”. Because of the break command, we’ll never see the string “Process” or “End” output to the screen. Do keep in mind that we can add some logic to determine whether or not the break command is actually  executed. This, much as we did when we checked for the numeric value of 1 and 2 in the previous example. Do note that this option can in fact completely avoid executing any code inside the Process and End blocks. Based on the Tweet, that’s exactly what the user was after.

While I can’t think of an official way to avoid going through Process or End — you know, like something built in — there’s a couple ways to get there and get close, even if it’s not official.

Leave a Reply

Your email address will not be published. Required fields are marked *