Azure DevOps reports PowerShell task as passed even with non-0 exit code

Viewed 4754

In Azure DevOps I have a task to run a PowerShell script. In certain scenarios, the script should exit with a non-0 code, causing the task to be reported as failed. However, Azure DevOps reports the task as passed regardless.

This is a problem because I have a subsequent job that should run if this job fails, but that is not happening because of the false positive.

enter image description here

The relevant part of the script shows that, in the case of the screenshot, an exit code of 1 was detected, which should result in the script exiting in error.

if ($exitCode -ne 0)
{
    Write-Output ("[Error] Failing task since return code was {0} while expected 0." -f $exitCode)
}
exit $exitCode

The task is run as part of a deployment job, and I do have the option failOnStandardError set to true.

- task: AzurePowerShell@5
  displayName: Check Function App Version
  inputs:
    azureSubscription: ${{ parameters.serviceConnectionName }}
    scriptType: FilePath
    scriptPath: ${{ parameters.scriptsArtefactPath }}/Test-FunctionAppVersion.ps1
    scriptArguments: -Uri ${{ parameters.healthCheckUri }} -AuthHeaderName Authorization -AuthHeaderValue "$(healthCheckAuthHeaderValue)"
    failOnStandardError: true
    azurePowerShellVersion: LatestVersion
    pwsh: true

How can I make Azure DevOps honour my exit codes?

2 Answers

It seems that the Azure PowerShell task has an issue capturing the exit code from a script file, it works fine with the inline scripts. You can report this problem to Microsoft development team. Hope they will provide a fix soon.

However, you can use either of below workarounds to fix it.

1, Use [Environment]::Exit($exitCode) instead of exit. See below:

if ($exitCode -ne 0)
{
    Write-Output ("[Error] Failing task since return code was {0} while expected 0." -f $exitCode)
}
[Environment]::Exit($exitCode)

2, Use logging command ##vso[task.complete result=Failed;]Failed to manually fail the task if the exitCode is non-0. See below:

if ($exitCode -ne 0)
{
    Write-Output ("[Error] Failing task since return code was {0} while expected 0." -f $exitCode)
    Write-Host "##vso[task.complete result=Failed;]Failed"
}
exit $exitCode

Since the solution did not directly worked for me, I improved this a little bit and use Write-Error instead of Write-Host.

if ($exitCode -ne 0) {
  Write-Error ("[Error] Failing task since return code was {0} while expected 0." -f $exitCode)
}

Combined with the failOnStderr you will get what you need.

- task: PowerShell@2
  displayName: check stuff
  inputs:
    failOnStderr: true
    targetType: 'inline'
    script: |
      do_some_thing
      if ($exitCode -ne 0) {
        Write-Error ("[Error] Failing task since return code was {0} while expected 0." -f $exitCode)
      }
Related