是否可以将$ ErrorActionPreference ='Stop'配置为Powershell模块中所有功能的默认设置?

时间:2019-04-24 22:53:36

标签: powershell module

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

每个功能我都有一个文件。

2 个答案:

答案 0 :(得分:1)

您似乎可以在整个会话期间$PSDefaultParameterValuespreference variable中使用显式默认参数设置来执行此操作。

这包括为特定功能将 ErrorAction Common Parameter设置为默认值的功能。请记住,由于$PSDefaultParameterValues使用哈希表,因此您要追加当前值,并且其他函数当前可能在当前会话中设置了默认值。这也意味着[CmdletBinding()]必须包含在为此默认值指定的每个函数中。

$PSDefaultParameterValueshash table,因此您希望以如下方式进行修改:

$PSDefaultParameterValues += @{
    "Get-Function:ErrorAction"="Stop"
    "Get-Command:ErrorAction"="Stop"
    "Get-MyFunction*:ErrorAction"="Stop"
}

$PSDefaultParameterValues.add("Get-Function:ErrorAction","Stop")

Wildcards在函数/ cmdlet名称中被接受,如果您具有用于从模块导入的唯一名词前缀命名方案,则可以更轻松地将所有函数放在一行中(尽管其中包括任何其他包含相同命名前缀的函数/ cmdlet(如果有的话)导入到会话中。

答案 1 :(得分:1)

假设您的模块是 script 模块,即以PowerShell代码实现:

重要

  • 模块具有自己的范围堆栈,该范围堆栈与非模块代码(和其他模块)的范围无关。尽管这提供了与通常有用的调用者环境的隔离,但这也意味着 调用者的 $ErrorActionPreference从不对脚本模块功能生效(除非您直接在 global 范围内运行,该模块也可以看到)-但这对于已编译的 cmdlet 来说是这样。 this GitHub issue中讨论了这种严重问题的行为。

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

  • 但是,使用-ErrorAction 通用参数而不是$ErrorActionPreference preference变量进行特定调用仍会覆盖您的模块-global $ErrorActionPreference值,因为PowerShell在后台将-ErrorAction参数转换为具有该值的 function-local $ErrorActionPreference变量。

  • -ErrorAction$ErrorActionPreference机制受到不一致和模糊行为的困扰-this GitHub docs issue提供了PowerShell错误处理的全面概述。

  

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

是-只需将$ErrorActionPreference = 'Stop'放在您的RootModule *.psm1文件的顶级代码中。 (模块清单文件(RootModule的{​​{1}}条目指定了模块的主模块-请参见the docs)。

  • 如果您没有引用*.psd1文件的RootModule条目,只需在模块文件夹(通常为封闭模块命名)中创建一个.psm1文件,其内容为{ {1}},并从.psm1条目中引用它-有关背景信息,请参见this answer

除非调用者在调用模块的函数(假定它们是高级函数)时使用通用的$ErrorActionPreference = 'Stop'参数覆盖,否则模块的顶级RootModule值将对您模块的所有功能均有效,如果您的功能直接 发出声明终止错误 [1] 除外sup>,在这种情况下,重要的是呼叫者的 -ErrorAction值。


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

已编译的cmdlet没有自己的作用域-它们在调用者的作用域中运行。因此,重要的是呼叫者的 $ErrorActionPreference,可以使用通用参数$ErrorActionPreference在每次呼叫的基础上覆盖它,但仅对于 non -终止错误。

与脚本模块中的高级功能一样,直接发出的语句-终止错误 [1] 总是 ,受调用者的{{1 }}值,即使使用$ErrorActionPreference也是如此。 (请注意,二进制cmdlet不会发出 script 终止错误)。


在以下情况下,会发生

[1] 声明终止错误:

  • 直接,以终止执行封闭的cmdlet或高级功能/脚本:

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

    • p>
    • 高级PowerShell功能/脚本类似地必须使用-ErrorAction,但是在实践中很少见;通常使用的$ErrorActionPreference语句会创建一个 script 终止错误,该错误默认情况下还会终止整个线程,即也终止调用方及其所有调用方。

  • 间接,在PowerShell代码中:

    • 表达式导致运行时错误,例如-ErrorAction$PSCmdlet.ThrowTerminatingError()

    • .NET 方法调用引发异常时,例如Throw

    • 在高级功能/脚本中调用另一个cmdlet或高级功能/脚本时,其本身直接发出语句终止错误。

    • 请注意,高级功能/脚本不能中继这样的语句终止错误

      • 默认情况下(1 / 0包含'a,b' -split ',', 'NotAnInt',可能只是在本地范围内),表达式的/ other命令的终止错误实际上变成了 non 终止错误从呼叫者的角度来看。

      • [int]::Parse('NotAnInt')设置为$ErrorActionPreference的情况下,最初的语句终止错误被提升为 script 终止错误。