gpt4 book ai didi

powershell - $PSCmdlet.ShouldProcess 状态在调用之间存储在哪里(以及如何重置)?

转载 作者:行者123 更新时间:2023-12-03 12:22:59 29 4
gpt4 key购买 nike

考虑以下人为的示例:

function Test-ProcessContinue {
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')]
Param()

for ($i = 1; $i -le 3; $i++) {
if ($PSCmdlet.ShouldProcess("$i", "Process")) {
Write-Output "Processing $i"
}
else {
Write-Verbose "No chosen"
}
}

for ($i = 1; $i -le 3; $i++) {
if ($PSCmdlet.ShouldProcess("$i", "Process")) {
Write-Output "Processing $i"
}
else {
Write-Verbose "No chosen"
}
}

$yta = $false; $nta = $false
for ($i = 1; $i -le 3; $i++) {
if ($PSCmdlet.ShouldContinue("$i", "Continue", [ref]$yta, [ref]$nta) -or $yta) {
Write-Output "Continuing with $i"
}
elseif ($nta) {
Write-Verbose "No to all chosen"
break
}
else {
Write-Verbose "No chosen"
}
}
}

...及其潜在输出之一:

PS C:\> Test-ProcessContinue -Verbose

Confirm
Are you sure you want to perform this action?
Performing the operation "Process" on target "1".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): a
Processing 1
Processing 2
Processing 3
Processing 1
Processing 2
Processing 3

Continue
1
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): a
Continuing with 1
Continuing with 2
Continuing with 3

ShouldContinue 循环(第三个 for 循环)的情况下,我可以看到带有两个按引用 bool 参数的重载负责存储是否最终用户在这两个 bool 值中选择了Yes to AllNo to All

但是,对于两个 ShouldProcess block (前两个 for 循环),这个状态是如何保存的?

特别是,在前两个 ShouldProcess block 之间,我如何检查是否指定了Yes to AllNo to All 并且/或者我需要重置或清除什么才能使第二个 ShouldProcess block 再次请求确认?

(支持 ShouldContinue 而不是 ShouldProcess 是细粒度控制的选项,但它似乎失去了 native /内置支持对于 [CmdletBinding(SupportsShouldProcess=$true)]

最佳答案

首先,我将介绍 $PSCmdlet.ShouldContinue。这基本上是一种自己提示的方式,无论确认首选项如何。

$PSCmdlet.ShouldProcess 另一方面,并​​不总是提示。它考虑了 ConfirmImpact(您设置为 High)和 $ConfirmPreference 自动变量,默认为 High。有效值为 NoneLowMediumHigh,用于指示影响程度有变化,所以当 $ConfirmPreference 的值等于或小于命令的 ConfirmImpact 值时,ShouldProcess 将提示。

我知道这不是您的直接问题,但背景对于回答您应该做什么很重要。

直接问题:“答案存储在哪里?”有一个无聊的答案:it's stored in an internal variable in the class that defines the ShouldProcess method .

所以,不,不幸的是,你不能自己得到它。

但这让我们回到了 .ShouldContinue,它可以获取这些引用并为您存储这些值,因此当您需要这些值并希望能够使用它们做出决定时,您应该使用 .ShouldContinue

但是,你真的应该同时使用两者。因为他们做的事情不同。

.ShouldProcess不仅负责确认提示,还负责处理-WhatIf/$WhatIfPreference;当您说您的命令 SupportsShouldProcess 时,您也表示它支持 -WhatIf。如果您不使用 .ShouldProcess,您将遇到这样一种情况:命令看似安全,但实际上无论如何都会执行操作。

所以像这样的模式将覆盖你的基地:

if ($PSCmdet.ShouldProcess('thing', 'do')) {
if ($PSCmdlet.ShouldContinue('prompt')) {
# do it
}
}

这个问题可以追溯到您确认的影响和偏好。如果这些排队,或者如果用户使用 -Confirm 调用您的命令,您将提示两次:一次在 .ShouldProcess 中,然后在 中再次提示.ShouldContinue.

不幸的是,这种情况很糟糕。

我写了一个似乎可以解决这个问题的东西。它首先基于一个函数,该函数允许您在确认后运行任意脚本 block ,这样您仍然可以运行 .ShouldProcess,同时抑制其提示。

然后它还会尝试计算是否需要提示,然后有选择地调用.ShouldContinue。我没有演示存储或重置 yesToAll 和 noToAll 变量,因为您已经知道该怎么做。

这主要是为了演示可用于遵守标准确认提示语义的模式,具有可发现性,支持 -Confirm 参数,$ConfirmPreference,以及ConfirmImpact,同时保持对-Verbose-WhatIf 的支持。

function Test-Should {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
param()

Begin {
$local:ShouldConfirm = $ConfirmPreference -ne [System.Management.Automation.ConfirmImpact]::None -and
$ConfirmPreference -le [System.Management.Automation.ConfirmImpact]::High # hard coded :(

function Invoke-CommandWithConfirmation {
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory)]
[ScriptBlock]
$ScriptBlock
)

Invoke-Command -NoNewScope -ScriptBlock $ScriptBlock
}
}

Process {
if (Invoke-CommandWithConfirmation -ScriptBlock { $PSCmdlet.ShouldProcess('target', 'action') } -Confirm:$false ) {
if (-not $local:ShouldConfirm -or $PSCmdlet.ShouldContinue('query', 'caption')) {
'Hi' | Write-Host
'Hello' | Write-Verbose
}
}
}
}

调用:

Test-Should
Test-Should -Confirm
Test-Should -Confirm:$false
Test-Should -Verbose
Test-Should -Verbose -WhatIf
Test-Should -WhatIf -Confirm
Test-Should -WhatIf -Confirm:$false

以此类推,$ConfirmPreference 的值不同,命令的ConfirmImpact 的值也不同。

令人讨厌的一件事是我标记为硬编码的值:它必须与您设置为该命令的确认影响相匹配。

It turns out it's kind of a pain in the ass to get at that value programmatically ,但也许您可以通过某种方式解决这个问题。

关于powershell - $PSCmdlet.ShouldProcess 状态在调用之间存储在哪里(以及如何重置)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56486821/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com