0

Assume I have two files, script.ps1 and filename.cmd, and I run .\script.ps1 from a Powershell prompt:

script.ps1

Write-Host "About to run filename.cmd"
$proc = Start-Process -FilePath filename.cmd -NoNewWindow -Wait
Write-Host "proc: [$proc]"
Write-Host "LASTEXITCODE: [$LASTEXITCODE]

filename.cmd

@echo off
ECHO File returns ErrorLevel=1
exit /b 1

Output:

About to run filename.cmd
proc: []
LASTEXITCODE: []

Both proc and LASTEXITCODE are $null. My understanding was that somehow I could access the ErrorCode?

How do I read the failed error level (in this case 1) in my Powershell script?

1 Answer 1

0

To synchronously execute console applications, including batch files, call them directly, do not use Start-Process - see this answer.

Therefore:

Write-Host "About to run filename.cmd"
# For security reasons, PowerShell requires that you explicitly
# signal the intent to run an executable located *in the current directory*,
# hence the need for `./` (or `.\`)
# Only direct invocation of external programs (batch files) sets
# the automatic $LASTEXITCODE variable.
./filename.cmd
Write-Host "LASTEXITCODE: [$LASTEXITCODE]

As for what you tried:

Start-Process outputs nothing by default - except if you pass the -PassThru switch, in which case a System.Diagnostics.Process instance representing the newly started process is returned.

Assuming you've also specified -Wait, as in your case, you can then access the returned object's .ExitCode property to determine the exit code immediately afterwards.

Note that automatic variable $LASTEXITCODE is only set after direct invocation of external programs, as shown above.

Therefore, if you were to use Start-Process - which is not necessary in this case, as explained above - you'd have to use the following:

Write-Host "About to run filename.cmd"
$proc = Start-Process -PassThru -FilePath filename.cmd -NoNewWindow -Wait
Write-Host "proc: [$proc]"
Write-Host "exit coe: [$($proc.ExitCode)]
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks this is very helpful. I ended up using Invoke-Expression -Command "filename.cmd" | Out-Host so that I could mock the call in my Pester tests, which appears to have worked like a charm using $LASTEXITCODE
Glad to hear it, @satoukum. As a matter of habit, I suggest avoiding Invoke-Expression, so perhaps Invoke-Command { ./filename.cmd } is the better alternative.

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.