Terminating a script in PowerShell

Powershell

Powershell Problem Overview


I've been looking for a way to terminate a PowerShell (PS1) script when an unrecoverable error occurs within a function. For example:

function foo() {
    # Do stuff that causes an error
    $host.Exit()
}

Of course there's no such thing as $host.Exit(). There is $host.SetShouldExit(), but this actually closes the console window, which is not what I want. What I need is something equivalent to Python's sys.exit() that will simply stop execution of the current script without further adieu.

Edit: Yeah, it's just exit. Duh.

Powershell Solutions


Solution 1 - Powershell

I realize this is an old post but I find myself coming back to this thread a lot as it is one of the top search results when searching for this topic. However, I always leave more confused then when I came due to the conflicting information. Ultimately I always have to perform my own tests to figure it out. So this time I will post my findings.

TL;DR Most people will want to use Exit to terminate a running scripts. However, if your script is merely declaring functions to later be used in a shell, then you will want to use Return in the definitions of said functions.

Exit vs Return vs Break

  • Exit: This will "exit" the currently running context. If you call this command from a script it will exit the script. If you call this command from the shell it will exit the shell.

If a function calls the Exit command it will exit what ever context it is running in. So if that function is only called from within a running script it will exit that script. However, if your script merely declares the function so that it can be used from the current shell and you run that function from the shell, it will exit the shell because the shell is the context in which the function contianing the Exit command is running.

Note: By default if you right click on a script to run it in PowerShell, once the script is done running, PowerShell will close automatically. This has nothing to do with the Exit command or anything else in your script. It is just a default PowerShell behavior for scripts being ran using this specific method of running a script. The same is true for batch files and the Command Line window.

  • Return: This will return to the previous call point. If you call this command from a script (outside any functions) it will return to the shell. If you call this command from the shell it will return to the shell (which is the previous call point for a single command ran from the shell). If you call this command from a function it will return to where ever the function was called from.

Execution of any commands after the call point that it is returned to will continue from that point. If a script is called from the shell and it contains the Return command outside any functions then when it returns to the shell there are no more commands to run thus making a Return used in this way essentially the same as Exit.

  • Break: This will break out of loops and switch cases. If you call this command while not in a loop or switch case it will break out of the script. If you call Break inside a loop that is nested inside a loop it will only break out of the loop it was called in.

There is also an interesting feature of Break where you can prefix a loop with a label and then you can break out of that labeled loop even if the Break command is called within several nested groups within that labeled loop.

    While ($true) {
        # Code here will run

        :myLabel While ($true) {
            # Code here will run

            While ($true) {
                # Code here will run

                While ($true) {
                    # Code here will run
                    Break myLabel
                    # Code here will not run
                }
                
                # Code here will not run
            }

            # Code here will not run
        }

        # Code here will run
    }

Solution 2 - Powershell

You should use the exit keyword.

Solution 3 - Powershell

Exit will exit PowerShell too. If you wish to "break" out of just the current function or script - use Break :)

If ($Breakout -eq $true)
{
     Write-Host "Break Out!"
     Break
}
ElseIf ($Breakout -eq $false)
{
     Write-Host "No Breakout for you!"
}
Else
{
    Write-Host "Breakout wasn't defined..."
}

Solution 4 - Powershell

Write-Error is for non-terminating errors and throw is for terminating errors

> The Write-Error cmdlet declares a non-terminating error. By default, > errors are sent in the error stream to the host program to be > displayed, along with output. > > Non-terminating errors write an error to the error stream, but > they do not stop command processing. If a non-terminating error is > declared on one item in a collection of input items, the command > continues to process the other items in the collection. > > To declare a > terminating error, use the Throw keyword. For more information, see > about_Throw (http://go.microsoft.com/fwlink/?LinkID=145153).

Solution 5 - Powershell

Terminates this process and gives the underlying operating system the specified exit code.

https://msdn.microsoft.com/en-us/library/system.environment.exit%28v=vs.110%29.aspx

[Environment]::Exit(1)

This will allow you to exit with a specific exit code, that can be picked up from the caller.

Solution 6 - Powershell

Throwing an exception will be good especially if you want to clarify the error reason:

throw "Error Message"

This will generate a terminating error.

Solution 7 - Powershell

I think you are looking for Return instead of Break. Break is typically used for loops and only breaks from the innermost code block. Use Return to exit a function or script.

Solution 8 - Powershell

I coincidentally found out that Break <UnknownLabel> (e.g. simply Break Script, where the label Script doesn't exists) appears to break out of the entire script (even from within a function) and keeps the host alive.
This way you could create a function that breaks the script from anywhere (e.g. a recursive loop) without knowing the current scope (and creating labels):

Function Quit($Text) {
    Write-Host "Quiting because: " $Text
    Break Script
} 

Solution 9 - Powershell

May be it is better to use "trap". A PowerShell trap specifies a codeblock to run when a terminating or error occurs. Type

Get-Help about_trap

to learn more about the trap statement.

Solution 10 - Powershell

I used this for a reruning of a program. I don't know if it would help, but it is a simple if statement requiring only two different entry's. It worked in powershell for me.

$rerun = Read-Host "Rerun report (y/n)?"

if($rerun -eq "y") { Show-MemoryReport }
if($rerun -eq "n") { Exit }

Don't know if this helps, but i believe this would be along the lines of terminating a program after you have run it. However in this case, every defined input requires a listed and categorized output. You could also have the exit call up a new prompt line and terminate the program that way.

Solution 11 - Powershell

I thought up a neat little trick to do just that, when I wanted a function to exit a script without throwing an error, but not exit the console if the function was used from there. It involves the $PSScriptRoot automatic variable that is only defined when running a script.

if($PSScriptRoot){exit}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkprobstView Question on Stackoverflow
Solution 1 - PowershellNew GuyView Answer on Stackoverflow
Solution 2 - PowershellMichael BrayView Answer on Stackoverflow
Solution 3 - PowershellEverydayNerdView Answer on Stackoverflow
Solution 4 - PowershellGreg BrayView Answer on Stackoverflow
Solution 5 - PowershellgabriwinterView Answer on Stackoverflow
Solution 6 - PowershellAmr BahaaView Answer on Stackoverflow
Solution 7 - PowershellRobView Answer on Stackoverflow
Solution 8 - PowershelliRonView Answer on Stackoverflow
Solution 9 - PowershellfpschultzeView Answer on Stackoverflow
Solution 10 - PowershellMichael MeliView Answer on Stackoverflow
Solution 11 - PowershellVopelView Answer on Stackoverflow