74

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
  • 132,665
  • 89
  • 401
  • 465
  • 2
    In Powershell, `$?` is an example of an "automatic variable." It helped me to know the nomenclature. – Baodad Jul 05 '18 at 23:55

5 Answers5

68

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.
  • 36,301
  • 12
  • 91
  • 131
  • @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
  • 20,385
  • 13
  • 48
  • 64
John Cravener
  • 71
  • 1
  • 1
  • 7
    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
  • 3
    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
3

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

# run some command
# ...
if ((! $?) -and $ErrorAction -eq "Stop") { exit $LastExitCode }
Kerem Demirer
  • 1,186
  • 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
  • 418
  • 5
  • 8
  • 2
    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
  • In my case it's the opposite. ExitCode is 0 but the command failed, so I have to check `$?`. Seems like a common issue (when using PS with AWS: https://github.com/aws/amazon-ssm-agent/issues/69) – wilmol Jan 31 '23 at 00:51
0

IMPORTANT!!! Pleas be aware of the answer from Jules Clements. $? can return false even $LastExitCode returns 0.

Even requesting $? causes that its content will change.

Example: Some command causes that $? is false. write $? => will return "false" for the first time write $? => will return "true" for the second time

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
  • 1
    Some further refinement to my approach in later versions of windows (> 2016), when calling programs rather than commandlets, I execute them within a CMD subshell, e.g. `cmd /c docker-compose up -d target 2>&1` then I test $LASTEXITCODE – Jules Clements Feb 01 '23 at 03:35