【发布时间】:2014-08-30 04:53:25
【问题描述】:
我正在尝试接受用户输入,在继续之前,我希望在屏幕上收到一条消息,而不是确认用户是否要继续。我正在使用以下代码,但它不起作用:
write-host "Are you Sure You Want To Proceed:" -Confirm
【问题讨论】:
标签: powershell
我正在尝试接受用户输入,在继续之前,我希望在屏幕上收到一条消息,而不是确认用户是否要继续。我正在使用以下代码,但它不起作用:
write-host "Are you Sure You Want To Proceed:" -Confirm
【问题讨论】:
标签: powershell
-Confirm 是大多数 PowerShell cmdlet 中的一个开关,它强制 cmdlet 要求用户确认。你真正要找的是Read-Host cmdlet:
$confirmation = Read-Host "Are you Sure You Want To Proceed:"
if ($confirmation -eq 'y') {
# proceed
}
或主机用户界面的PromptForChoice()方法:
$title = 'something'
$question = 'Are you sure you want to proceed?'
$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'))
$decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
if ($decision -eq 0) {
Write-Host 'confirmed'
} else {
Write-Host 'cancelled'
}
编辑:
正如 M-pixel 在 cmets 中指出的那样,代码可以进一步简化,因为选择可以作为简单的字符串数组传递。
$title = 'something'
$question = 'Are you sure you want to proceed?'
$choices = '&Yes', '&No'
$decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
if ($decision -eq 0) {
Write-Host 'confirmed'
} else {
Write-Host 'cancelled'
}
【讨论】:
$decision = $Host.UI.PromptForChoice('something', 'Are you sure you want to proceed?', @('&Yes'; '&No'), 1)
$message 是弹出窗口的标题。因此,您确实需要保持简短,并将整个消息(包括问题)放入$question 变量中。 ($message 真的应该重命名为$title)。
这是一个简单的循环,除非用户选择'y'或'n',否则会一直提示
$confirmation = Read-Host "Ready? [y/n]"
while($confirmation -ne "y")
{
if ($confirmation -eq 'n') {exit}
$confirmation = Read-Host "Ready? [y/n]"
}
【讨论】:
break 将正确退出 while 循环,而不是 exit!它确实取决于上下文:break vs exit vs return@dallyack
read-host进行确认,也不要使用exit转break。
exit 而不是break。
do { $yn = Read-Host "Ready? [y/n]"; if ($yn-eq 'n') {exit}; } while($yn -ne "y")
Read-Host 是 -Confirm 对它没有影响的 cmdlet 的一个示例。-Confirm 是 PowerShell 的常用参数之一,特别是在 cmdlet 即将进行更改时使用的风险缓解参数到 Windows PowerShell 环境之外的系统。许多但不是所有 cmdlet 都支持 -Confirm 风险缓解参数。
以下是使用Read-Host cmdlet 和正则表达式测试来获得用户确认的示例:
$reply = Read-Host -Prompt "Continue?[y/n]"
if ( $reply -match "[yY]" ) {
# Highway to the danger zone
}
Remove-Variable cmdlet 是一个说明-confirm 开关用法的示例。
Remove-Variable 'reply' -Confirm
其他参考:CommonParameters、Write-Host、Read-Host、Comparison Operators、Regular Expressions、Remove-Variable
【讨论】:
-eq 不区分大小写。 $reply -eq 'y' 就足够了。
write-host 没有-confirm 参数。
你可以这样做:
$caption = "Please Confirm"
$message = "Are you Sure You Want To Proceed:"
[int]$defaultChoice = 0
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Do the job."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Do not do the job."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$choiceRTN = $host.ui.PromptForChoice($caption,$message, $options,$defaultChoice)
if ( $choiceRTN -ne 1 )
{
"Your Choice was Yes"
}
else
{
"Your Choice was NO"
}
【讨论】:
这里是来自 Microsoft 的 documentation,关于如何在 cmdlet 中请求确认。这些示例使用 C# 编写,但您也可以执行 PowerShell 中显示的所有操作。
首先将CmdletBinding 属性添加到您的函数中,并将SupportsShouldProcess 设置为true。然后可以引用$PSCmdlet变量的ShouldProcess和ShouldContinue方法。
这是一个例子:
function Start-Work {
<#
.SYNOPSIS Does some work
.PARAMETER Force
Perform the operation without prompting for confirmation
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param(
# This switch allows the user to override the prompt for confirmation
[switch]$Force
)
begin { }
process {
if ($PSCmdlet.ShouldProcess('Target')) {
if (-not ($Force -or $PSCmdlet.ShouldContinue('Do you want to continue?', 'Caption'))) {
return # user replied no
}
# Do work
}
}
end { }
}
【讨论】:
# Do work 的位置缺少右括号 (})。
ShouldProcess 条件没有右括号,但也许这是一种奇怪的格式,这就是我说我认为的原因
当你想要一个 1-liner
while( -not ( ($choice= (Read-Host "May I continue?")) -match "y|n")){ "Y or N ?"}
【讨论】:
The Read-Host cmdlet reads a line of input from the console. You can use it to prompt a user for input? -- docs.microsoft.com/en-us/powershell/module/…
Write-Warning "This is only a test warning." -WarningAction Inquire
【讨论】:
这是我使用过的解决方案,类似于 Ansgar Wiechers 的解决方案;
$title = "Lorem"
$message = "Ipsum"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "This means Yes"
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "This means No"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $Options, 0)
Switch ($result)
{
0 { "You just said Yes" }
1 { "You just said No" }
}
【讨论】:
$result 不会是 0 或 1。
基于Ansgar Wiechers's answer 的稍微漂亮的函数。它是否真的更有用是一个争论的问题。
function Read-Choice(
[Parameter(Mandatory)][string]$Message,
[Parameter(Mandatory)][string[]]$Choices,
[Parameter(Mandatory)][string]$DefaultChoice,
[Parameter()][string]$Question='Are you sure you want to proceed?'
) {
$defaultIndex = $Choices.IndexOf($DefaultChoice)
if ($defaultIndex -lt 0) {
throw "$DefaultChoice not found in choices"
}
$choiceObj = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
foreach($c in $Choices) {
$choiceObj.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList $c))
}
$decision = $Host.UI.PromptForChoice($Message, $Question, $choiceObj, $defaultIndex)
return $Choices[$decision]
}
示例用法:
PS> $r = Read-Choice 'DANGER!!!!!!' '&apple','&blah','&car' '&blah'
DANGER!!!!!!
Are you sure you want to proceed?
[A] apple [B] blah [C] car [?] Help (default is "B"): c
PS> switch($r) { '&car' { Write-host 'caaaaars!!!!' } '&blah' { Write-Host "It's a blah day" } '&apple' { Write-Host "I'd like to eat some apples!" } }
caaaaars!!!!
【讨论】:
我更喜欢弹出窗口。
$shell = new-object -comobject "WScript.Shell"
$choice = $shell.popup("Insert question here",0,"Popup window title",4+32)
如果 $choice 等于 6,答案是肯定的 如果 $choice 等于 7,则答案是否定的
【讨论】: