我有一个PowerShell脚本,它使用du.exe(最初来自Sysinternals的Disk Usage)来计算目录的大小。
如果我在控制台中运行du c:\Backup
,它会按预期工作,但在ISE或PowerGui中运行的相同代码行会给出预期结果加上错误
+ du <<<< c:\backup
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
为什么?如何避免此错误?我使用&
尝试了invoke-expression,但没有去。
感谢您的帮助。
答案 0 :(得分:44)
为避免这种情况,您可以将stderr重定向为null,例如:
du 2> $null
本质上,控制台主机和ISE(以及远程处理)以不同方式处理stderr流。在控制台主机上,PowerShell支持像edit.com这样的应用程序与其他将彩色输出和错误写入屏幕的应用程序一起工作非常重要。如果未在控制台主机上重定向I / O流,则PowerShell会为本机EXE提供直接写入的控制台句柄。这会绕过PowerShell,因此PowerShell无法看到写入错误,因此无法通过$ error或写入PowerShell的stderr流来报告错误。
ISE和远程处理不需要支持这种情况,因此他们确实看到stderr上的错误,然后写错误并更新$ error。
答案 1 :(得分:35)
我最近遇到了同样的问题,但我想将stderr输出定向到stdout。您会认为以下内容可行:
& du 2>&1
但PowerShell将解释重定向并在'du'完成后处理它。我找到的解决方法是使用cmd.exe / c:
调用它 & cmd /c 'du 2>&1'
答案 2 :(得分:12)
另一种取消NativeCommandError
输出的方法是将管道中的对象转换为字符串,如this answer底部所示:
du c:\Backup 2>&1 | %{ "$_" }
答案 3 :(得分:5)
尝试:
du 2>&1 | %{ "$_" }
答案 4 :(得分:1)
以前的FIX会重定向错误,但如果您的用户名或密码不正确,或者使用集成身份验证,则您可能会失去真正的错误,而您无法访问。
因此,这是一种实现错误处理并绕过psexec引发的特定错误(不是一个错误)的方法。
try{
psexec command .....
}
catch [System.Management.Automation.RemoteException]{
if ($_.TargetObject -like "Connecting to *" -and $_.CategoryInfo.Category -eq "NotSpecified" -and $_.FullyQualifiedErrorId -eq "NativeCommandError" -and $_.InvocationInfo.MyCommand.Name -like "psexec*.exe"){
$error.Remove[$Error[0]]
}
else{
Throw
}
}
catch{
throw
}