Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How capture errorlevel of powershell script in a batch file when execute as admin

I need to capture output of powershell script in a batch file when execute as admin.

Example:

ps1 file:

Write-Host "PS1 executed"
exit 1

If I execute powershell script without admin access

NotAdminFile.bat:

@ECHO OFF
setlocal enableextensions
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1'"
echo %ERRORLEVEL%
endlocal

Then, the output is

PS1 executed
1

This is ok. But, when I execute powershell script with admin access

AdminFile.bat:

@ECHO OFF
setlocal enableextensions
PowerShell.exe -NoProfile -Command "& {Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File "%~dpn0.ps1" ' -Verb RunAs}"
echo %ERRORLEVEL%
endlocal

Then, the output is:

0

I don't want that. Can you help me please?

like image 759
Mauricio Pardo Avatar asked Apr 05 '26 16:04

Mauricio Pardo


1 Answers

exit_1_only.ps1

Write-Host "executed: $($MyInvocation.Line)"
# pause
Exit 123+[int]([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::
    GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")

q44600354.bat

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion

(call )
echo errorlevel clear=%errorlevel%

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command ^
  "& 'D:\PShell\tests\exit_1_only.ps1'; exit $LASTEXITCODE"
echo errorlevel non-admin=%errorlevel%

echo(
(call )
echo errorlevel clear=%errorlevel%

PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command ^
  "& {exit ( Start-Process -Wait -PassThru -FilePath PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -Command ""D:\PShell\tests\exit_1_only.ps1; exit $LASTEXITCODE"" ' -Verb RunAs).ExitCode}"
echo errorlevel admin=%errorlevel%

Output

==> D:\bat\SO\q44600354.bat
errorlevel clear=0
executed: & 'D:\PShell\tests\exit_1_only.ps1'; exit $LASTEXITCODE
errorlevel non-admin=123

errorlevel clear=0
errorlevel admin=124

==>

Explanation

Exit Codes

In PowerShell $? contains True if last operation succeeded and False otherwise.

The exit code of the last Win32 executable execution is stored in the automatic variable $LASTEXITCODE

To read exit codes (other than 0 or 1) launch the PowerShell script and return the $LASTEXITCODE in a single line like this:

powershell.exe -noprofile C:\scripts\script.ps1; exit $LASTEXITCODE

Start-Process

-PassThru

Returns a System.Diagnostics.Process process object for each process that the cmdlet started. By default, this cmdlet does not generate any output.

-Wait

Indicates that this cmdlet waits for the specified process to complete before accepting more input. This parameter suppresses the command prompt or retains the window until the process finishes.

(call ): Dave Benham in reply to setting ERRORLEVEL to 0 question:

If you want to force the errorlevel to 0, then you can use this totally non-intuitive, but very effective syntax: (call ). The space after call is critical. If you want to set the errorlevel to 1, you can use (call). It is critical that there not be any space after call.

like image 115
JosefZ Avatar answered Apr 08 '26 06:04

JosefZ