PowerShell模块函数不会继承WhatIf

时间:2018-01-24 11:33:46

标签: 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".
----------------------------------------

你可以在第二个"块"输出我直接调用模块函数并得到一个WhatIf语句。

你可以看到第5"块"输出我在本地Call-ShowWhatIf函数中调用模块函数,因为得到警告说没有设置WhatIf。

1 个答案:

答案 0 :(得分:2)

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

将此问题添加到Show-WhatIfOutput可以解决问题:

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

检查 来电者 Call-ShowWhatIf)是否指定了-WhatIf。如果 函数调用 -WhatIf

中未指定Show-WhatIfOutput,则会执行此操作

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