Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Powershell and $LastExitCode

Status
Not open for further replies.

kmcferrin

MIS
Jul 14, 2003
2,938
US
Weird thing going on here, maybe someone has seen it. I have a Powershell script that I have written that calls several executables. After the executable completes I want to retrieve the exit code for the executable so that I can note if it was successful for not. I'm told that $LastExitCode contains the exit code from the last Win32 app to execute. So I try it:

ping localhost
$lastexitcode

And the value returned is 0. Great!

Then I try:

GPUPDATE (while disconnected from the network, which should generate an error)
$lastexitcode

And the value returned is -1. Great!

So then I try to execute the same commands within my script. I can see the script waiting for the execution to complete before continuing, but this time when I ask for $lastexitcode I don't get a value (or it's null or similar). Any idea why?

Code:
Start-Process -FilePath C:\Windows\System32\ping.exe -ArgumentList 127.0.0.1 -NoNewWindow -Wait
"Did the last execution succeed?  " + $?
$LastExitCode + "Is the last exit code" #why doesn't this work?
Start-Process gpupdate.exe -NoNewWindow -Wait
"Did the last execution succeed?  " + $?
$LastExitCode + "Is the last exit code" #why doesn't this work?

________________________________________
CompTIA A+, Network+, Server+, Security+
MCTS:Windows 7
MCSE:Security 2003
MCITP:Server Administrator
MCITP:Enterprise Administrator
MCITP:Virtualization Administrator 2008 R2
Certified Quest vWorkspace Administrator
 
I have also tried removing the NoNewWindow and Wait parameters to see if one of them was tripping it up, but to no avail. Is it because I'm calling it via Start-Process instead of some other method?

________________________________________
CompTIA A+, Network+, Server+, Security+
MCTS:Windows 7
MCSE:Security 2003
MCITP:Server Administrator
MCITP:Enterprise Administrator
MCITP:Virtualization Administrator 2008 R2
Certified Quest vWorkspace Administrator
 
Hmm, built-in V2 help (help about_Automatic_Variables) says "Contains the exit code of the last Windows-based program that was run". A V1 book I have gives the description as "A number that represents the exit code/error level of the last script or application that exited". The V1 book must be closer to right, as you can actually have your scripts exit with a code number (exit 50, for instance) and it will set $LastExitCode to that number.

Doing some quick experiments, it appears that not all Windows executables set $LastExitCode. It also appears that built-in cmdlets do not set the $LastExitCode at all but just leave it alone. In the case of your script above, since you're using Start-Process, even to run Windows executables, the value of $LastExitCode will be whatever it was before you ran the script.

Try the following as a script:
Code:
ping -n 1 [valid server name/IP address]
"Ping 1 last code $lastexitcode"
ping -n 1 [invalid server name/IP address]
"Ping 2 last code $lastexitcode"
ping -n 1 [valid server name/IP address]
"Ping 3 last code $lastexitcode"
start-process -file c:\windows\system32\ping.exe -argument [invalid server name/IP address]
"Ping 4 last code $lastexitcode"
ping -n 1 [invalid server name/IP address]
"Ping 5 last code $lastexitcode"

exit 50
I got the following results:
Ping 1 last code 0: Since I ran Ping directly and it was successful
Ping 2 last code 1: Since I ran Ping directly and it was not successful
Ping 3 last code 0: As expected since it was a repeat, but $LastExitCode is now 0
Ping 4 last code 0: We might have expected 1 since the Ping was to an invalid host, but since it was done through Start-Process the value was apparently left alone. You can prove this by putting an invalid direct ping before the Start-Process call
Ping 5 last code 1: Since I ran Ping directly and it was not successful
If you then examine $LastExitCode after the script exits, it should be 50
 
I did finally find a code snippet online that solved the issue for me. It's included here for reference:

Code:
# This function calls external executables, waits for them to complete and returns the exit code
function Run-LocalProcess ($cmd, $Parameters) {
    $Process = New-Object System.Diagnostics.Process
    $Process.StartInfo = New-Object System.Diagnostics.ProcessStartInfo
    $ExitCode = $false      
    $Process.StartInfo.FileName = $cmd
    $Process.StartInfo.Arguments = $Parameters
    $Process.StartInfo.UseShellExecute = $shell
    $Process.StartInfo.WindowStyle = 1; #Window style is hidden.  Comment out this line to show output in separate console
    $null = $Process.Start()
    $Process.WaitForExit() #Waits for the process to complete.   
    $ExitCode = $Process.ExitCode
        If ($Process.ExitCode -ne 0) {
            #Log an error
            #Sets performance counter State to Warning
            }
        Else {
            #Log OK
            }
    $Process.Dispose()    
    return $ExitCode
}

It was even fairly easy to modify for use to remotely execute code via PSSession as well.

________________________________________
CompTIA A+, Network+, Server+, Security+
MCTS:Windows 7
MCSE:Security 2003
MCITP:Server Administrator
MCITP:Enterprise Administrator
MCITP:Virtualization Administrator 2008 R2
Certified Quest vWorkspace Administrator
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top