运行 通过远程 运行 空间时 PowerShell RemoteException 不一致
PowerShell RemoteException incosistency when run via remote runspace
我有这个演示脚本,我将其放入 Jenkins 作业中:
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 "##############################################"
当我在本地 运行 时,我得到以下结果:
##############################################
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.
##############################################
然而,当我通过 Jenkins 运行 完全相同的事情时,我确实得到了以下信息:
[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
这个 'RemoteException' 来自哪里 - 为什么会被抓到?
请注意,Jenkins 服务正在使用与本地 运行 时相同的帐户执行。
更糟糕的是,这个问题似乎只存在于上述 Win10 + PowerShell 组合中,当我 运行 在另一台(较旧的)服务器上执行相同的作业时,我得到以下(预期的) ) 结果:
[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
现在,再添一层疯狂:
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)
有人知道这是怎么回事吗?
注意:所有这些仅适用于 tested/verified Windows PowerShell 5.1
当没有附加控制台的 PowerShell 运行s 时,STDERR 会生成 'RemoteException'。 (在 PS 远程会话中也是如此)。
当 powershell "sees" 一个控制台(即 CREATE_NEW_CONSOLE 或没有特定标志)时,它 will not generate any exception or error,相反它会
只需将来自子进程的 STDERR 输出通过管道传输到它自己的 STDERR 流。此 STDERR 输出将依次显示在控制台 window 上,而无需
任何红色高亮或 PS 异常。
当 运行从使用 'CREATE_NO_WINDOW' 或 'DETACHED_PROCESS' 标志。
在 Windows 10 1809:
当 运行ning powershell.exe 没有 Console 时,只是 like Jenkins does it (Java Runtime.exec),
它的行为就像在远程会话中 运行ning (Enter-PSSession
)(参见 #3996)。
在Windows 10 1607 和 1903:
在 STDERR 处理方面,没有控制台的本地启动的 powershell.exe 就好像它有一个控制台(就像 cmd.exe 中的 运行)。
(没有生成异常,而是子进程在 STDERR 上的所有输出都通过 powershell.exe 的 STDERR 传递)
旁注:明确使用 Enter-PSSession
时,PoSh 在 1607、1809 和 1903 上的行为相同。
一个可行的解决方案是通过使用 'CREATE_NEW_CONSOLE' 标志执行 CreateProcess 的应用程序包装所有 powershell.exe 调用,并将 stdout 以及 stderr 重定向到它的父流。
MSDN example 可以很容易地修改为 "proxy application".
我有这个演示脚本,我将其放入 Jenkins 作业中:
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 "##############################################"
当我在本地 运行 时,我得到以下结果:
##############################################
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.
##############################################
然而,当我通过 Jenkins 运行 完全相同的事情时,我确实得到了以下信息:
[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
这个 'RemoteException' 来自哪里 - 为什么会被抓到? 请注意,Jenkins 服务正在使用与本地 运行 时相同的帐户执行。
更糟糕的是,这个问题似乎只存在于上述 Win10 + PowerShell 组合中,当我 运行 在另一台(较旧的)服务器上执行相同的作业时,我得到以下(预期的) ) 结果:
[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
现在,再添一层疯狂:
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)
有人知道这是怎么回事吗?
注意:所有这些仅适用于 tested/verified Windows PowerShell 5.1
当没有附加控制台的 PowerShell 运行s 时,STDERR 会生成 'RemoteException'。 (在 PS 远程会话中也是如此)。 当 powershell "sees" 一个控制台(即 CREATE_NEW_CONSOLE 或没有特定标志)时,它 will not generate any exception or error,相反它会 只需将来自子进程的 STDERR 输出通过管道传输到它自己的 STDERR 流。此 STDERR 输出将依次显示在控制台 window 上,而无需 任何红色高亮或 PS 异常。
当 运行从使用 'CREATE_NO_WINDOW' 或 'DETACHED_PROCESS' 标志。
在 Windows 10 1809:
当 运行ning powershell.exe 没有 Console 时,只是 like Jenkins does it (Java Runtime.exec),
它的行为就像在远程会话中 运行ning (Enter-PSSession
)(参见 #3996)。
在Windows 10 1607 和 1903: 在 STDERR 处理方面,没有控制台的本地启动的 powershell.exe 就好像它有一个控制台(就像 cmd.exe 中的 运行)。 (没有生成异常,而是子进程在 STDERR 上的所有输出都通过 powershell.exe 的 STDERR 传递)
旁注:明确使用 Enter-PSSession
时,PoSh 在 1607、1809 和 1903 上的行为相同。
一个可行的解决方案是通过使用 'CREATE_NEW_CONSOLE' 标志执行 CreateProcess 的应用程序包装所有 powershell.exe 调用,并将 stdout 以及 stderr 重定向到它的父流。 MSDN example 可以很容易地修改为 "proxy application".