24

MyScript.ps1:

exit 1

MyThrow.ps1:

throw "test"

Execution in PowerShell:

& ".\MyScript.ps1"
Write-Host $LastExitCode # Outputs 1

Clear-Variable LastExitCode

& ".\MyThrow.ps1"
Write-Host $LastExitCode # Outputs nothing

How do I set a proper exit code when throwing an exception?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
D.R.
  • 20,268
  • 21
  • 102
  • 205
  • Why not either `try/catch` the command, or clear `$lastexitcode` before the command and test if it's `$null` afterwards? – arco444 Feb 25 '15 at 16:35
  • In the end the script is not executed from the PowerShell but from the task scheduler. Currently if the script throws an exception, the exit code in the task scheduler is 0. – D.R. Feb 25 '15 at 16:36
  • Do you have access to the script? Best solution would be to properly trap the exceptions there and exit with a from the catch, or set a code to exit with at the end – arco444 Feb 25 '15 at 16:38
  • 1
    wtf powershell, why you no set exit code on exception :) – KCD Oct 27 '16 at 20:38
  • note that Powershell's behavior is inconsistent with uncaught `throw` statements. `$LastExitCode` is left as 0, indicating success, but `$?` is set to `$False`, indicating failure. – Tydaeus Nov 15 '18 at 23:52

4 Answers4

21

Becareful:

With Powershell 4 and less:

When an exception is thrown, exit code remains at 0 (unfortunately)

With Powershell 5 and up:

When an exception is thrown, exit code defaults to 1

No Name Pro
  • 160
  • 1
  • 7
Kino101
  • 765
  • 8
  • 18
  • 2
    Upvoted, this is a much better answer nowadays. Maybe I should even change the accepted answer...don't know about the meta rules though. – D.R. Mar 05 '21 at 17:05
20

You don't. When you throw an exception you expect someone to handle it. That someone would be the one to terminate execution and set an exit code. For instance:

try {
  & ".\MyThrow.ps1"
} catch {
  exit 1
}

If there is nothing to catch your exception you shouldn't be throwing it in the first place, but exit right away (with a proper exit code).

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • 1
    What if you want to do a try catch finally? I would assume if you end up inside the catch then you would never hit the finally because of the exit. – BigMiner Nov 30 '16 at 18:44
  • 3
    As per @AnsgarWiechers' answer, a `finally` will always run even if the catch before it does an `exit 1`. – SIRHAMY Oct 19 '18 at 17:44
3

Actually you can set the code also with throw, just put it before throw.

Contents of the script: Throw.ps1

exit 222
throw "test"

Output:

PS C:\> .\Throw.ps1
PS C:\> $LASTEXITCODE
222

If you run it like this:

powershell .\Throw.ps1

The output will be as follows:

PS C:\> powershell .\Throw.ps1
PS C:\> $LASTEXITCODE
1

But here is the thing, powershell exit codes should be either 0 or 1, anything else, finally will give you result of 1.

Another interesting thing to mention, if to try $? after you run the script, if true or false, the result depends of what you want to put in there. exit 0 --> true, exit 1 --> false

Here it is an example:

Content of the script: Throw_1.ps1

exit 1
throw "test"

Output:

PS C:\> .\Throw_1.ps1
PS C:\> $?
False

Content of the script: Throw_0.ps1

exit 0
throw "test"

Output:

PS C:\> .\Throw_0.ps1
PS C:\> $?
True

As you can see it is just what you need or want to achieve.

Eddy Levi
  • 79
  • 6
  • 5
    This doesn't set the exit code and throw. It sets the exit code and exits. Everything after the `exit` is unreachable code. – EKW Dec 17 '20 at 16:27
0

Running the mythrow.ps1 inside powershell will set $? to false, and will add to the $error object array. Running it with another powershell process will set $lastexitcode to 1.

PS C:\> powershell mythrow.ps1
PS C:\> $lastexitcode
1
js2010
  • 23,033
  • 6
  • 64
  • 66