为何用$Host创建的Runspace的错误流未在控制台显示?
为什么Runspace中写入的错误信息未出现在输出里?
问题重现
以下PowerShell代码先在当前Runspace的各非输出流写入内容,再通过$Host创建另一个Runspace执行相同逻辑:
$sb = { $DebugPreference = 'Continue' $InformationPreference = 'Continue' Write-Debug 'some debug' Write-Information 'some information' Write-Verbose 'some verbose' -Verbose Write-Warning 'some warning' Write-Error 'some error' } . $sb '----' $rs = [runspacefactory]::CreateRunspace($Host) $rs.Open() [powershell]::Create($rs). AddScript($sb). Invoke() | Out-Null
在控制台运行后输出如下:
VERBOSE: some verbose WARNING: some warning Write-Error: C:\test.ps1:13 Line | 13 | . $sb | ~~~~~ | some error ---- DEBUG: some debug some information VERBOSE: some verbose WARNING: some warning
原因分析
核心问题在于独立Runspace的错误流不会自动输出到控制台:
- 直接调用
. $sb时,当前Runspace的错误流默认关联宿主控制台,所以Write-Error的内容会直接显示。 - 当你通过
[powershell]类创建独立Runspace执行脚本时,该实例的错误流会被收集到自身的.Streams.Error集合中,而非自动转发到宿主控制台。Invoke()方法仅返回输出流(成功流)的内容,你用Out-Null丢弃了这部分,但错误流的内容从未被处理或输出。
而调试、信息、警告、Verbose流能显示,是因为你创建Runspace时传入了当前$Host,这些流会直接关联宿主输出管道,所以内容会自动显示。
验证与解决
如果要查看Runspace中的错误信息,可以显式访问.Streams.Error集合:
$sb = { $DebugPreference = 'Continue' $InformationPreference = 'Continue' Write-Debug 'some debug' Write-Information 'some information' Write-Verbose 'some verbose' -Verbose Write-Warning 'some warning' Write-Error 'some error' } . $sb '----' $rs = [runspacefactory]::CreateRunspace($Host) $rs.Open() $ps = [powershell]::Create($rs).AddScript($sb) $ps.Invoke() | Out-Null # 输出错误流内容 $ps.Streams.Error
运行后就能看到Runspace中产生的错误信息了。如果想让错误自动输出到控制台,也可以在脚本块中设置$ErrorActionPreference = 'Continue',不过本质上还是需要确保错误流的内容被处理或转发。
内容的提问来源于stack exchange,提问作者alx9r
相关产品推荐
相关产品推荐

