0
votes

When calling a powershell script from a batch file, and exiting with a value, errorlevel is 0 in batch file, not the exit value

I've tried using the code below to call a powershell script which exits with a number that should be an errorlevel in the batch file, but when I check %errorlevel% in the batch file, it is always zero. I'm calling it in the For loop as I need to also have it return some text.

This is the powershell script:

# TestReturnValAndCode.ps1
$DataIn = $args[0]
$ReturnVal="You passed in the text '" + $DataIn + "'"
$ReturnVal
exit 1234

This is the batch file:

:: testpscaller.bat
@echo off
set "BaseFolder=C:\temp\test"
set "TestPSScript=%BaseFolder%\TestReturnValAndCode.ps1"
set "TestValue=Test This Text"
for /f "delims=" %%a in ('powershell -executionpolicy bypass -file 
"%TestPSScript%" "TestValue"') do set "ReturnVal=%%a"
@echo ErrorLevel=[%ErrorLevel%]
@echo ReturnVal=[%ReturnVal%]

This is the result:

ErrorLevel=[0] ReturnVal=[You passed in the text 'TestValue']

THe ErrorLevel should be 1234.

What do I need to do to get both my text value and the error level (that is not too klunky/kludgy)

1
The exit code of PowerShell is being overwritten by the FOR command. You will need to capture it after PowerShell executes, and before the FOR command runs. Why not do everything in PowerShell rather than wrapping PowerShell in a batch script?TheMadTechnician
Right now we have a suite of batch files and many small ones are called by larger ones. The long term plan is to convert them all to powershell, but in the interim, we want to be able to convert smaller powershell scripts to be called by the larger batch scripts.cashonly

1 Answers

0
votes

The for command does not return the %errorlevel% of the (last) command executed inside it. You need to "convert" such an %errorlevel% into text inside the for body in order to get it as a second line outside the for:

:: testpscaller.bat
@echo off
set "TestPSScript=.\TestReturnValAndCode.ps1"
set "ReturnVal="
for /f "delims=" %%a in ('powershell -executionpolicy bypass -file "%TestPSScript%" "TestValue" ^& echo %ErrorLevel%') do (
   if not defined ReturnVal (
      set "ReturnVal=%%a"
   ) else (
      set "ReturnErrorLevel=%%a"
   )
)
@echo ErrorLevel=[%ReturnErrorLevel%]
@echo ReturnVal=[%ReturnVal%]

Output:

ErrorLevel=[1234]
ReturnVal=[You passed in the text 'TestValue']

EDIT:

This is strange. I did this method work before. However, it seems that the echo %ErrorLevel% command placed inside the FOR body reports the errorlevel value set by the last execution of powershell outside a FOR command... I don't understand this behavior... :(

A workaround is store the powershell output in a temp file:

:: testpscaller.bat
@echo off
set "TestPSScript=.\TestReturnValAndCode.ps1"
powershell -executionpolicy bypass -file "%TestPSScript%" "TestValue" > TempFile.txt
@echo ErrorLevel=[%ErrorLevel%]
set /P "ReturnVal=" < TempFile.txt
@echo ReturnVal=[%ReturnVal%]