【问题标题】:Powershell: How can I stop errors from being displayed in a script?Powershell:如何阻止错误显示在脚本中?
【发布时间】:2012-01-13 09:22:03
【问题描述】:

例如,当我的 PowerShell 脚本尝试为不存在的服务器(在我的例子中为“bla”)创建 SQL Server 对象时,PowerShell 会以红色显示大量 PowerShell 错误。

由于我的脚本会在此类调用后检查 $? 的值,并显示和记录错误,因此我宁愿不要同时显示几行 PowerShell 错误。

如何停用为我的脚本显示的那些?

【问题讨论】:

    标签: powershell error-handling


    【解决方案1】:

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

    例子:

    $rec = Resolve-DnsName $fqdn -Server $dns 2>$null
    

    【讨论】:

      【解决方案2】:

      在某些情况下,您可以在命令后使用管道输出空值

      command | Out-Null
      

      【讨论】:

        【解决方案3】:

        你在这里偏离了轨道。

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

        相反,请使用 PowerShell 的内置机制为您服务。您可以通过将error preference 设置为最高级别来启用它:

        $ErrorActionPreference = 'Stop'
        

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

        如果您遇到确实需要禁用此行为的情况,您可以catch 错误或使用通用-ErrorAction 将设置传递给特定函数。在您的情况下,您可能希望您的进程在第一个错误时停止,捕获错误,然后记录它。

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

        额外的可靠性

        您可能还想考虑使用strict mode

        Set-StrictMode -Version Latest
        

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

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

        【讨论】:

        • 您声称这使它更可靠,但在任何自动化的情况下,它的作用恰恰相反。有时,无论以前的 cmdlet 是否存在错误,都应该运行一些脚本,并且分发单个 powershell 脚本比每个所需操作更容易。使用您的解决方案,如果需要在启动时删除的文件不存在(因为 windows),那么尽管系统处于所需状态,但该脚本中的任何后续 cmdlet 都不会运行。恭喜,您现在远程运行了一个损坏的脚本,其中包含未推送到日志文件的错误
        • @TheHitchenator 更常见的是,脚本应该在它产生某种意外结果之前停止,这可能会以某种方式损坏系统,使您的观点完全无效。如果您知道即使出现错误也希望它继续运行,我解释了您是如何做到的。
        • @TheHitchenator 此外,OP已经确保检测到错误并采取行动。手动为每个命令执行此操作并不比让 PowerShell 为您执行此操作更可靠。你完全没有抓住重点。
        【解决方案4】:

        -ErrorAction SilentlyContinue 添加到您的脚本中,一切顺利。

        【讨论】:

        • 如何将 -ErrorAction SiltentlyContinue 添加到脚本中?可以举个例子吗?
        • 使用此标志,脚本可以继续运行而不会出错,但某些命令可能仍会打印错误消息。对于此命令,它会继续并且不打印错误消息:“$result = Test-Path $path -ErrorAction SilentlyContinue”,但对于此“$AppPool = Get-WebAppPoolState $sitename -ErrorAction SilentlyContinue”,它会继续并打印错误消息
        【解决方案5】:

        您有几个选择。最简单的方法是使用 ErrorAction 设置。

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

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

        如果你想忽略脚本中的所有错误,你可以使用系统变量$ErrorActionPreference并做同样的事情:$ErrorActionPreference= 'silentlycontinue'

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

        【讨论】:

        • 您需要在 -erroraction 'silentlycontinue' 中使用单引号吗? Intellisese 显示选项而不是添加单引号。
        • 如果上面的格式不适合您,请参考上面提供的链接。我必须在 PS 5.1 中格式化为 -ErrorAction:SilentlyContinue。我是从批处理中调用我的 cmdlet,所以我不知道这是否会有所不同。但是,当您知道可以接受的错误时,可能会抛出很好的信息。
        • --rm .\Windows.old\ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
        【解决方案6】:

        如果您希望抑制 cmdlet 的 powershell 错误消息,但仍想捕获错误,请使用“-erroraction 'silentlyStop'”

        【讨论】:

        • 没有这样的动作。尽管有一个停止动作。
        • 但在使用New-Item -ItemType directory (PowerShell v2.0) 时,它允许抑制红色错误消息并仍然使用catch 命令/部分
        • @MilanKerslager 您能否展示一个代码示例 - 因为我和其他所有人都相信没有像“SilentlyStop”这样的 ActionPreference
        • 我有理由相信 Mikkel 的意思是 SilentlyContinue 而不是 silentlyStop,因为这在您希望它执行的内容中更有意义。
        【解决方案7】:

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

        例如

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

        【讨论】:

          【解决方案8】:

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

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

          前:

          try
          {
            Your database code
          }
          catch
          {
            Error reporting/logging
          }
          

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

          【讨论】:

            猜你喜欢
            • 2015-02-16
            • 2022-11-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-06-16
            • 2021-01-21
            相关资源
            最近更新 更多