How do you make powershell ignore failures on legacy commands?
All powershell modules support -ErrorAction, however that does not work with legacy commands like NET STOP
NET STOP WUAUSERV
echo $?
true
I want to attempt to stop the service, and if the service is already stopped, continue. An easy way to reproduce this is to try and stop the service twice.
Things I've tried
$ErrorActionPreference = "SilentlyContinue"
NET STOP WUAUSERV
NET STOP WUAUSERV
echo $LASTEXITCODE
Tried using AND and OR operrators
and
NET STOP WUAUSERV || $true
NET STOP WUAUSERV || $true
echo $LASTEXITCODE
or
NET STOP WUAUSERV && $true
NET STOP WUAUSERV && $true
echo $LASTEXITCODE
I've also tried redirecting errors
NET STOP WUAUSERV 2>nul
NET STOP WUAUSERV 2>nul
echo $LASTEXITCODE
As recommended in a similar question, I've also tried
cmd.exe /C "NET STOP WUAUSERV"
How can I make this legacy command idempotent?
To silence error / stderr output in PowerShell, use 2> $null, not 2> NUL.
$ErrorActionPreference should not have any effect on calling external utilities (console applications) such as net.exe, but - due to a bug as of Windows PowerShell v5.1 / PowerShell Core v6.0.0-beta.9 - if the value is 'Stop', 2> $null (indeed, any redirection of stream 2, the error stream) currently triggers a PowerShell error.Unfortunately, control operators && and || are not supported in PowerShell as of Windows PowerShell v5.1 / PowerShell Core v6.0.0-beta.9; even if they were, however, you wouldn't need them here (and you wouldn't use them with $true or $false).
Irrespective of whether stderr output is silenced or not:
$LASTEXITCODE contains the exit code of the most recently executed external utility.
Immediately after executing an external utility, $? is $True if $LASTEXITCODE is 0, and $False otherwise.
For a comprehensive discussion of PowerShell's error handling - with respect to both PowerShell-native commands and external utilities - see here.
For many common tasks, the right answer is to use the native PowerShell commands that already exist.
For this particular example, the correct path is to use Stop-Service cmdlet, which will handle your conditions gracefully.
If you must use a legacy tool, see this StackOverflow answer: Powershell: Capture program stdout and stderr to separate variables
The .exe's don't put a traditional value on the PowerShell output pipeline for you to evaluate, so trying to compare $true does nothing useful. See also: Windows PowerShell Rethinking the Pipeline
Additionally, $ErrorActionPreference will have no effect on a legacy .EXE. (And -ErrorAction is specific to PowerShell commands.)
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