function - PowerShell 模块函数不继承 WhatIf

标签 function powershell testing module

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”行为,这可能是灾难性的。

如果我调用 Show-WhatIfOutput 并显式设置了 -WhatIf 开关,它会按预期工作。

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

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

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


测试代码

测试-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)
}

测试-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".
----------------------------------------

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

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

最佳答案

来电者 Preference Variables不会从 Call-ShowWhatIf 传播到 Show-WhatIfOutput。据我所知,这是从模块调用的函数的一个已知问题。在这种情况下,$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

关于function - PowerShell 模块函数不继承 WhatIf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48421512/

相关文章:

javascript - 我只想让这个函数提醒该书在遍历 bookStore 数组后一次没有找到,而不是在每个索引处。

c++ - 解释一下C++中的链接(外部/内部)?

php - 如何用php编写函数(类似于mysql_query)

javascript - 用于多台打印机的 Testcafe .presskey

ruby - Rails 3.0.12 性能测试问题

javascript - 让函数 "return"成为 super 函数?

PowerShell Write-Zip 不保留目录结构

powershell - 当其他用户使用PowerShell注销时自动登录用户

powershell - Start-Job 输出去哪里了?

testing - Jenkins :限制测试作业在与其测试作业相同的奴隶上运行