2016-10-24 45 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 
}