1

I have a simple PS script:

    [CmdletBinding()]
    param(
      [Parameter()]
      [String] $CodeCoverageXmlReportPath,
      
      [Parameter()]
      [Int32] $MinimumLineCoverage = 100
    )
    
    Write-Host $"MinimumLineCoverage = $MinimumLineCoverage"
    Write-Host $"Reading CodeCoverage XML report: {$CodeCoverageXmlReportPath}"
    
    ### logic to calculate code coverage from report ###
    
    if ($lineCoverageNum -lt $MinimumLineCoverage)
    {
       Write-Host $"Code coverage of this build ($lineCoverageNum) is below the expected value ($MinimumLineCoverage). Please add tests to validate new code."
       exit 1
    }
    else
    {
       Write-Host $"Code coverage check (($lineCoverageNum)) for this build is at par with the ($MinimumLineCoverage). Great job!."
       exit 0
    }

These are the two ways I have tried to execute it from a .cmd file:

%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -ExecutionPolicy Unrestricted -File ValidateCodeCoverage.ps1 -CodeCoverageXmlReportPath "%TestResultsDir%\Cobertura.xml" -MinimumLineCoverage 57
    
ECHO ErrorLevel=%errorlevel%

and

%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -
    ExecutionPolicy Unrestricted -Command "& {.\ValidateCodeCoverage.ps1 -CodeCoverageXmlReportPath "%TestResultsDir%\Cobertura.xml" -MinimumLineCoverage 57; exit $LASTEXITCODE}"
    
ECHO ErrorLevel=%errorlevel%

In both these cases, checking the value of %errorlevel% right after the .ps1 execution remains 0 no matter what. I tried tested it with always exiting with return code 1, using trap, throwing an exception, etc. The %errorlevel% in cmd file is always set to 0.

What could I be missing? :(

0

2 Answers 2

2

Your PowerShell commands correctly set the exit code, so the problem must be in the way your batch file checks it.

The only scenario in which your code doesn't work is if it is inside a (...) block, where variable references such as %errorlevel% are expanded before the commands in the block execute; e.g.:

@echo off

REM # Does NOT work as expected, because %ErrorLevel% is expanded 
REM # BEFORE the powershell command excutes.
for /l %%i in (1,1,1) do (
  powershell.exe -ExecutionPolicy Bypass -Command "exit 5"
  echo ErrorLevel=%ErrorLevel%
)

Output is ErrorLevel=0, namely the value of %errorlevel% before the PowerShell command, which sets the exit code (error level) to 5, is executed.

To solve this problem:

  • You must use setlocal enableDelayedExpansion at the start of your batch file...

    • Note: The setlocal part implies that whatever custom variables you set in your batch file will be local to your batch file, which is generally preferable anyway; see setlocal /?
  • ... and then use !ErrorLevel! rather than %ErrorLevel%, because only the former guarantees dynamic expansion of the error level (exit code):

@echo off
setlocal enableDelayedExpansion

REM # OK - thanks to enableDelayedExpansion and !...!,
REM # powershell.exe's exit code is dynamically evaluated.
for /l %%i in (1,1,1) do (
  powershell.exe -ExecutionPolicy Bypass -Command "exit 5"
  echo ErrorLevel=!ErrorLevel!
)

Output is ErrorLevel=5, which now correctly reflects the PowerShell command's exit code.

Sign up to request clarification or add additional context in comments.

2 Comments

Hi @mklement0 nice to see you again, thanks for helping me on my other question. However, in this instance your answer is off. In my test.ps1 I have: exit 10 when I execute it: powershell -executionpolicy bypass .\test.ps1 echo %errorlevel% guess what, I get 1. not 10 or whatever number I exit with. I only get 0 or 1.
You're welcome, @gk_2000. To see a .ps1 file's exit code, you must invoke it with -File: powershell -executionpolicy bypass -File .\test.ps1. See this answer for more information.
0

SHould have used !var! instead of %var%

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.