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