Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a PowerShell script not end when there is a non-zero exit code using the call operator?

Tags:

powershell

Why does a PowerShell script not end when there is a non-zero exit code when using the call operator and $ErrorActionPerference = "Stop"?

Using the following example, I get the result managed to get here with exit code 1:

$ErrorActionPreference = "Stop"

& cmd.exe /c "exit 1"

Write-Host "managed to get here with exit code $LASTEXITCODE"

The Microsoft documentation for the call operator does not discuss what should happen when using call operator, it only states the following:

Runs a command, script, or script block. The call operator, also known as the "invocation operator," lets you run commands that are stored in variables and represented by strings. Because the call operator does not parse the command, it cannot interpret command parameters.


Additionally, if this is expected behaviour, is there any other way to have the call operator cause an error rather than let it continue?

like image 627
Panda TG Attwood Avatar asked Oct 31 '17 09:10

Panda TG Attwood


People also ask

How do I stop a PowerShell script from running?

Open a PowerShell console session, type exit , and press the Enter key. The PowerShell console will immediately close.

What does $() mean in PowerShell?

The $() is the subexpression operator. It causes the contained expressions to be evaluated and it returns all expressions as an array (if there is more than one) or as a scalar (single value).

Does Return exit the function PowerShell?

The return keyword exits a function, script, or script block. It can be used to exit a scope at a specific point, to return a value, or to indicate that the end of the scope has been reached.

What does $_ mean in PowerShell?

The “$_” is said to be the pipeline variable in PowerShell. The “$_” variable is an alias to PowerShell's automatic variable named “$PSItem“. It has multiple use cases such as filtering an item or referring to any specific object.


2 Answers

The return code is not a PowerShell error - it's seen the same way as any other variable.

You need to then act on the variable and throw an error using PowerShell for you script to see it as a terminating error:

$ErrorActionPreference = "Stop"

& cmd.exe /c "exit 1"

if ($LASTEXITCODE -ne 0) { throw "Exit code is $LASTEXITCODE" }
like image 122
henrycarteruk Avatar answered Oct 10 '22 16:10

henrycarteruk


In almost all my PowerShell scripts, I prefer to "fail fast," so I almost always have a small function that looks something like this:

function Invoke-NativeCommand() {
    # A handy way to run a command, and automatically throw an error if the
    # exit code is non-zero.

    if ($args.Count -eq 0) {
        throw "Must supply some arguments."
    }

    $command = $args[0]
    $commandArgs = @()
    if ($args.Count -gt 1) {
        $commandArgs = $args[1..($args.Count - 1)]
    }

    & $command $commandArgs
    $result = $LASTEXITCODE

    if ($result -ne 0) {
        throw "$command $commandArgs exited with code $result."
    }
}

So for your example I'd do this:

Invoke-NativeCommand cmd.exe /c "exit 1"

... and this would give me a nice PowerShell error that looks like:

cmd /c exit 1 exited with code 1.
At line:16 char:9
+         throw "$command $commandArgs exited with code $result."
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (cmd /c exit 1 exited with code 1.:String) [], RuntimeException
    + FullyQualifiedErrorId : cmd /c exit 1 exited with code 1.
like image 18
Phil Avatar answered Oct 10 '22 16:10

Phil