支持Whatif并确认回复

时间:2014-04-12 23:12:49

标签: c# powershell cmdlet pscmdlet

这里有太多问题在SO和其他地方解释如何将-Confirm传播到一个cmdlet到嵌套cmdlet等等。然而,我找不到的是如何传播响应< / em>到那个提示。也就是说,一旦用户回答此提示......

[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):

...可以合理地假设我的cmdlet现在可以对用户对该提示的响应执行。这当然是正确的:Suspend [S]Help [?]都是本地化的操作,而且这些操作正常。

但我的主要问题是识别Yes to AllNo to All并采取行动。 在C#(通过Cmdlet.ShouldProcess())和PowerShell(通过$PSCmdlet.ShouldProcess())中,只能得到一个我只能猜测的布尔结果:

  • true是[Y]或[A]。
  • false是[N]或[L]。

我最初希望虽然没有记录这样说,ShouldContinue会利用内部cmdlet状态来区分,但使用脚本cmdlet的实验表明情况并非如此。

事实上,我发现的唯一可能的解决方法是Jeffrey Snover's early rendition(大约2007年!)PowerShell的一个应该处理函数,大概是在“官方”Cmdlet.ShouldProcess和{{1}之前介绍了。

我发现很难相信PowerShell团队忘记区分Yes / Yes to All和No / No to All;相反,我认为我只是在忽视它。

所以我的简短形式的问题是:对于已编译的cmdlet和脚本化cmdlet,我如何区分$PSCmdlet.ShouldProcessYesYes to All与{{} 1}}?

1 个答案:

答案 0 :(得分:3)

我相信Yes to all选项意味着说&#34;是的,对我目前正在处理的所有项目执行此操作&#34;而不是&#34;是的,执行每项操作可能,不要再问我了#34;测试这种方法的一种方法是将数组传递给一个支持ShouldProcess的函数,该函数一次内部调用一个内部函数(也支持ShouldProcess)。你会看到,至少在我的Win 8.1机器上的PowerShell v4.0上,我用数据管道输出的外部函数不会要求数组中的其他项目。但是,内部函数被多次调用,而不是被一个数组用于输入调用一次,每次调用它时都会询问一次。

我们可以使用以下函数和内部函数来测试此行为:

function Test-ShouldProcess
{
    [CmdletBinding(SupportsShouldProcess = $true)]
    PARAM (
        [Parameter(ValueFromPipeline = $true)]
        $InputObject
    )

    PROCESS
    {
        if ($PSCmdlet.ShouldProcess($InputObject, "Do stuff to it"))
        {
            Write-Host "Doing stuff to $InputObject"
            Test-ShouldProcess_InnerFunc -InputObject $InputObject
        }
    }
}

function Test-ShouldProcess_InnerFunc
{
    [CmdletBinding(SupportsShouldProcess = $true)]
    PARAM (
        [Parameter(ValueFromPipeline = $true)]
        $InputObject
    )

    PROCESS
    {
        if ($PSCmdlet.ShouldProcess($InputObject, "Do internal stuff to it"))
        {
            Write-Host "Doing internal stuff to $InputObject"
        }
    }
}

如果我们通过将数组传递给函数来调用外部函数,如下所示:

"item1", "item2" | Test-ShouldProcess -Confirm

鉴于我们对所有人做出回应,并且#34;在每个提示中,我们都会得到以下输出:

Confirm
Are you sure you want to perform this action?
Performing the operation "Do stuff to it" on target "item1".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): A
Doing stuff to item1

Confirm
Are you sure you want to perform this action?
Performing the operation "Do internal stuff to it" on target "item1".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): A
Doing internal stuff to item1
Doing stuff to item2

Confirm
Are you sure you want to perform this action?
Performing the operation "Do internal stuff to it" on target "item2".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): A
Doing internal stuff to item2

注意它要求一次&#34;做东西给它&#34;然后一次为&#34;做内部事情&#34;。在内部函数执行之后的下一行是来自数组中第二项的外部函数的输出,_不提示,因为我们回答“#34;是”所有&#34;。第二项的外部函数再次将内部函数调用为单项调用,因此PowerShell再次提示用户。

PowerShell再次提示的原因是这是处理新数据集的新指令。因此,只要它是在数据列表上工作的相同指令,那么对所有人来说都是&#34;不再要求列表中的后续项目,但是对于新指令或新的数据,它应该再次询问。

如果用户根本不希望提示确认,则用户不应使用-Confirm开关,甚至可能更改ConfirmPreference设置或使用-Force开关