我正在编写一个 Powershell 脚本,它执行构建/部署过程中的步骤之一,并且需要在远程计算机上运行一些操作。该脚本相对复杂,因此如果在远程活动期间发生错误,我需要详细的堆栈跟踪来了解脚本中发生错误的位置(在已生成的日志记录之上)。
出现问题的原因是,当从远程计算机中继终止异常时,Invoke-Command 会丢失堆栈跟踪信息。如果在本地计算机上调用脚本块:
Invoke-Command -ScriptBlock {
throw "Test Error";
}
返回所需的异常详细信息:
Test Error
At C:\ScriptTest\Test2.ps1:4 char:2
+ throw "Test Error";
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Test Error:String) [], RuntimeException
+ FullyQualifiedErrorId : Test Error
但如果远程运行:
Invoke-Command -ComputerName $remoteComputerName -ScriptBlock {
throw "Test Error";
}
异常堆栈跟踪指向整个 Invoke-Command 块:
Test Error
At C:\ScriptTest\Test2.ps1:3 char:1
+ Invoke-Command -ComputerName $remoteComputerName -ScriptBlock {
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Test Error:String) [], RuntimeException
+ FullyQualifiedErrorId : Test Error
我可以手动将异常传输回本地计算机:
$exception = Invoke-Command -ComputerName $remoteComputerName -ScriptBlock {
try
{
throw "Test Error";
}
catch
{
return $_;
}
}
throw $exception;
但重新抛出它会丢失堆栈跟踪:
Test Error
At C:\ScriptTest\Test2.ps1:14 char:1
+ throw $exception;
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Test Error:PSObject) [], RuntimeException
+ FullyQualifiedErrorId : Test Error
如果我将异常写入输出:
$exception = Invoke-Command -ComputerName $remoteComputerName -ScriptBlock {
try
{
throw "Test Error";
}
catch
{
return $_;
}
}
Write-Output $exception;
我得到了正确的堆栈跟踪信息:
Test Error
At line:4 char:3
+ throw "Test Error";
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Test Error:String) [], RuntimeException
+ FullyQualifiedErrorId : Test Error
但由于它不在错误流中,因此我的构建工具无法正确拾取它。如果我尝试 Write-Error,我会遇到类似的问题,重新抛出异常,并且堆栈跟踪指向脚本的错误部分。
所以我的问题是 - 如何让 Powershell 报告来自远程计算机的异常,就好像它是在本地引发的一样,具有相同的堆栈跟踪信息和错误流?