question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

$LASTEXITCODE does not get set for native commands in pipelines

See original GitHub issue

Prerequisites

Steps to reproduce

I am trying to get the exit code of a native command, but the variable $LASTEXITCODE is not set. This happens only, if I pipe the output of the native command to a cmdlet.

The stripped down script, to reproduce this, is:

Set-StrictMode -Version:'3.0'
$local:ErrorActionPreference = 'Stop'

# Using cmd.exe here is only an example. Could be any native command.
$firstLine = cmd.exe /c 'echo hello & echo world & exit 42' | Select-Object -First 1
$firstLine
"The exit code of cmd.exe is ${LASTEXITCODE}"
'end'

I give this script the name temp.ps1. To run this script, I execute the following line in cmd.exe:

pwsh -NoProfile -File .\temp.ps1

Expected behavior

The expected output is:

hello
the exit code of cmd.exe is 42
end

Actual behavior

The actual output is:

hello
InvalidOperation: C:\Users\User\temp.ps1:7
Line |
   7 |  "The exit code of cmd.exe is ${LASTEXITCODE}"
     |                               ~~~~~~~~~~~~~~~
     | The variable '$LASTEXITCODE' cannot be retrieved because it has not been set.

Error details

Type        : System.Management.Automation.RuntimeException
ErrorRecord :
    Exception             :
        Type    : System.Management.Automation.ParentContainsErrorRecordException
        Message : The variable '$LASTEXITCODE' cannot be retrieved because it has not been set.
        HResult : -2146233087
    TargetObject          : LASTEXITCODE
    CategoryInfo          : InvalidOperation: (LASTEXITCODE:String) [], ParentContainsErrorRecordException
    FullyQualifiedErrorId : VariableIsUndefined
    InvocationInfo        :
        ScriptLineNumber : 7
        OffsetInLine     : 30
        HistoryId        : -1
        ScriptName       : C:\Users\User\temp.ps1
        Line             : "The exit code of cmd.exe is ${LASTEXITCODE}"

        PositionMessage  : At C:\Users\User\temp.ps1:7 char:30
                           + "The exit code of cmd.exe is ${LASTEXITCODE}"
                           +                              ~~~~~~~~~~~~~~~
        PSScriptRoot     : C:\Users\User
        PSCommandPath    : C:\Users\User\temp.ps1
        CommandOrigin    : Internal
    ScriptStackTrace      : at <ScriptBlock>, C:\Users\User\temp.ps1: line 7
                            at <ScriptBlock>, <No file>: line 1
TargetSite  :
    Name          : Invoke
    DeclaringType : System.Management.Automation.Runspaces.PipelineBase, System.Management.Automation, Version=7.3.4.500, Culture=neutral, PublicKeyToken=31bf3856ad364e35
    MemberType    : Method
    Module        : System.Management.Automation.dll
Message     : The variable '$LASTEXITCODE' cannot be retrieved because it has not been set.
Data        : System.Collections.ListDictionaryInternal
Source      : System.Management.Automation
HResult     : -2146233087
StackTrace  :
   at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
   at Microsoft.PowerShell.Executor.ExecuteCommandHelper(Pipeline tempPipeline, Exception& exceptionThrown, ExecutionOptions options)

Environment data

Name                           Value
----                           -----
PSVersion                      7.3.4
PSEdition                      Core
GitCommitId                    7.3.4
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

and also

Name                           Value
----                           -----
PSVersion                      7.4.0-preview.3
PSEdition                      Core
GitCommitId                    7.4.0-preview.3
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

Issue Analytics

  • State:closed
  • Created 3 months ago
  • Comments:9

github_iconTop GitHub Comments

1reaction
j0lecommented, Jun 27, 2023

I close this issue, because I see that the label “Issue-Question” was added. I interpret this to mean that the behaviour is as designed. Thanks again for your help.

1reaction
SeeminglySciencecommented, Jun 26, 2023

Select-Object -First 1 stops upstream commands after they have output one item, so cmd never hits the exit 42 part. If instead you force full execution of the command before piping like this:

(cmd.exe /c 'echo hello & echo world & exit 42') | Select-Object -First 1
$LASTEXITCODE

You will see what you expect

Read more comments on GitHub >

github_iconTop Results From Across the Web

PowerShell Start-Process not setting $lastexitcode
I have a set of test DLL's that I'm running from a powershell script that calls OpenCover.Console.exe via the Start-Process command. I have...
Read more >
about Automatic Variables - PowerShell
The script calls a native command; The script uses the exit keyword. When a script is called with pwsh using the File parameter,...
Read more >
LastExitCode and $? always return empty or True
Looking again at your script you are running non-powershell commands. $lastexitcode is set to non-zero value when a native command (ex. netsh, ...
Read more >
about Pipeline Chain Operators - PowerShell
These operators use the $? and $LASTEXITCODE variables to determine if a pipeline failed. This allows you to use them with native commands...
Read more >
Windows PowerShell failed still marks job successful (#3194)
Summary A Powershell command failed, job stopped (while there are some other script lines) but it succeeded. It mustn't.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found