PowerShell Exit Codes

Recently I came across an interesting quirk in PowerShell: exit codes from powershell.exe are inconsistent.

As you may know there are two ways of launching PowerShell script: you can use -File or -Command parameter.

powershell -File test.ps1

or

powershell -Command .\test.ps1

-Command could be ommitted:

powershell .\test.ps1

Now let’s say you want to execute PowerShell script from a scheduled task or from continuous integration server. Naturally, you would be interested if the script fails or not.

And here’s the bug: if you launch your script using -File parameter powershell.exe exits with zero code even if there was an exception.

You can confirm this by creating a script that always throws an error:

throw 'oops'

Now if you launch it using -File parameter exit code is 0:

powershell.exe -File testerror.ps1
echo Error level is %ERRORLEVEL%

oops
At C:\testerror.ps1:1 char:6
+ throw <<<<  'oops'
    + CategoryInfo          : OperationStopped: (oops:String) [], RuntimeException
    + FullyQualifiedErrorId : oops

Error level is 0

But if you use -Command parameter exit code is set as expected:

powershell.exe -Command .\testerror.ps1
echo Error level is %ERRORLEVEL%

Chris Oldwood also came across this bug:

depending on whether I use the “-File” or “-Command” switch to execute the .ps1 script I get different behaviour. Is this a PowerShell bug or is there something fundamental about the execution model the differs between -File and -Command that I’ve yet to understand?

Bonus

How to execute PowerShell script from NAnt script:

<exec program="powershell.exe" append="true">
  <arg value="-noprofile" />
  <arg value="&amp;'C:\your-script.ps1'" />
  <arg value="param1" />
  <arg value="'param 2 with spaces'" />
</exec>

References

One thought on “PowerShell Exit Codes

  1. Pavel, why do we use ‘&’ in Ant scripts instead of -Command?

    Tried from a cmd.exe shell, with Powershell 3
    I find ‘&’ means that Powershell does not terminate:

    C:\Users\ishepher>powershell -noprofile &’C:\Users\ishepher\test.ps1′
    Windows PowerShell
    Copyright (C) 2012 Microsoft Corporation. All rights reserved.

    PS C:\Users\ishepher>

    But with ‘-Command’ it works as expected:

    C:\Users\ishepher>powershell -noprofile -command .\test.ps1
    ScriptHalted
    At C:\Users\ishepher\test.ps1:1 char:1
    + throw
    + ~~~~~
    + CategoryInfo : OperationStopped: (:) [], RuntimeException
    + FullyQualifiedErrorId : ScriptHalted

    C:\Users\ishepher>echo %ERRORLEVEL%
    1

Leave a Reply

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