【问题标题】:PowerShell module function does not inherit WhatIfPowerShell 模块函数不继承 WhatIf
【发布时间】:2018-07-03 10:35:19
【问题描述】:

TL;DR:为什么模块函数在从脚本调用时不隐式继承 -WhatIf

据我了解,cmdlet 和函数将从调用脚本继承开关,例如 -WhatIf,但我看到的行为表明并非总是如此。我已经确认How do you support PowerShell's -WhatIf & -Confirm parameters in a Cmdlet that calls other Cmdlets? 中的示例对我来说可以正常工作,但是当我的脚本调用模块中定义的函数时似乎会出现问题。

在我的例子中,我有一个脚本,其函数在本地(即在 PS1)文件中定义。此脚本导入一个脚本模块。当我使用-WhatIf 开关运行我的主脚本时,本地函数会继承-WhatIf 状态,但模块函数不会表现出“WhatIf”行为,这可能是灾难性的。

如果我在明确设置-WhatIf 开关的情况下调用Show-WhatIfOutput,它会按预期工作。

如果我将 Call-ShowWhatIf 函数从脚本移动到模块,并使用 Call-ShowWhatIf -WhatIf 它工作正常。也就是说,Show-WhatIfOutput 确实隐式设置了 -WhatIf,但这不是我可以在实际案例中使用的解决方案。

更简单,如果我在主脚本上启用SupportsShouldProcess,就会出现相同的模式:本地函数将继承开关;模块功能现在将。

为什么模块函数在脚本调用时不继承-WhatIf


测试代码

Test-WhatIf.psm1

function Show-WhatIfOutput {
    [CmdletBinding(SupportsShouldProcess)]
    param(
    )

    Write-Host $MyInvocation.Line.Trim()

    if($PSCmdlet.ShouldProcess("My host","Display WhatIf text")){
        Write-Warning "This is not WhatIf text!"
    }

    Write-Host ("-"*40)
}

Test-WhatIf.ps1

Import-Module C:\Test-WhatIf.psm1 -Force

function Call-ShowWhatIf {
    [CmdletBinding(SupportsShouldProcess)]
    param(
    )

    Write-Host "$($MyInvocation.Line.Trim()) > " -NoNewline
    Show-WhatIfOutput

    Write-Host "$($MyInvocation.Line.Trim()) > " -NoNewline
    Show-WhatIfOutput -WhatIf
}

Write-Host ("-"*40)

Show-WhatIfOutput
Show-WhatIfOutput -WhatIf
Call-ShowWhatIf
Call-ShowWhatIf -WhatIf

将这两个文件保存到(比如说)C:\ 并运行 PS1 脚本。我收到的输出是:

----------------------------------------
Show-WhatIfOutput
WARNING: This is not WhatIf text!
----------------------------------------
Show-WhatIfOutput -WhatIf
What if: Performing the operation "Display WhatIf text" on target "My host".
----------------------------------------
Call-ShowWhatIf > Show-WhatIfOutput
WARNING: This is not WhatIf text!
----------------------------------------
Call-ShowWhatIf > Show-WhatIfOutput -WhatIf
What if: Performing the operation "Display WhatIf text" on target "My host".
----------------------------------------
Call-ShowWhatIf -WhatIf > Show-WhatIfOutput
WARNING: This is not WhatIf text!
----------------------------------------
Call-ShowWhatIf -WhatIf > Show-WhatIfOutput -WhatIf
What if: Performing the operation "Display WhatIf text" on target "My host".
----------------------------------------

您可以看到,在输出的第二个“块”中,我直接调用了模块函数并得到了一个 WhatIf 语句。

您可以看到,在输出的第 5 个“块”中,我从本地 Call-ShowWhatIf 函数中调用模块函数,因为收到警告说未设置 WhatIf。

【问题讨论】:

  • 这是什么 PowerShell 版本?
  • PowerShell 5.1.15063.483

标签: function powershell testing module


【解决方案1】:

调用者Preference Variables 不会从Call-ShowWhatIf 传播到Show-WhatIfOutput。 AFAIK 这是从模块调用的函数的已知问题。在这种情况下,没有传播的是$WhatIfPreference

将此添加到您的 Show-WhatIfOutput 应该可以解决问题:

if (-not $PSBoundParameters.ContainsKey('WhatIf'))
{
    $WhatIfPreference= $PSCmdlet.GetVariableValue('WhatIfPreference')
}

它检查 调用者 (Call-ShowWhatIf) 是否指定了-WhatIf。它在 函数调用 (Show-WhatIfOutput)

中未指定 -WhatIf 时执行此操作

This is a similar post 描述了与 -Verbose 不传播相同的问题。

相关链接:
PowerShell.org - Script Modules and Variable Scopes
Scripting Guy - Weekend Scripter: Access PowerShell Preference Variables
TechNet - Import Preference variables from the caller of a Script Module function

【讨论】:

  • 我会尽快阅读链接;我正在寻找关于为什么会发生这种情况的解释以及如何解决或解决该问题的想法。理想情况下,我不想为每个模块函数添加逻辑。
猜你喜欢
  • 2023-02-07
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2016-06-24
  • 2014-01-02
  • 2020-06-27
相关资源
最近更新 更多