Hello Readers, Prateek here…. I'm so excited to edit and publish the second article of its kind "a deep dive" written by a friend and guest Author 'Manoj Sahoo'. I'm hoping that you will enjoy reading this long form of content and by the end of this article, you will definitely learn a few tips, tricks, and concepts.. happy learning! ♥

You may also want to check out other articles in this Deep-Dive category:

  • Deep Dive – PowerShell Loops and Iterations
  • Deep Dive – Break, Continue, Return, Exit in PowerShell

Table of Contents

  • Introduction
  • Break
    • Flowchart of Break
    • Break Keyword in a Loop
    • Break Keyword with 'Label'
    • Break Keyword in a Function
    • Quick Summary of Break
  • Continue
    • Flowchart of Continue
    • Continue Keyword in a Loop
    • Exception in case of Foreach-Object
    • Continue Keyword with Label
    • Continue Keyword inside a Function
    • Quick Summary of Continue
  • Return
    • Write-Output cmdlet vs Return Keyword
    • Write-Host cmdlet vs Return Keyword
    • Write-Host vs Write-Output cmdlet
    • Return Multiple Values
    • Return Multiple values and Multi-variable assignment
    • Return keyword outside the function body
    • Return Multi-dimensional array from a function
    • Return keyword in Foreach-Object cmdlet
    • Quick Summary of Return
  • Exit
    • Exit Codes
    • Exit and Try..Catch..Finally
    • Exit and -NoExit
    • Quick Summary of Exit
  • Break, Continue, Return and Exit in Switch Case statement
  • Comparison between Break, Continue, Return, Exit
  • References

[Announcement] PowerShell to C# and back Book

This bookbridges concept and knowledge the gap between a scripting language like PowerShell and modern programming language like C#, which is a natural language of choice for People who know PowerShell.

An increase in adoption of software development inside Infrastructure teams makes this the perfect time to get started with a programming language and C# is a natural choice for people using PowerShell today. As it fits best with the basket of matching skillsets like Azure, Azure DevOps which will add value in your career.

Download the FREE Book Sample from the book web page which covers all the basics of C# within 50 pages – https://leanpub.com/powershell-to-csharp šŸ‘‡ šŸ‘‡ šŸ‘‡


Introduction

This article will deep dive into the concepts and use cases of break, continue, exit and return keywords in PowerShell with examples. We will also look into the comparison between all of these and different ways to use them in your script. Let's start!

Break

