80

我有一个 PowerShell 脚本,它使用 du.exe(最初来自 Sysinternals 的磁盘使用情况)来计算目录的大小。

如果我du c:\Backup在控制台中运行,它会按预期工作,但在 ISE 或 PowerGui 中运行的同一行代码会给出预期结果加上错误

+ du <<<<  c:\backup
+ CategoryInfo          : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

这是为什么?如何避免此错误?我尝试了调用表达式,使用&,但不行。

谢谢您的帮助。

4

5 回答 5

54

为避免这种情况,您可以将 stderr 重定向到 null 例如:

du 2> $null

本质上,控制台主机和 ISE(以及远程处理)对 stderr 流的处理方式不同。在控制台主机上,重要的是 PowerShell 支持像 edit.com 这样的应用程序与其他将彩色输出和错误写入屏幕的应用程序一起工作。如果 I/O 流未在控制台主机上重定向,PowerShell 会为本机 EXE 提供一个控制台句柄以直接写入。这绕过了 PowerShell,因此 PowerShell 无法看到写入的错误,因此无法通过 $error 或写入 PowerShell 的 stderr 流来报告错误。

ISE 和远程处理不需要支持这种情况,因此它们确实会在 stderr 上看到错误并随后写入错误并更新 $error。

于 2010-01-19T17:45:04.920 回答
49

我最近遇到了同样的问题,但我想将标准错误输出定向到标准输出。您会认为以下方法会起作用:

    & du 2>&1

但是 PowerShell 会在“du”完成后解释重定向并处理它。我发现的解决方法是使用 cmd.exe /c 调用它:

    & cmd /c 'du 2>&1'
于 2013-05-02T09:08:13.833 回答
47

抑制NativeCommandError输出的另一种方法是将管道中的对象转换为字符串,如本答案底部所述:

du c:\Backup 2>&1 | %{ "$_" }
于 2014-01-06T12:49:48.247 回答
2

以前的 FIX 将重定向错误,但如果您的用户名或密码不好,或者如果使用集成身份验证,您没有访问权限,您可能会丢失一个真正的错误。

因此,这是一种实现错误处理并绕过 psexec 引发的特定错误(不是一个)的方法。

try {
    whoami # powershell commands
}
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
}

于 2017-02-17T20:30:46.790 回答
0

After pulling a load of hair out, I realised that actually, these errors only occur when running the .ps1 file from "Windows PowerShell ISE".

When I ran the same .ps1 script from a Command Line, the errors didn't happen.

powershell.exe .\MikesScript.ps1
于 2022-01-03T16:10:24.673 回答