如何在调用其他Cmdlet的Cmdlet中支持PowerShell的-WhatIf&-Confirm参数?

Dan*_*ane 22 powershell cmdlets powershell-2.0

我有一个支持-WhatIf&-Confirm参数的PowerShell脚本cmdlet .

它通过$PSCmdlet.ShouldProcess()在执行更改之前调用方法来完成此操作.
这按预期工作.

我遇到的问题是我的Cmdlet是通过调用其他Cmdlet实现的,并且-WhatIf或者-Confirm参数不会传递给我调用的Cmdlet.

我怎么能沿的值传递-WhatIf-Confirm我从我的Cmdlet的调用的cmdlet?

例如,如果我的Cmdlet是Stop-CompanyXyzServices,它用于Stop-Service实现其操作.

如果-WhatIf传递给Stop-CompanyXyzServices我,我希望它也传递给Stop-Service.

这可能吗?

Ryn*_*ant 16

明确传递参数

您可以使用和变量传递-WhatIf-Confirm参数.以下示例使用参数splatting实现此目的:$WhatIfPreference$ConfirmPreference

if($ConfirmPreference -eq 'Low') {$conf = @{Confirm = $true}}

StopService MyService -WhatIf:([bool]$WhatIfPreference.IsPresent) @conf
Run Code Online (Sandbox Code Playgroud)

$WhatIfPreference.IsPresent将是True,如果-WhatIf开关是在包含它的函数使用.使用-Confirm包含功能上的开关临时设置$ConfirmPreferencelow.

隐式传递参数

由于-Confirm并且自动-WhatIf临时设置$ConfirmPreference$WhatIfPreference变量,是否有必要通过它们?

考虑这个例子:

function ShouldTestCallee {
    [cmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')] 
    param($test)

    $PSCmdlet.ShouldProcess($env:COMPUTERNAME,"Confirm?")
}


function ShouldTestCaller {
    [cmdletBinding(SupportsShouldProcess=$true)]
    param($test)

    ShouldTestCallee
}

$ConfirmPreference = 'High'
ShouldTestCaller
ShouldTestCaller -Confirm
Run Code Online (Sandbox Code Playgroud)

ShouldTestCaller结果True来自ShouldProcess()

ShouldTestCaller -Confirm 即使我没有通过开关,也会出现确认提示.

编辑

@manojlds回答让我意识到我的解决方案总是设置$ConfirmPreference为'低'或'高'.-Confirm如果确认首选项为"低",我已将代码更新为仅设置开关.


Dan*_*ane 7

经过一些谷歌搜索后,我想出了一个很好的解决方案,用于将常用参数传递给被调用的命令.您可以使用@splatting运算符传递传递给命令的所有参数.例如,如果

Start-Service -Name ServiceAbc @PSBoundParameters

在您的脚本的主体中,powershell会将传递给您的脚本的所有参数传递给Start-Service命令.唯一的问题是,如果你的脚本包含一个-Name参数,它也会被传递,PowerShell会抱怨你包含-Name参数两次.我编写了以下函数将所有常用参数复制到一个新字典然后我splat它.

function Select-BoundCommonParameters
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        $BoundParameters
    )
    begin
    {
        $boundCommonParameters = New-Object -TypeName 'System.Collections.Generic.Dictionary[string, [Object]]'
    }
    process
    {
        $BoundParameters.GetEnumerator() |
            Where-Object { $_.Key -match 'Debug|ErrorAction|ErrorVariable|WarningAction|WarningVariable|Verbose' } |
            ForEach-Object { $boundCommonParameters.Add($_.Key, $_.Value) }

        $boundCommonParameters
    }
}
Run Code Online (Sandbox Code Playgroud)

最终结果是将-Verbose之类的参数传递给脚本中调用的命令,并且它们符合调用者的意图.