我的PowerShell脚本遇到了一个问题,其中“Write-Error”函数在通过“Register-ObjectEvent”触发时未在控制台中显示错误。
以下是我的脚本:
$ScriptBlock = {
Start-Sleep 3
Write-Error 'sample Error'
}
$ps = [powershell]::Create()
$null = $ps.AddScript($ScriptBlock)
$handle = $ps.BeginInvoke()
$e = Register-ObjectEvent -InputObject $ps -EventName 'InvocationStateChanged' -Action {
Write-Warning 'event fired'
if($event.Sender.HadErrors)
{
foreach($ErrorItem in $event.Sender.Streams.Error)
{
Write-Warning ('[Error Exception] {0}' -f $ErrorItem.Exception)
Write-Error -Exception $ErrorItem.Exception
}
}
}
当我运行这个脚本时,我在控制台中得到以下输出:
WARNING: event fired
WARNING: [Error Exception] Microsoft.PowerShell.Commands.WriteErrorException: sample Error
正如您所看到的,正在执行“Write-Error”函数,但控制台中没有显示错误。
有人能帮助我理解为什么会发生这种情况,以及如何解决它吗?
感谢您的评分
2条答案
按热度按时间uwopmtnx1#
我不能谈论设计原理,但是如何处理来自
-Action
脚本块的输出流**是令人惊讶的(从PowerShell 7.3.3开始编写):Register-ObjectEvent
调用返回的事件作业中被捕获。Receive-Job
按需收集这样的输出Write-Host
和Out-Host
)* 直接 * 打印到主机(控制台)。关于
-Action
脚本块的错误输出需要注意的事项:$Error
中,即会话范围的错误日志中。[int]::Parse('foo')
)还是 script-terminating(例如throw 'Aborting'
)-脚本块的执行都会被 * 悄悄地 * 中止。Receive-Job
检查它们。至于您尝试了和变通方法:
综上所述,您的
Write-Warning
调用的输出以正确的方式打印,而Write-Error
的输出则没有。让错误输出 also 立即打印的一个简单方法是使用
2>&1
重定向到成功输出流,并通过管道传输到Out-Host
:这仍然允许您稍后通过
Receive-Job
检查错误。相比之下,如果你想将 success-output流发送给 * 事件作业和直接发送给主机,你需要 * 两个 * 输出操作:一次通过
Out-Host
,并分别到成功输出流;例如:6ljaweal2#
以下可能是在PowerShell中使用
PSEventJob
的方法。对此有2个要求,第一个是从高级函数或脚本块中初始化事件,并将$PSCmdlet
传递给事件的SessionState。第二个要求是等待任务完成,这也意味着阻止线程。下面是一个最小可重复的示例: