70

What is the meaning of $? in Powershell?


Edit: TechNet answers in tautology, without explaining what 'succeed' or 'fail' mean.

$?
Contains the execution status of the last operation. It contains TRUE if the last operation succeeded and FALSE if it failed.

I presumed $? would simply test whether $LastExitCode is 0, but I found a counter example where $? is False but $LastExitCode is True.

Community
  • 1
  • 1
Colonel Panic
  • 126,394
  • 80
  • 383
  • 450
  • 2
    In Powershell, `$?` is an example of an "automatic variable." It helped me to know the nomenclature. – Baodad Jul 05 '18 at 23:55

4 Answers4

64

It returns true if the last command was successful, else false.

However, there are a number of caveats and non-obvious behaviour (e.g. what exactly is meant by "success"). I strongly recommend reading this article for a fuller treatment.

For example, consider calling Get-ChildItem.

PS> Get-ChildItem 

PS> $? 
    True

$? will return True as the call to Get-ChildItem succeeded.

However, if you call Get-ChildItem on a directory which does not exist it will return an error.

PS> Get-ChildItem \Some\Directory\Which\Does\Not\Exist
    Get-ChildItem : Cannot find path 'C:\Some\Directory\Which\Does\Not\Exist' because it does not exist.

PS> $?
    False

$? will return False here, as the previous command was not successful.

RB.
  • 35,110
  • 12
  • 84
  • 126
  • @MattHickford A command is something you execute using Powershell. It can be a cmdlet or an executable for example. See the example I've added. – RB. May 17 '12 at 12:07
  • 1
    What does 'successful' mean? Do you think it means 'if and only if $LastExitCode is 0'? – Colonel Panic May 19 '12 at 14:30
  • 1
    I've found a counter-example where $? is False but $LastExitCode is 0. See http://stackoverflow.com/questions/10666101/powershell-lastexitcode-0-but-false-redirecting-stderr-to-stdout-gives-nat – Colonel Panic May 19 '12 at 14:45
  • The article link in the answer is dead. – Robb Vandaveer Mar 06 '20 at 02:12
  • 1
    @RobbVandaveer Thanks - I've linked to archive.org now. – RB. Mar 06 '20 at 10:02
7

$? will contain $false if the last command resulted in an error. It will contain $true if it did not. In the PowerShell v1 days, this was a common way to do error handling. For example, in a script, if you wanted to check for the existence of a file and then print a custom message if it did not, you could do:

Get-Item -Path john -ErrorAction silentlycontinue;
if( -not $?)
{
    'could not find file.';
     exit
 }`
Marko
  • 19,975
  • 13
  • 46
  • 63
John Cravener
  • 71
  • 1
  • 1
  • 5
    What do people do now instead? – mikemaccana Oct 07 '16 at 13:34
  • 1
    @mikemaccana, in the same boat here.... I would think try/catch statements. – Johnrad Jun 01 '17 at 15:39
  • 2
    try/catch is available in PS, but exceptions are only 'caught' when there is a terminating error. Often, a cmdlet won't terminate the execution but will continue on. In these cases, $? is you're alternative. – Jeff Reddy Aug 29 '18 at 19:51
2

You can also access last commands exit code using $LastExitCode parameter.

# run some command
# ...
if ((! $?) -and $ErrorAction -eq "Stop") { exit $LastExitCode }
Kerem Demirer
  • 1,106
  • 2
  • 13
  • 24
1

I have encountered in Windows Server 2019, $? can be set false when Standard Error has been generated. In my example docker-compose logs warnings via Standard Error, so although exiting with 0, $? indicates failure.

Jules Clements
  • 368
  • 3
  • 8
  • 1
    I'm pretty sure you just saved me from an exploding artery in my head. I'm running a powershell script in a Jenkins build that executes Selenium tests. A Chrome browser and web driver upgrade just started logging an error, but the test passed. The `$?` variable was `$False` but `$LastExitCode` was zero. This build has been failing for a while now, and this answer finally pinpointed the failure. Basically don't trust `$?`. Use `$LastExitCode` instead. – Greg Burghardt Feb 07 '20 at 16:26