在Powershell中使用-Co​​nfirm

时间:2016-10-24 18:46:32

标签: powershell

我试图了解$?$lastexitcode变量与Powershell cmdlet中-Confirm标志之间的关系。

例如,假设您使用-confirm运行命令,它会相应地提示您采取措施:

PS C:\temp> rm .\foo.txt -confirm
Confirm

Are you sure you want to perform this action?

Performing the operation "Remove Directory" on target "C:\temp\foo.txt".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is "Y"):n

PS C:\temp> $?

True

我理解技术上命令运行成功,但如果用户选择no,则命令不会运行。

我的问题是如何获取用户对-Confirm标志的回答?

2 个答案:

答案 0 :(得分:2)

$?$LastExitCode-Confirm完全无关。

$?是一个automatic variable,其布尔值表示最后一次(PowerShell)操作是否成功执行。

$LastExitCodeautomatic variable,其中包含上次执行的外部命令的退出代码(整数值)。

-Confirm是一个common parameter,用于控制cmdlet是否提示用户确认其操作。

据我所知,PowerShell不会在任何地方存储-Confirm提示的答案,因此如果您需要其他内容的响应,则必须prompt the user yourself,例如像这样:

function Read-Confirmation {
  Param(
    [Parameter(Mandatory=$false)]
    [string]$Prompt,
    [Parameter(Mandatory=$false)]
    [string]$Message
  )

  $choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
  $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes'))
  $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&No'))

  -not [bool]$Host.UI.PromptForChoice($Message, $Prompt, $choices, 1)
}

$doRemove = if ($PSBoundParameters['Confirm'].IsPresent) {
  Read-Confirmation -Prompt 'Really delete'
} else {
  $true
}

if ($doRemove) {
  Remove-Item .\foo.txt -Force
}

答案 1 :(得分:0)

AFAIK,无法捕获用户对确认提示的回复;它不是PowerShell的命令历史记录的一部分,虽然您可能以某种方式从缓冲区获取信息,但只有默认的PowerShell主机才支持,因为其他主机将使用不同的缓冲区。在这种情况下,最好使用if语句在脚本中单独进行确认。

$userAnswer = Read-Host "Are you sure you wish to proceed?"
if($userAnswer -eq "yes"){
    rm .\foo.txt
}    

然后只需使用$ userAnswer变量即可知道用户的响应内容。或者,您可以通过检查操作是否已完成来确定其答案。这将是我首选的方法,因为您确定该文件已被删除而不是假设,因为cmdlet已成功执行并且用户已确认(考虑到remove-item的测试结果令人难以置信,但可靠性可能没有任何不同如果你使用某种类型的第三方库,它可能会有所作为,如下所示。

rm .\foo.txt -Confirm

if(Test-Path .\foo.txt){
    $success = $false
} else {
    $success = $true
}

如果您确实需要知道是否由于错误而无法删除,或者用户拒绝您可以执行类似

的操作
rm .\foo.txt -Confirm


if(Test-Path .\foo.txt){
    $success = $false
} else {
    $success = $true
}

if(!($success) -and (!($?))){
    $status = "Previous command failed"
} elseif (!($success) -and $?){
    $status = "User cancelled operation"
} 

希望有所帮助。