2016-10-24 41 views
1

我想了解在Powershell cmdlet中$?$lastexitcode变量与-Confirm标志之间的关系。在PowerShell中使用-Co​​nfirm

说,例如,您运行-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 

据我所知,技术上的命令成功运行,但如果用户选择了不那么该命令没有运行。

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

回答

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" 
} 

希望有所帮助。

+0

感谢您的快速回复和解决方法。 :) –

2

$?,$LastExitCode-Confirm彼此完全无关。

$?是一个automatic variable与布尔值指示是否最后(PowerShell)操作已成功执行。

$LastExitCode是一个automatic 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 
}