1

I need to check the exit code of a script block run in a remote session (started with New-PSSession) and initiated with Invoke-Command. The implementation I would prefer to use is featured here

Here is the code snippet:

$RemoteSession = New-PSSession -ComputerName ... -Credential $cred 
$s = "something"
$parameters = ($parameters + $s)
$ScriptBlock = {
    function PrintObjectDetails ()
    {
        $object = [PSCustomObject]@{
            prop1 = "value1"
            prop2 = "value2"
        }
        Write-Output $object
    }

    PrintObjectDetails

    Write-Host $args[-1]

    exit 1
}
Invoke-Command -Session $RemoteSession -ArgumentList $parameters -ScriptBlock $ScriptBlock
Invoke-Command -Session $RemoteSession -ScriptBlock { $LASTEXITCODE } -OutVariable exitCodeArray > $null
$exitCode = $exitCodeArray[0]

Note: I keep the object print function to just give context for the expected output sequence

The issue is I get 2 errors associated with the session not being open anymore for the second Invoke-Command:

Invoke-Command : Because the session state for session <id, computerName> is not equal to Open, you cannot run a command in the session.  The session state is Closing.
 
Invoke-Command : No valid sessions were specified.  Ensure you provide valid sessions that are in the Opened state and are available to run commands.

Why does the session close after one Invoke-Command?

How can I avoid closing it or getting $LASTEXITCODE from that run (without disrupting the output sequence)?

  • Try removing the "exit 1". Exit 0 is the return code with no errors. – jdweng Apr 25 '23 at 11:15
  • 1
    @jdweng The idea is to get the error code if there is one stored in the $LASTEXITCODE but the issue is still that I cannot run the second "Invoke-Command" due to errors mentioned in the question – Black Shark Apr 25 '23 at 11:35
  • That is why I suggested to remove the exit code. – jdweng Apr 25 '23 at 11:51
  • @jdweng Yes, if the exit command does not happen, the second invoke-command seems to work. But what to do in case it happens? – Black Shark Apr 25 '23 at 12:13
  • Only add exit coded when there is an error. The error should show up on the $LastExitCode. – jdweng Apr 25 '23 at 14:06

1 Answers1

1

tl;dr

  • Replace exit 1 with $LASTEXITCODE = 1 to prevent your remote session from closing after the first Invoke-Command call.

Background information:
  • If you use exit in the global scope of a session, the session exits as a whole.

  • Thus, your exit 1 exits the session and thereby invariably closes the remote session stored in $RemoteSession.

    • Subsequent attempts to use the closed session with Invoke-Command then trigger the error you saw.
  • By contrast, exit calls from inside a script exit that script only and, if an exit code was specified (using a numeric argument, e.g., exit 1), that exit code is recorded in the automatic $LASTEXITCODE variable

  • Similarly, the exit code of the most recently executed child process (external-program call) is recorded in $LASTEXTICODE.

Even though it's generally not a good idea, you can set $LASTEXTICODE directly, as shown at the top, if you really need to determine the exit code manually (as opposed to letting the last script / external-program call set it).

mklement0
  • 382,024
  • 64
  • 607
  • 775