Friday, May 22, 2015

Powershell and exit status for cmdlets and commands

In Unix and Linux systems you can use the $? variable to find out the exit status of a command. To make a long story short, when you type commands in a UNIX shell, $? always expands to the status of the most recently executed foreground command or pipeline.

Now, since the original Powershell is based on the POSIX standard (back in the eighties, guys!), which tries to standardize commands from the UNIX Korn Shell, it's somewhat natural that Powershell borrowed this $? variable from its predecessor.

Let me give a few basic tips on the use of it.

The $? is a boolean variable documented in about_Automatic_Variables, and can by design hold only two values: $True or $False.

Get-ChildItem C:\Windows\System32\drivers\etc

    Directory: C:\Windows\System32\drivers\etc

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        10/06/2009     23:00        824 hosts
-a---        10/06/2009     23:00       3683 lmhosts.sam
-a---        10/06/2009     23:00        407 networks
-a---        10/06/2009     23:00       1358 protocol
-a---        10/06/2009     23:00      17463 services

$?
True
Test-Connection nohost -Count 1
Test-Connection : Testing connection to computer 'nohost' failed: The requested name is valid, but no data of the
requested type was found
At line:1 char:1
+ Test-Connection nohost -Count 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (nohost:String) [Test-Connection], PingException
    + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand

$?
False
Here's how to check the variable type:

$?.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Boolean                                  System.ValueType
So, while in UNIX $? returned 0 or 1, in Powershell it returns $True or $False.

There is another important variable named $LastExitCode which returns the exit command of the last Windows command run:

cmd /C exit 0

$LASTEXITCODE
0
Remember though, $LastExitCode doesn't work with Powershell commands. For instance if we check the value of the variable after a failed Powershell cmdlet, its value stays 0, which means succesful:

Test-Connection nohost -Count 1

Test-Connection : Testing connection to computer 'nohost' failed: The requested name is valid, but no data of the
requested type was found
At line:1 char:1
+ Test-Connection nohost -Count 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceUnavailable: (nohost:String) [Test-Connection], PingException
    + FullyQualifiedErrorId : TestConnectionException,Microsoft.PowerShell.Commands.TestConnectionCommand

$LASTEXITCODE
0
On the other side, when we check it after a failing legacy or external command, it becomes effective:
ping nohost

Ping request could not find host nohost. Please check the name and try again.

$LASTEXITCODE
1
Also, $LastExitCode isn't populated until you execute a Powershell task that returns an exit code. If you open a fresh Powershell console and search for $LastExitCode... you won't find it:

$LASTEXITCODE -eq $null

True
Nor you will find if you run a Powershell cmdlet:

gci c:\nonexistingfolder

gci : Cannot find path 'C:\nonexistingfolde
At line:1 char:1
+ gci c:\nonexistingfolder
+ ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFoun
    + FullyQualifiedErrorId : PathNotFound,

$LASTEXITCODE -eq $null
True
The variable gets populated only when you run an external executable that returns an exit code, like the ping command:

ping nohost

Ping request could not find host nohost. Please check the name and try again.

$LASTEXITCODE -eq $null
False
I hope this brief description of the the two $? and $LASTEXITCODE variable was clear enough. If you have any specific question do not hesitate to leave it in a comment.

If you liked ths quick post, be kind, share. Alot more to come.

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...