Powershell:如何阻止错误显示在脚本中?

And*_*ehm 76 error-handling powershell

例如,当我的PowerShell脚本尝试为不存在的服务器创建SQL Server对象时(在我的情况下为"bla"),PowerShell会以红色显示许多PowerShell错误.

由于我的脚本会检查$?此类调用之后的值,并显示和记录错误,因此我不想显示多行PowerShell错误.

如何停用为脚本显示的内容?

JNK*_*JNK 111

你有几个选择.最简单的涉及使用ErrorAction设置.

-Erroraction是所有cmdlet的通用参数.如果您要忽略特殊命令-erroraction 'silentlycontinue',则可以使用哪些命令基本上会忽略该命令生成的所有错误消息.您还可以使用该Ignore值(在PowerShell 3+中):

与SilentlyContinue不同,Ignore不会将错误消息添加到$ Error自动变量.

如果要忽略脚本中的所有错误,可以使用系统变量$ErrorActionPreference并执行相同的操作:$ErrorActionPreference= 'silentlycontinue'

有关-ErrorAction的更多信息,请参阅about_CommonParameters.有关$ ErrorActionPreference的更多信息,请参阅about_preference_variables.

  • 设置系统变量就是诀窍. (10认同)
  • 如果上述格式不适合您,请参考上面提供的链接。我必须在 PS 5.1 中将其格式设置为 `-ErrorAction:SilentlyContinue`。我正在从批处理中调用我的 cmdlet,所以我不知道这是否会产生影响。但是,当您知道可能会抛出可接受的错误时,这是​​很好的信息。 (2认同)
  • --rm .\Windows.old\ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code> (2认同)

ske*_*tax 28

您还可以附加2>$null到您的命令中。

例子:

$rec = Resolve-DnsName $fqdn -Server $dns 2>$null
Run Code Online (Sandbox Code Playgroud)

  • 尽管这可能不是“正确”的方式,但这对于处理输出错误的损坏的 CmdLet 来说是完美的,无论错误首选项开关或变量如何。只需对 Get-CsOnlineVoiceUser 版本 3.1.1 执行此操作,该版本必须在后台使用 Get-CsUser 而不正确处理其错误。 (4认同)

JPB*_*anc 15

Windows PowerShell提供了两种报告错误的机制:一种用于终止错误的机制和另一种用于非终止错误的机制.

内部CmdLets代码可以ThrowTerminatingError在发生错误时调用方法,该错误不允许或不允许cmdlet继续处理其输入对象.脚本编写者可以使用异常来捕获这些错误.

EX:

try
{
  Your database code
}
catch
{
  Error reporting/logging
}
Run Code Online (Sandbox Code Playgroud)

WriteError当cmdlet可以继续处理输入对象时,内部CmdLets代码可以调用方法来报告非终止错误.然后,脚本编写者可以使用-ErrorAction选项隐藏消息,或使用它$ErrorActionPreference来设置整个脚本行为.


Jay*_*ani 8

添加-ErrorAction SilentlyContinue到您的脚本中,您就可以开始了。


小智 7

尝试使用时解决主机名时遇到了类似的问题[system.net.dns].如果IP未解决.Net会发出终止错误.为了防止终止错误并仍然保持对输出的控制,我使用了创建了一个函数TRAP.

例如

Function Get-IP 
{PARAM   ([string]$HostName="")
PROCESS {TRAP 
             {"" ;continue} 
             [system.net.dns]::gethostaddresses($HostName)
        }
}
Run Code Online (Sandbox Code Playgroud)


jpm*_*c26 7

你在这里偏离了轨道。

你已经有一个很好的、很大的错误信息。为什么您要编写$?每个命令之后进行显式检查的代码?这非常麻烦且容易出错。正确的解决办法是停止检查$?

相反,请使用 PowerShell 的内置机制为您解决问题。您可以通过将错误首选项设置为最高级别来启用它:

$ErrorActionPreference = 'Stop'
Run Code Online (Sandbox Code Playgroud)

我把它放在我写过的每个脚本的顶部,现在我不必检查$?. 这使我的代码更加简单和可靠。

如果您遇到确实需要禁用此行为的情况,您可以catch使用公共-ErrorAction. 在您的情况下,您可能希望您的进程在第一个错误处停止,捕获错误,然后将其记录下来。

请注意,当外部可执行文件失败(退出代码非零,传统上)时,这不会处理这种情况,因此您仍然需要检查$LASTEXITCODE是否调用了任何。尽管有这个限制,该设置仍然节省了大量的代码和精力。

额外的可靠性

您可能还想考虑使用严格模式

Set-StrictMode -Version Latest
Run Code Online (Sandbox Code Playgroud)

当您使用不存在的变量和其他奇怪的情况时,这可以防止 PowerShell 静默运行。(有关-Version其限制的详细信息,请参阅参数。)

结合这两个设置使 PowerShell 更像是快速失败的语言,这使得使用它进行编程变得更加容易。

  • 您声称这使其更加可靠,但在任何自动化的情况下,它都会起到相反的作用。有时,无论先前的 cmdlet 是否存在错误,都应该运行某些脚本,并且分发单个 powershell 脚本比为每个所需操作分发一个脚本要容易得多。使用您的解决方案,如果启动时需要删除的文件不存在(因为 Windows),则尽管系统处于所需状态,但该脚本中的后续 cmdlet 都不会运行。恭喜,您现在远程运行了一个损坏的脚本,其中的错误未推送到日志文件中 (6认同)
  • 您实际上是在回答“如何禁用此错误输出?我在脚本中内置了自己的错误检查”,方法是“不要这样做,只需让错误阻止脚本” ”。显然,如果他们内置了错误检查功能,那么他们就会处理这些问题。你并没有提供帮助,只是不必要地逆反,因为你没有预见到一个事情不会按照你习惯的方式运作的环境。请在提供答案时,实际回答问题,而不是仅仅告诉某人不要做某事。 (5认同)