Why are my PowerShell exit codes always "0"?

Solution 1:

This is a known issue with PowerShell. Executing a script with -file returns an exit code of 0 when it shouldn't.

(Update: The links below no longer work. Please look for, or report, this problem on PowerShell: Hot (1454 ideas) – Windows Server)

  • https://connect.microsoft.com/PowerShell/feedback/details/777375/powershell-exe-does-not-set-an-exit-code-when-file-is-used

  • https://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option

Since using -command wasn't working for you, you could try adding a trap at the top of the script:

trap
{
    write-output $_
    ##teamcity[buildStatus status='FAILURE' ]
    exit 1
}

The above should result in a proper exit code when an exception is thrown.

Solution 2:

I was having this exact issue while running with the -file, but for some reason the trap syntax or the 'exit' syntax provided by Kevin wasn't working in my scenario.

I am not sure why, but just in case somebody else hits the same problem, I used the below syntax and it worked for me:

try{
    #DO SOMETHING HERE
}
catch
{
    Write-Error $_
    ##teamcity[buildStatus status='FAILURE']
    [System.Environment]::Exit(1)
}

Solution 3:

Until this (presumably) gets closed as dup of my self-answer of an older question, I'll summarise the cleanest solution here:

  • Most of the other answers involve emitting something to the stderr from the PowerShell bit. This can be accomplished directly with TeamCity via the Format stderr output as option (set it to Error instead of the default, which is Warning)

  • However, critically, it's also necessary to switch on the "Fail build if: ... An error message is logged by (sic) build runner" under "Failure Conditions" (if any of the other answers work for you, you'll likely have this switched on already but IME it's very easy to forget!)

Solution 4:

Using -ErrorAction stop on a command returns an Exit code 1 by default and is showing it also in TeamCity without adding a Failure Condition. We will now implement this behaviour by default for every PowerShell command using $ErrorActionPreference = "Stop";.