Break keyword is used to terminate or exit from a loop (or from the inner loop if it's nested). But this can be used in conjunction with Label to point to the outer loop if it is nested but by default, it will always point to the inner loop. A Label can be defined by using symbol colon ':', the syntax will be :LabelName and can be pointed by writing "Break LabelName". We will have some examples to see how they can be used in a script.

It's recommended to use Break keyword inside a loop but in case we use it simply in a script or inside a function then we will find some surprising results. Like, If we keep the Break keyword inside a function that is not present inside any loop, then whenever the flow of control hit's the Break keyword it will stop executing the whole script. The reason is quite simple, this keyword is meant to be used inside a loop and whenever a Break keyword executes it searches for the loop block and the flow of control moves up to an outer loop instead of the next line. Whereas, if the keyword is not present inside any such loop it stops execution and the control goes out of the current scope. So anything written outside the function will not be executed. We will look into some examples later in this article to understand this.

Flowchart of Break

Break keyword in a loop

Let's look into a simple example to understand this better.

Break Keyword in a Loop

Example 1:

                      foreach            ($value            in            (1..2)) {            Write-Host            "outerloop              $value"            Write-Host            "Going inside innerloop              $value"            foreach            ($letter            in            [char[]]([char]'A'..[char]'C')) {            if            ($letter            -match            "B") {            $letter            Break;         }            else            {            $letter            }     } }            "End of Scripts"                  

Output:

Break keyword in a loop

As you can see in the above output the Break keyword terminates the inner/child loop as soon it is executed by it's default and skips letter 'C' from printing and the control goes back to the outer/parent loop.

Break Keyword with 'Label'

Here is another example to understand how we can terminate the parent loop using 'Label'.

Example 2:

          :parentloop            foreach            ($value            in            (1..2)) {            Write-Host            "outerloop              $value"            Write-Host            "Going inside innerloop              $value"            foreach            ($letter            in            [char[]]([char]'A'..[char]'C')) {            if            ($letter            -match            "B") {            $letter            Break            parentloop;         }            else            {            $letter            }     } }            "End of Scripts"                  

Output:

Break keyword with a Label

Here we can see the outer/parent loop executed once as the Break keyword jumps directly to Label and terminates the outer loop. So by using Label, we can control where the flow of control should go, irrespective of its default behavior.

Break Keyword in a Function

Now, let's see how Break works when placed inside a PowerShell function.

Example 3:

                      function            test {            Write-Host            "Before break statement"            function            foo {            break;     }     foo            Write-Host            "After break statement"            } test            "End of Script"                  

Output:

Break keyword in a Function

As we can see here, the Break tries to find the parent loop and since there is none, it stops executing the script at line-4 and even the 2nd Write-Host cmdlet or the last line "End of Script" is never executed. This shows that the Break is not the best thing to be used in the case of Functions to control the flow of control.

Quick Summary of Break

  1. Break will terminate\exit from a loop
  2. Break will exit from the current loop iteration and will jump to the outer loop if it exists.
  3. Use Label to control the flow of code once Break keyword is encountered in code to override its default behavior

Now let's move on to the next keyword i.e. Continue.


Continue

Continue keyword is used to jump to the next iteration of the loop by skipping the execution of lines after Continue keyword is encountered in the current iteration. In simple words, whenever flow of control will hit Continue keyword inside a loop it will stop executing the ongoing iteration and the control will move to the next expression value in a loop.

Note: In the case of nested loops, if it is present inside the inner loop it will switch to the next expression for the same loop, not to the outer loop i.e. this is the default behavior.

Just like Break keyword, we can also use Labels in Continue using which we can move the control to the outer/parent loop expressions. Continue keyword inside a function will terminate the script because Continue works well only with loops and otherwise unexpected results are observed, in which we will deep dive later in this section.

Flowchart of Continue

Continue keyword in a Loop

Continue Keyword in a Loop

Let's look into a simple use case of Continue keyword first.

Example 4:

                      foreach            ($value            in            (1..2)) {            Write-Host            "outerloop              $value"            Write-Host            "Going inside innerloop              $value"            foreach            ($letter            in            [char[]]([char]'A'..[char]'C')) {            if            ($letter            -match            "B") {            Continue;            $letter            }            else            {            $letter            }     } }            "End of Scripts"                  

Output:

Continue keyword in a Loop

If you look closely in the above output, then you'll observe that every time when the flow of control reaches at line-6 on the continue keyword, it skips the current iteration of the loop and goes to the next expression present in the loop, i.e, by default the control moves to the inner loop.

Exception in case of Foreach-Object

As we have seen in the above example how continue keyword behaves in case of the loop but there is a difference in behavior when it comes to ForEach-Object cmdlet. Though it is used to iterate items from a collection of items or items through the pipeline, so let's not confuse this with a loop and expect similar results. Here is another example to help you understand this better.

Example 4.1:

          [char[]]([char]'A'..[char]'F') |            ForEach-Object            {            if            ($_            -eq            'D') {            continue            }            $_            }            "End of Scripts"                  

Output:

Continue keyword in a Loop

As you can observe from the above output, the Continue keyword is behaving like a break keyword, in case of ForEach-Object that's because Foreach-Object is considered a cmdlet, not a loop, and the curly bracket {} is not loop body, but a [scriptblock]. So Continue is searching for loop iteration to continue, but unable to find one, hence it comes out and exits the script without executing the last line "End of Scripts". Such behavior will also be observed in case of function and we will look into that in later subsections.

Continue Keyword with Label

We can also forcefully move the control to the outer loop using a Label as demonstrated in the next example.

Example 5:

          :parentloop            foreach            ($value            in            (1..2)) {            Write-Host            "outerloop              $value"            Write-Host            "Going inside innerloop              $value"            foreach            ($letter            in            [char[]]([char]'A'..[char]'C')) {            if            ($letter            -match            "B") {            Continue            parentloop;            $letter            }            else            {            $letter            }     } } `            "End of Script"                  

Output

Continue keyword with a Label

Now if we compare above example 4 and 5, you will then notice that in example-4 printing of letter 'B' was skipped, which is present after Continue keyword and the flow of control moved to the next expression of the inner loop. But in example-5 using a Label we have moved the flow of control to the next expression of the outer loop, that's why even printing of letter 'C' was skipped.

Continue Keyword inside a Function

Let's see an example of how Continue keyword behaves inside a PowerShell Function.

Example 6:

                      function            check {            Write-Host            "Before Continue statement"            function            so {            Continue;     }     so            Write-Host            "After Continue statement"            } check            "End of Script"                  

Output:

Continue keyword in a Function

It gives us the same result as Break keyword, which we have already seen in the example-3 under Break subsection. The reason behind this is also the same, as it keeps looking for a loop block to move the flow of control, but since there exists none, the flow of control goes out of scope and it stops the execution of the script.

Quick Summary of Continue

  1. Continue will jump the flow of control to the beginning of the loop in which it is encountered. Rest of the lines in the body of the loop after Continue keyword is not executed.
  2. Loop doesn't terminate but continues on with the next iteration.
  3. Use Label to control the flow of code once Continue keyword is encountered in code to override its the default behavior

Return

Return keyword is used in a function to terminate the function scope and return back to the caller scope i.e. the line from where the function has been called. Using Return we can also catch expression present inside function block and can assign it to a variable in caller scope, also known as returning a value from the function.

To return a value we can write the syntax as follows:

                      function            function1 {            $name            =            "Manoj"            return            $name            }            function1            # alternatively            function            function2 {            $name            =            "Manoj"            $name            return            }            function2                  

Write-Output vs Return inside a function

Important

Both examples mentioned above will provide the same results and will return the value of the $name variable, but there is a difference between their behavior and the overall execution process. Using the above code snippet it's not possible to differentiate but we will attempt to explain this in another example, without which we might miss the concept of return keyword, that may lead to an issue or undesired behavior in PowerShell scripts you create.

Write-Output cmdlet vs Return Keyword

Here is an example here to understand why $name; Return is different from Return $name:

Example 7:

                      Function            MyFunction {            $name            =            "Manoj"            $name            # Or write-output $name            sleep(30)            Return            }  MyFunction |            Out-File            file.txt                  

In the above code snippet, we have intentionally introduced a 30 seconds sleep() so that we can observe the difference between the two approaches. But before that just to re-enforce the fact that, Powershell is an interpreted language which means the code is interpreted one line at a time. That being said, when we execute the above example, then the function is called from the caller scope and the interpreter starts executing commands in function's body line by line. On reaching line-3 $name which is also equivalent of Write-Output $name it will send the value of $name variable to the pipeline directly. Now, since we have a Out-File cmdlet just after the pipeline, so the output from the function would be piped to it, without waiting for the whole body of the function to complete execution and returning the flow of control to the next line from where the function was called. Even if we explicitly close the PowerShell during this sleep(), then also the file will be created with the content.

As demonstrated in the following screenshot, the function when executed is still running, in fact, sleeping for 30 secs and meanwhile, the content has been already written to the file.

Write-Output vs Return inside a function

But if we choose to write Return $name and instead of the previous approach, then the value of $name will be sent to the Out-File once the flow of control returns to the calling function.

                      Function            MyFunction2 {            $name            =            "Manoj"            sleep(30)            Return            $name            }  MyFunction2 |            Out-File            file2.txt                  

As demonstrated in the following screenshot, the function is still running but no content has been written to the file: file2.txt yet and will only do so once return keyword is encountered at last line of function's body which will return the value of $name variable on the left hand side of the pipeline. This value will be eventually pass through the pipeline to the Out-File cmdlet. Please try this use case by yourself to get an understanding of these different approaches.

Output:

Write-Output vs Return inside a function

NOTE: Both approaches are right and nothing wrong with using either of them, as it totally depends on the use case to use case basis what is best for the situation.

In fact this ability to capture values like $name and appending them into a file, before the flow of control returns to the scope where the function was called, can be useful in writing critical scripts to record the logs of each executed step. For sake of example, any abnormal shutdown will have a log file created and we can track our execution process and identify on which step the script failed. This won't be possible if our function only returned values upon return, so it's more like a trade-off to choose what is the best approach for our scenario.

Following code snippet, when executed will exit the powershell.exe if a service name "BITS" was found. But, even though it will exit the script, before even reaching to the return statement, you can check the file it was writing and you'll observe the names of services were being written to the file, where the last name written is BITS.

                      function            GetService {            $Services            =            Get-Service            foreach            ($Service            in            $Services) {            if            ($Service.Name            -like            "b*") {            $Service.name |            Out-File            svc.txt -Append            # synthetic event where something goes wrong            if            ($Service.Name            -eq            'BITS') {            exit            # or Restart-Computer            }         }     }            return            }                  

Write-Output vs Return inside a function

Write-Host cmdlet vs Return Keyword

Now, lets see an example of Write-Host and Write-Output inside a function, and how they return values and assigning these values to another variable in caller scope.

Example 9:

                      function            CaptureService {            $services            =            Get-Service            foreach            ($service            in            $services) {            if            ($service.Name            -eq            "VSS") {            $service            Write-host            "`nHello !"            -Foreground Green            return            }     } }            $serviceName            = CaptureService            "`nService Name: $($serviceName.name)"            "`nEnd of script!"                  

Output:

Return vs Write-Host

Write-Host cmdlet at line-6 inside the function will write\print the value directly to the console application, avoiding the pipeline. So this value can not be assigned to a variable in the caller scope unless it is redirected to the output\success stream. Check out the following article to learn more about stream redirection

  • About Redirection
  • Understanding Streams, Redirection, and Write-Host in PowerShell

Only the value of the variable $service is returned to the caller scope at line-11 and we have assigned the value to $serviceName variable. This means $service variable will hold a [string] value VSS and that will go to the pipeline and assigned to $service variable through assignment operator, Hence we see the service name printed in the next line. But "Hello!" will be printed to the console and won't be assigned to a variable, unless redirected to the output stream.

Write-Host vs Write-Output cmdlet

Let's have another similar example and instead of using Write-Host we would be using Write-Output and we will see differences in output.

                      function            CaptureService {            $services            =            Get-Service            foreach            ($service            in            $services) {            if            ($service.Name            -eq            "VSS") {            $service            Write-Output            "`nHello !"            return            }     } }            $serviceName            = CaptureService            "`nService Name: $($serviceName.Name)"            "`nEnd of script!"                  

Output:

Write-Host vs Write-Output

Write-Output cmdlet is used to send the output objects from the left-hand side of the pipeline through the pipeline to the next command. So once the function is called the value of $service and [String] object from the function body is returned and saved to the variable $servicename, unlike Write-Host which would have printed the value to the console directly. Hence, executing the $serviceName will output both [ServiceController] and [String] objects.

Note: Use of a variable name directly or with Write-Object both will return a value that can be passed to the pipeline and can be used alternatively. Like in the following example both would have similar behavior:

Example 11.1:

                      # function definition            Function            Test {            Write-Output            'String'            return            }            # alternatively            Function            Test {            'String'            return            }            $value            = Test                  

In the above example, both functions will return the same value to the variable $value

Return Multiple Values

By now we already know how to return single values to the caller scope as demonstrated in the following example:

                      function            SingleValue {            $a            =            10            # returns one value            return            $a+1            }  SingleValue                  

But there would be some use cases when you want to return more than one value to the caller scope, so we are going to look into it with some examples.

Example 11.2:

                      function            MultipleValue {            $a            =            10            $b            =            $a            +            10            $c            =            $b            +            10            # returns more than one value            return            $a,$b,$c            }            # function call            MultipleValue                  

Output:

Return Multiple values and Multi-variable assignment

In the previous example, 3 values were returned to the caller scope, we can save these values to a variable. But instead, we can also assign these 3 different values to 3 different variables like in the following code snippet and screenshot.

Example 12:

                      function            MultipleValue {            $a            =            10            $b            =            $a            +            10            $c            =            $b            +            10            # returns more than one value            return            $a,$b,$c            }            # function call and assignment to variables            $var1,            $var2,            $var3            = MultipleValue                  

Please make sure the count of values returned has equal variables for assignment, otherwise, all the extra values returned will be assigned to the last variable. Like in the following example $var2 has been assigned two values 20 and 30, because 3 values are returned and we only have two variables to assign.

In the opposite scenario, where we have more variables than count of values returned, then, in that case, extra variables will be empty with no value assigned to them. Like in the following screenshot you can see that no value has been assigned to the variable $var4.

Return keyword outside the Function body

The return keyword is not only restricted to functions, and can be directly used in the script, not in function body or a script block. Let's see an example and understand it's behavior then.

Example 13:

                      Get-Service            bits            return            Get-Process            explorer                  

Output

As we can see the value of $service has simply printed and after that, the execution of script stops, because return keyword is used to return to the caller scope as there is no caller scope it stops searching and ends the script.

Return Multi-dimensional array from a Function

Often you will come across scenarios, where you want to return a multi-dimensional array. Let's look into some examples where I will show you 2 ways of creating and returning a 2D array. One important concept here is to understand the use of (,) operator also knowns as unary array construction operator. The comma operator wraps one array with another one to create multi-dimensional.

Example 14.1:

                      function            2DArray {            $array1            = @()            # define empty array            # assign array to an array index to make it 2-dimensional            $array1            += ,@("Microsoft","Google")            $array1            += ,@("Amazon","Apple")            return            $array1            }            $array2            =            2DArray            $array2[1][1]            # accessing 2nd element of 2nd row in array            $array2[0][1]            # accessing 2nd element of 1st row in array                  

Return multidimensional array from function

                      function            2DArray {            $array1            = @()            # define empty array            # assign array to an array index to make it 2-dimensional            $array1            += ,@("Microsoft","Google")            $array1            += ,@("Amazon","Apple")            return            $array1            }            $array2            =            2DArray            $array2.Rank            # check the dimension of the array                  

Alternatively, you can also create the array without using the += shorthand as demonstrated in the following example. I know the syntax looks little weird, but that is how it is šŸ™‚

                      $array1            = @()            # define empty array            # alternatively            $array1            =            $array1            + ,@("Microsoft","Google")            $array1            =            $array1            + ,@("Amazon","Apple")                  

Return multidimensional array from function

But, aren't we suppose to get Rank = 2 for a two-dimensional array? YES. In PowerShell most arrays have one dimensional only, even when you think you are building a multi-dimensional array. To create a truly multidimensional array you have to use .Net Framework as demonstrated in the following example.

                      # building a 2D array using .Net Framework            $array            =            New-Object            'object[,]'            2,            2                  

NOTE: Even though we are using .Net Classes to make an Array, even then while returning an Array from a function it is unrolled or we can say thatexpands to flat Array which is single dimensional. To avoid that you have to use ( , ) comma operator with return keyword as well.

Example 14.2:

                      function            2DArray() {            $array            =            New-Object            'object[,]'            2,            2            $array[0,0] =            "Microsoft"            $array[0,1] =            "Google"            $array[1,0] =            "Amazon"            $array[1,1] =            "Apple"            Write-Host            "Dimension:"            $array.rank -Foreground Magenta            return            ,$array            }            $array            =            2DArray            # accessing the elements            $array[0,0]            $array[1,0]                  

Output

Return multidimensional array from function

Return keyword in Foreach-Object cmdlet

Before we can look into how return keyword behaves with Foreach-Object cmdlet, first we need to understand that Foreach-Object accept [scriptblock] as an input. Scripts are nothing but un-named or anonymous functions as demonstrated in the following example:

Example 15.1:

                      $scriptblock            = {            if($args[0]            -ne            5){            return            'RETURNED'            }            $args[0] }            # calling the script block with arguments            &            $scriptblock            5            &            $scriptblock            2            &            $scriptblock            1                  

Return keyword in foreach-object

Nothing changes with Foreach-Object cmdlet each value from a pipeline is passed to the [scriptblock] and if the condition meets the flow of control will move to the caller scope at the other end of the pipeline but, because of values which are coming through the pipe Foreach-Object will keep iterating and executing the [scriptblock] times the value on the left-hand side of the PowerShell pipeline.

Example 15.2:

                      1..10            |            ForEach-Object            -Process {            if($_            -ne            5){            return            'RETURNED to Caller Scope'            }            $_            }                  

Return keyword in foreach-object

Quick Summary of Return

  1. Return statement abort the code when executed and continues the flow of code in caller scope. And often used to write the optional expression to output.
  2. Primary use-case of return is to return the flow of control to caller scope, but it can be also used to return 1 or more value(s) to the caller scope.
  3. More than one occurrence of return can be used in logic, but once the first return statement is executed, the flow of control jumps to the caller scope.
  4. Please don't confuse with the behavior of a return in a function and a cmdlet like Foreach-Object that uses a [scriptblock], because the behavior is the same.

Exit

Exit keyword is used to leave the current context wherein the script it has been used. This means if we use the exit keyword in a function and run the script which has this function, then it will abort the code at the caller scope, which is in this context means the running script. Like you can see from the following screenshot once the function:foo executes, since an Exit keyword is used in the function body it aborts the function and the current context of the script which is the test.ps1 script, this is the reason why the next line "End of the script" is not executed.

                      Function            foo {            "Start of function"            exit            "End of function"            }            "Start of script"            foo            "End of script"                  

Exit keyword

But, if we use the Exit statement directly in a PowerShell console it will kill the PowerShell instance.

Exit Codes

The exit statement allows us to return some exit codes as well. In PowerShell, an Exit statement sets the value of the $LASTEXITCODE variable.

Syntax:

                      exit            exit            <exitcode>                  

Like in the following example we didn't just abort the current context using the exit statement but the value of $LASTEXITCODE is set to 2. This can be very useful to indicate status and be utilized in post validation in the script, to understand what happened in the function while execution.

                      Function            foo {            Write-Host            "Inside Function Body"            -ForegroundColor Green            exit            2            }  foo                  

Returning Exit Codes

Exit and Try…Catch…Finally

If we have defined try..catch..finally blocks in our code and mentioned an exit statement in the try..catch block, upon execution it will still run the code in finally block, even if it is supposed to leave the current context. The script will abort\terminate the current PowerShell session only after the code in finally block is executed.

As demonstrated in the following example, even though script terminates when $i = 5 as the exit statement is executed, you can still see that the finally block inserted a string output to the file.

                      try            {            $i            =            0            While(1){            Start-Sleep            -Seconds            2            if($i            -eq            5){            exit            }            else{            $i=$i+1            $i            |            Out-File            num.txt -Append            $i            }     } }            catch            {            # placeholder            }            finally            {            "End of script from finally block"            |            Out-File            num.txt -Append }                  

'Exit' and '-NoExit'

Sometimes when we execute Powershell.exe from CMD prompt and the PowerShell executable has a -NoExit switch parameter, this parameter once used will not abort the launched PowerShell session and you will notice after the commands are executed it remains in the PowerShell Session and doesn't come back to CMD. To forcefully abort the script or the context you have to manually specify the Exit in the command or the script file as demonstrated in the following image.

Now let's see what will happen if we define a script test.ps1 with exit keyword, like one in the following example

                      # test.ps1            Write-Host            "Hello World!"            Exit                  

When we call this script from CMD.exe using the PowerShell executable, with -noexit switch parameter. Then first it will abort the script context of test.ps1 where exit statement is used and flow of control returns to PowerShell.exe session and stops there. But it doesn't abort the PowerShell.exe session to return to CMD.exe prompt because of the -NoExit switch, unless you explicitly specify exit in-scope where test.ps1 script is called. I know little, mind-boggling, please read again it will give you little more clarity.

The whole purpose to understand this behavior is to know when and how to use Exit with -NoExit switch parameter together and the trade-off.

For example: If we called a child PowerShell script from another parent PowerShell script which contains exit then, in that case, it will not stop the execution of the parent script and will only exit the child script in which exit keyword is present.

And if you define the exit statement in parent script then only it will abort the execution, before executing the rest of the code, as demonstrated in the following example.

Quick Summary of Exit

  1. Exit keyword is primarily used to leave the current context of a function or script.
  2. If Exit keyword is used in try block, then before aborting the current context the finally block will be executed at all times if it is defined.

Break, Continue, Return and Exit in Switch Case statement

Now as we have covered those 4 keywords using it in different case let's see how it behaves when we use the same in Switch case.

                      $a            =            1,2,3            switch($a) {            1            {            "1st block"            #break            #continue            #return            #exit            "End of 1st block"            }            2            {            "2nd block"            "End of 2nd block"            }            3            {            "3rd block"            "End of 3rd block"            }     default {            "default block"            "End of default block"            } } `            "End of Script!"                  

As we can see from the output all the 3 blocks executed as $a is an array containing 1, 2 and 3 and it matches with the block name. The default block will only execute if in case $a is null.

Now let's see if we use the keywords what output we get.

Let's remove the pound sign # from each keyword and observe the difference in the output. While removing from one keeping others commented.

Removing comments from Break

As far as we are concerned about the behavior of Break, it has moved the flow of control outside of Switch statement. This is just like its behavior within PowerShell loops.

                      $a            =            1,2,3            switch($a) {            1            {            "1st block"            break            #continue            #return            #exit            "End of 1st block"            }            2            {            "2nd block"            "End of 2nd block"            }            3            {            "3rd block"            "End of 3rd block"            }     default {            "default block"            "End of default block"            } } `            "End of Script!"                  

If required we can also use Label to change the default behavior of break in a nested switch case to handle the flow of control as per our requirements, exactly like we did with PowerShell Loops.

Removing Comment from Continue

When we use Continue keyword in a Switch case, it skips the next line(s) that are present after Continue keyword and the control moves to the next expression., which can be the next case defined in PowerShell Switch as demonstrated in the following example. Just like Break, the Continue statement can also be used with Label in a nested Switch case.

                      $a            =            1,2,3            switch($a) {            1            {            "1st block"            #break            continue            #return            #exit            "End of 1st block"            }            2            {            "2nd block"            "End of 2nd block"            }            3            {            "3rd block"            "End of 3rd block"            }     default {            "default block"            "End of default block"            } } `            "End of Script!"                  

Removing Comments from Return

The Return keyword returns the flow of control to the caller scope from the scope of the function in which it is defined. Since in this case there is no function, that is why the execution stops once it hits Return keyword. Nothing after that will be executed as we can observe in the following example.

                      $a            =            1,2,3            switch($a) {            1            {            "1st block"            #break            #continue            return            #exit            "End of 1st block"            }            2            {            "2nd block"            "End of 2nd block"            }            3            {            "3rd block"            "End of 3rd block"            }     default {            "default block"            "End of default block"            } } `            "End of Script!"                  

Removing Comments from Exit

The output is similar to the Return but, it also terminates PowerShell which is not the same in the case of return.

                      $a            =            1,2,3            switch($a) {            1            {            "1st block"            #break            #continue            #return            exit            "End of 1st block"            }            2            {            "2nd block"            "End of 2nd block"            }            3            {            "3rd block"            "End of 3rd block"            }     default {            "default block"            "End of default block"            } } `            "End of Script!"                  

As we have gone in deep with each keyword now let's have a comparison between them to understand what are there similarities and differences in brief.

Comparison between Break, Continue, Return, Exit

# Break Continue Return Exit
USAGE Mostly used in loops and switch cases to break out of the current iteration of the current loop Used in case of loops and switch cases to continue execution of the next iteration of the loop Used in PowerShell Functions to return values or flow of control to the caller scope Exit can be used anywhere in the script to terminate\abort current context
OVERRIDE DEFAULT BEHAVIOR Break can be used in conjunction of Label to control the flow of control, irrespective of the default behavior Continue can be used in conjunction of Label to control the flow of control, irrespective of the default behavior N/A N/A
PIPELINES N/A N/A We can return a single or multiple values to the caller scope which can be pipelined. N/A
RECOMMENDATION Recommended to be used inside a loop or switch cases. Recommended to be used inside a loop or switch cases. Recommended to be used inside a function block. No recommendation can be used anywhere.

NOTE

Each keyword behaves differently in different use cases, but if the right keyword is chosen for the right use case or scenario, it can optimize the code with respect to memory consumption, execution speed, and code complexity. More than that it is easier for other developers to understand why a particular keyword was used in that specific scenario.

In conclusion, I want to say that it is again the choice of the developer to use any of these keywords as desired, but keeping in mind the purpose why these keywords are introduced in any programming language may help to define right things at right places making your code more readable and understandable.

References

https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/46
https://www.sapien.com/blog/2009/06/02/powershell-functions-return-vs-write/
https://www.vistax64.com/threads/using-labels-in-powershell.36544/
https://www.computerperformance.co.uk/powershell/continue/
https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/understanding-break-continue-return-and-exit
https://stackoverflow.com/questions/40220590/return-multidimensional-array-from-function

Optical Character Recognition
~ Author of "PowerShell Guide to Python",  and currently writing a Book on "Windows Subsystem for Linux (WSL)"


All my books are available as a discounted bundle:

    1. PowerShell Guide to Python :ThisPowerShell Scripting guide to Python is designed to make readers familiar withsyntax, semantics and core concepts of Python language, in an approach thatreaders can totally relate with the concepts of PowerShell already in their arsenal, to learn Python fast and effectively, such that itsticks with readers for longer time.
    2. Windows Subsystem for Linux (WSL) : Keywords, definitions, and problems WSL solve and how it works under the hoods. From download to setup to interoperability this book even covers details like the architecture of Windows subsystem for Linux and new features in WSL 2 with some wonderful use cases.