2

这里有很多关于 SO 和其他地方的问题,解释了如何在-Confirm整个 cmdlet 中传播到嵌套的 cmdlet 等。但是,我没有找到的是如何传播对该提示的响应。也就是说,一旦用户回答了这个提示......

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

...人们会合理地假设我的 cmdlet 现在可以根据用户对该提示的响应采取行动。这在一定程度上肯定是正确的:两者Suspend [S]都是Help [?]本地化操作,并且工作正常。

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

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

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

事实上,到目前为止,我发现的唯一可能的解决方法是Jeffrey Snover 的早期版本(大约 2007 年!)PowerShell 的 Should-Process 函数,大概在“官方”之前Cmdlet.ShouldProcess并被$PSCmdlet.ShouldProcess引入。

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

所以我的简短问题是:对于编译的 cmdlet 和脚本化的 cmdlet,我如何区分YesfromYes to AllNofrom No to All

4

1 回答 1

3

我相信该Yes to all选项的意思是说“是的,对我当前正在处理的所有项目执行此操作”,而不是“是的,尽可能执行所有操作并且不要再问我”。测试这一点的一种方法是将数组传递给支持 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

假设我们在每个提示上都回答“是的”,我们将得到以下输出:

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

请注意,它会询问一次“对其进行处理”,然后再询问一次“对其进行内部处理”。紧接着内部函数执行后的下一行是外部函数对数组中第二项的输出,_没有提示,因为我们回答“全部是”。第二个项目的外部函数再次将内部函数调用为单个项目调用,因此 PowerShell 再次提示用户。

PowerShell 再次提示的原因是这是处理一组新数据的新指令。因此,只要它是处理数据列表的相同指令,“全部同意”就不会再次询问列表中的后续项目,但对于新指令或新数据,它应该再次询问。

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

于 2014-04-13T02:34:17.573 回答