PowerShell: Is there an automatic variable for the last execution result?
No there is not automatic variable like that.
You have to do:
$output = Get-Something
$output
$anObj = $output
to get the behaviour
As stated, there's no built-in support for this, but here's a simple, but suboptimal PSv3+ custom solution:
Note:
For a proper, but nontrivial solution, see BartekB's helpful answer.
GitHub feature request #7853 asks for building this functionality into a future PowerShell Core version (the current version as of this writing is PowerShell (Core) 7.2).
Add the following to your $PROFILE
file:
# Store previous command's output in $__
$PSDefaultParameterValues['Out-Default:OutVariable'] = '__'
What to name the variable - such as $__
(2 underscores) in this example - is up to you, but beware of name collisions, notably with $_
, the automatic variable that represents the input object at hand in a number of contexts.
This will capture the terminal-bound output of the most recently executed PowerShell command [that produced terminal output] in variable $__
in your interactive sessions,
by way of PowerShell's ability to globally preset parameter defaults - see Get-Help about_Parameters_Default_Values
.
-OutVariable
is a common parameter designed to collect a cmdlet's / advanced function's output objects in a variable, and the above definition applies this parameter implicitly to all Out-Default
calls, which in turn is called behind the scenes whenever PowerShell outputs something to the terminal - however, note the exceptions mentioned below.
Caveats:
If needed, use
$saved = $__.Clone()
to save the captured output for later use, given that$__
is reassigned to on every command (of course, if you know ahead of time that you want to keep a command's output, use an assignment to begin with:$saved = <command>
).- Note that just
$saved = $__
does not work, because that makes$saved
point to the same[ArrayList]
instance as$__
, which gets repopulated on the next command.
- Note that just
Output is not captured in the following cases:
Output from external programs, such as
git
, because by design PowerShell passes the output streams from external programs directly to the terminal (unless they're redirected or captured), and therefore doesn't callOut-Default
. The simplest workaround is to pipe toWrite-Output
(something like*>&1
to explicitly route through PowerShell streams doesn't work); e.g.:whoami.exe | Write-Output # $__ is now populated
Output from commands that explicitly call a formatting cmdlet -
Format-Custom
,Format-Hex
,Format-List
,Format-Table
, orFormat-Wide
.- It's tempting to attempt to fix that with
$PSDefaultParameterValues['Format-*:OutVariable'] = '__'
, but, unfortunately, this would collect formatting objects (instructions) rather than the original data in$__
, which is undesired. An unsatisfying workaround is to captureFormat-*
output in a different variable, which not only requires you to think about which variable you need to target, but you'll still only see formatting objects rather than data, and, sinceFormat-*
cmdlets are involved behind the scenes even if you don't use them explicitly, the output of commands withoutFormat-*
calls is then captured twice - once as data, in$__
, and again as formatting objects, in the other variable.
- It's tempting to attempt to fix that with
Due to a design quirk,
$__
always contains an array list (of type[System.Collections.ArrayList]
), even if the previous command output only a single object. When in doubt, use$($__)
(or$__[0]
) to get a single output object as such.Beware of commands producing very large output sets, because
$__
will collect them in memory.$__
will only capture objects output to the terminal - just like_
does in Python; a command that produces no output or$null
/ an array of$null
s leaves any previous$__
value intact.