I've got this demo-script, which I put into a Jenkins job:
Write-Host "##############################################"
$ErrorActionPreference = "Stop"
Write-Host "ErrorActionPreference: $ErrorActionPreference"
Write-Host "whoami: $(whoami)"
$PSVersionTable | Format-Table
try {
cmd /c "comanddoesnotexist c:/foo c:/bar"
} catch {
Write-Host "### Exception! ###"
}
Write-Host "################### TRACE ###########################"
Trace-Command -Name errorrecord -Expression { cmd /c "comanddoesnotexist c:/foo c:/bar" } -PSHost
Write-Host "##############################################"
When I run it locally, I get the following result:
##############################################
ErrorActionPreference: Stop
whoami: td\builder
Name Value
---- -----
PSVersion 5.1.17763.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Der Befehl "comanddoesnotexist" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
################### TRACE ###########################
Der Befehl "comanddoesnotexist" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
##############################################
however, when I run the exact same thing via Jenkins, I do get the following:
[PowerShell_DummyChecks] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Users\BUILDE~1\AppData\Local\Temp\jenkins5194440861464562005.ps1'"
##############################################
ErrorActionPreference: Stop
whoami: td\builder
Name Value
---- -----
PSVersion 5.1.17763.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
### Exception! ###
################### TRACE ###########################
cmd : Der Befehl "comanddoesnotexist" ist entweder falsch geschrieben oder
In C:\Users\builder\AppData\Local\Temp\jenkins5194440861464562005.ps1:16 Zeichen:48
+ ... cord -Expression { cmd /c "comanddoesnotexist c:/foo c:/bar" } -PSH ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (Der Befehl "com...eschrieben oder:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Build step 'Windows PowerShell' marked build as failure
Finished: FAILURE
where does this 'RemoteException' come from - why is it being caught? note that the Jenkins-service is being executed with the same account as when run locally.
to make it even worse, this issue only seems to exist with the above stated combination of Win10 + PowerShell, when I run the same job on another (older) server, I get the following (expected) result:
[PowerShell_DummyChecks] $ powershell.exe -NonInteractive -ExecutionPolicy ByPass "& 'C:\Users\BUILDE~1\AppData\Local\Temp\jenkins5640455886657276493.ps1'"
##############################################
ErrorActionPreference: Stop
whoami: td\builder
Name Value
---- -----
PSVersion 5.1.14393.3053
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14393.3053
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Der Befehl "comanddoesnotexist" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
################### TRACE ###########################
Der Befehl "comanddoesnotexist" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
##############################################
Build step 'Windows PowerShell' marked build as failure
Finished: FAILURE
and now, to add yet another layer of crazy:
when I run this script remotely via Enter-PSSession, it always fails with the "weird" behavior as on the new server. (also on the old hosts)
has anybody got a clue what's going on here?
Note: all of this is only tested/verified on Windows PowerShell 5.1
A 'RemoteException' is generated from STDERR when PowerShell runs without attached Console. (Which is (also) the case in a PS remote session). When powershell "sees" a Console (i.e. CREATE_NEW_CONSOLE or no specific flags), it will not generate any exception or error, instead it will just pipe STDERR ouput from a child process through to its very own STDERR stream. This STDERR output will in turn show up on the Console window without any red highligthing or PS exceptions.
It looks as if you're running into trouble when running from a process that has been invoked with 'CREATE_NO_WINDOW' or 'DETACHED_PROCESS' flags.
In Windows 10 1809:
When running powershell.exe without Console, just like Jenkins does it (Java Runtime.exec),
it acts as if it is running in a remote session (Enter-PSSession
) (see #3996).
In Windows 10 1607 and 1903: A locally started powershell.exe without Console acts as if it had a Console (just like run from cmd.exe) with regard to STDERR handling. (No Exception is generated, instead all output on STDERR from child processes is passed through STDERR of powershell.exe)
Side Note: When using Enter-PSSession
explicitly, PoSh behaves identically on 1607, 1809 and 1903.
One viable solution is to wrap all powershell.exe calls via a application that does CreateProcess with the 'CREATE_NEW_CONSOLE' flag and redirect stdout, as well as stderr to it's parent streams. The MSDN example can easily be modified to act as such a "proxy application".