I find myself chaining these a lot, eg:
do-cmd-one
if($?)
{
do-cmd-two
}
...
then at the end:
if(!$?)
{
exit 1
}
I assume there's a pattern for this in powershell but I don't know it.
PowerShell (Core) 7.0 introduced Bash-like &&
and ||
operators called pipeline-chain operators.
They will not be back-ported to Windows PowerShell, however, as the latter will generally see no new features.
In short, instead of:
do-cmd-one; if ($?) { do-cmd-two }
Note: Up to PowerShell 7.1, the more robust formulation is actuallydo-cmd-one; if ($LASTEXITCODE -eq 0) { do-cmd-two }
, for the reasons explained in this answer.
you can now write:
do-cmd-one && do-cmd-two
&&
(AND) and ||
(OR) implicitly operate on each command's implied success status, as reflected in automatic Boolean variable $?
.
This will likely be more useful with external programs, whose exit codes unambiguously imply whether $?
is $true
(exit code 0
) or $false
(any nonzero exit code).
By contrast, for PowerShell commands (cmdlets) $?
just reflects whether the command failed as a whole (a statement-terminating error occurred) or whether at least one non-terminating error was reported; the latter doesn't necessarily indicate overall failure.
However, there are plans to allow PowerShell commands to set $?
directly, as a deliberate overall-success indicator.
Also note that the following do not work with &&
and ||
:
PowerShell's Test-*
cmdlets, because they signal the test result by outputting a Boolean rather than by setting $?
; e.g., Test-Path $somePath || Write-Warning "File missing"
wouldn't work.
Boolean expressions, for the same reason; e.g., $files.Count -gt 0 || write-warning 'No files found'
wouldn't work.
See this answer for background information, and the discussion in GitHub issue #10917.
There's a syntax caveat: As of this writing, the following will not work:
do-cmd-one || exit 1 # !! Currently does NOT work
Instead, you're forced to wrap exit
/ return
/ throw
statements in $(...)
, the so-called subexpression operator:
do-cmd-one || $(exit 1) # Note the need for $(...)
GitHub issue #10967 discusses the reasons for this awkward requirement, which are rooted in the fundamentals of PowerShell's grammar.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With