3

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?

1
  • IMO it is OK since the batch errorlevel reflects that powershell ran the Start-Process without errors. Commented Jun 17, 2017 at 5:45

1 Answer 1

9

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.

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

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.