Поддержка Whatif и подтверждение ответов

В SO и других местах есть множество вопросов, объясняющих, как распространять -Confirm от одного командлета до вложенных командлетов и т. д. Однако я не нахожу, как распространить ответ на это приглашение. То есть, когда пользователь отвечает на это приглашение...

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

... можно было бы разумно предположить, что мой командлет теперь может влиять на ответ пользователя на это приглашение. Это, безусловно, верно отчасти: оба Suspend [S] а также Help [?] локализованные операции, и те работают нормально.

Но моя главная проблема заключается в признании и действии Yes to All а также No to All, В обоих C# (через Cmdlet.ShouldProcess()) и PowerShell (через $PSCmdlet.ShouldProcess()) можно получить только логический результат, из которого я могу только догадываться:

  • true это либо [Y], либо [A].
  • false это либо [N], либо [L].

Сначала я надеялся, что, хотя и не задокументировано, так сказать, ShouldContinue будет использовать внутреннее состояние командлета, чтобы сделать это различие, но эксперименты с командлетами со сценарием показали, что это не так.

Фактически, единственный возможный обходной путь, который я нашел таким образом, - это раннее исполнение Джеффри Сновером (около 2007 года!) Функции "должен обработать" для PowerShell, предположительно до "официального" Cmdlet.ShouldProcess а также $PSCmdlet.ShouldProcess были введены.

Мне трудно поверить, что команда PowerShell забыла разрешить различать Да / Да для всех и Нет / Нет для всех; скорее, я предполагаю, что просто упускаю это из виду.

Итак, мой вопрос в краткой форме: как различить скомпилированные командлеты и командлеты со скриптами Yes от Yes to All а также No от No to All?

1 ответ

Я верю Yes to all Параметр option означает "Да, выполнить эту операцию для всех элементов, над которыми я сейчас работаю", а не "Да, выполнить каждую возможную операцию и не спрашивать меня снова". Один из способов проверить это - передать массив в функцию, которая поддерживает mustProcess, который внутренне вызывает внутреннюю функцию (которая также поддерживает ShouldProcess) с одним элементом за раз. Вы увидите, что, по крайней мере, в PowerShell v4.0 на моем компьютере с Win 8.1 внешняя функция, к которой я передал массив, не запрашивает другие элементы в массиве. Однако внутренняя функция, которая вызывается много раз, а не вызывается один раз с массивом для ввода, будет запрашивать один раз каждый раз, когда она вызывается.

Мы можем проверить это поведение, используя следующую функцию и внутреннюю функцию:

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 переключатель.

Другие вопросы по тегам