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="&'C:\your-script.ps1'" />
<arg value="param1" />
<arg value="'param 2 with spaces'" />
</exec>
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