首页 > 解决方案 > 是否可以将 $ErrorActionPreference = 'Stop' 配置为 powershell 模块中所有功能的默认值?

问题描述

我希望我的模块中的所有功能都默认为$ErrorActionPreference = 'Stop'. 是否可以不修改所有功能?

我每个函数都有一个文件。

标签: powershellmodule

解决方案


假设您的模块是脚本模块,即在 PowerShell 代码中实现:

重要

  • 模块有自己的范围堆栈,独立于非模块代码(和其他模块)的范围。虽然这提供了与通常有用的 $ErrorActionPreference调用者环境的隔离,但这也意味着调用者的永远不会对脚本模块函数生效(除非您直接从全局范围运行,模块也可以看到) - 但它对已编译的小命令此GitHub 问题中讨论了这种高度成问题的行为。

  • 因此,即使您目前无法通过调用方控制脚本模块的错误行为,但通过在模块中$ErrorActionPreference设置(覆盖) ,您将永久关闭该门。$ErrorActionPreference

  • 但是,使用特定调用的-ErrorAction 公共参数而不是$ErrorActionPreference 首选项变量仍将覆盖您的模块全局$ErrorActionPreference值,因为在幕后,PowerShell 将-ErrorAction参数转换为具有该值的函数局部 $ErrorActionPreference变量。

  • -ErrorAction$ErrorActionPreference机制受到不一致和模糊行为的困扰 -这个GitHub 文档问题提供了 PowerShell 错误处理的全面概述。

我希望我的模块中的所有功能都默认为$ErrorActionPreference = 'Stop'. 是否可以不修改所有功能?

是的 - 只需放在$ErrorActionPreference = 'Stop'文件RootModule *.psm1的顶级代码中。(RootModule模块清单文件 ( *.psd1) 的条目指定模块的主模块 - 请参阅文档)。

  • 如果您没有RootModule引用.psm1文件的条目,只需.psm1在模块文件夹(通常以封闭模块命名)中创建一个包含 content 的文件$ErrorActionPreference = 'Stop',然后从RootModule条目中引用它 - 有关背景信息,请参阅此答案

除非调用者-ErrorAction在调用模块函数时使用 common 参数覆盖(假设它们是高级函数),否则模块的顶级$ErrorActionPreference值将对模块的所有函数有效,除非函数直接发出语句-terminating error [1],在这种情况下,调用者的 $ErrorActionPreference值很重要。


如果您的模块是二进制模块,即导出已编译的 cmdlet(通常在 C# 中实现):

编译的 cmdlet 没有自己的范围 - 它们在调用者的范围内运行。因此,重要的是调用者 $ErrorActionPreference,它可以在每次调用的基础上使用 common parameter 覆盖-ErrorAction,但仅适用于终止错误。

与脚本模块中的高级函数一样,直接发出的语句终止错误[1]始终受调用者的$ErrorActionPreference值影响,即使-ErrorAction使用了也是如此。(请注意,二进制 cmdlet 不会发出脚本终止错误)。


[1]语句终止错误发生在以下情况:

  • 直接,中止封闭 cmdlet 或高级函数/脚本的执行:

    • 当二进制cmdlet遇到阻止其继续执行的严重错误时,它会使用方法报告此类错误ThrowTerminatingError()(或仅引发异常)。

    • 高级 PowerShell 函数/脚本同样必须使用$PSCmdlet.ThrowTerminatingError(),但是在实践中很少见;通常使用的Throw语句会创建一个脚本终止错误,默认情况下也会终止整个线程,即也终止调用者及其所有调用者。

  • 间接地,在 PowerShell 代码中:

    • 表达式导致运行时错误时,例如1 / 0or 'a,b' -split ',', 'NotAnInt'

    • 当 .NET方法调用引发异常时,例如[int]::Parse('NotAnInt')

    • 当在高级函数/脚本中调用另一个 cmdlet 或高级函数/脚本时,它本身会直接发出语句终止错误。

    • 请注意,高级函数/脚本不能像这样中继语句终止错误:

      • 默认情况下($ErrorActionPreference包含'Continue',可能只是在本地范围内),从调用者的角度来看,表达式的 / other 命令的终止错误实际上变成了非终止错误。

      • $ErrorActionPreference设置为,'Stop'最初的语句终止错误被提升为脚本终止错误。


推荐阅读