$ LastExitCode = 0, pero $? = False en PowerShell. Redirigir stderr a stdout da NativeCommandError

¿Por qué PowerShell muestra el comportamiento sorprendente en el segundo ejemplo a continuación?

Primero, un ejemplo de comportamiento sano:

PS C:\> & cmd /c "echo Hello from standard error 1>&2"; echo "`$LastExitCode=$LastExitCode and `$?=$?"
Hello from standard error
$LastExitCode=0 and $?=True

No hay sorpresas. Imprimo un mensaje a error estándar (usandocmdesecho). Yo inspecciono las variables$? y$LastExitCode. Son iguales a Verdadero y 0 respectivamente, según lo esperado.

Sin embargo, si le pido a PowerShell que redirija el error estándar a la salida estándar sobre el primer comando, obtengo un NativeCommandError:

PS C:\> & cmd /c "echo Hello from standard error 1>&2" 2>&1; echo "`$LastExitCode=$LastExitCode and `$?=$?"
cmd.exe : Hello from standard error
At line:1 char:4
+ cmd <<<<  /c "echo Hello from standard error 1>&2" 2>&1; echo "`$LastExitCode=$LastExitCode and `$?=$?"
    + CategoryInfo          : NotSpecified: (Hello from standard error :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

$LastExitCode=0 and $?=False

Mi primera pregunta, ¿por qué NativeCommandError?

En segundo lugar, porque es$? Falso cuandocmd corrió con éxito y$LastExitCode es 0? Documentación de PowerShellsobre variables automáticas no define explícitamente$?. Siempre supuse que es verdad si y solo si$LastExitCode es 0, pero mi ejemplo contradice eso.

Aquí es cómo me encontré con este comportamiento en el mundo real (simplificado). Realmente es FUBAR. Estaba llamando a un script de PowerShell de otro. El guión interno:

cmd /c "echo Hello from standard error 1>&2"
if (! $?)
{
    echo "Job failed. Sending email.."
    exit 1
}
# Do something else

Ejecutando esto simplemente como.\job.ps1, funciona bien, y no se envía ningún correo electrónico. Sin embargo, lo estaba llamando desde otro script de PowerShell, iniciando sesión en un archivo.\job.ps1 2>&1 > log.txt. En este caso, se envía un correo electrónico! Lo que haga fuera de la secuencia de comandos con la secuencia de error afecta el comportamiento interno de la secuencia de comandos.Observar un fenómeno cambia el resultado. ¡Esto se siente como física cuántica en lugar de scripting!

[Curiosamente:.\job.ps1 2>&1 puede o no explotar dependiendo de donde lo ejecutes]

Respuestas a la pregunta(4)

Su respuesta a la pregunta