我们可以在PowerShell中使用一些东西来要求用户从一系列项目中选择一个项目吗?例如,我喜欢Inquirer.js如何做到这一点。
我也看过PoshGui,但创建一个简单的提示似乎太多了。
我们想要类似的东西的原因是我们需要为我们的客户提供部署脚本,并使部署指南尽可能简单。要求用户在屏幕上选择一个项目比要求他们在配置文件中插入一些guid要好得多。
您对数组的用户提示有什么建议吗?
我过去曾经使用过Out-GridView
cmdlet。当与-PassThru
开关一起使用时,它允许将所选项目传递给变量。您使用Out-GridView
编写的示例图像(ogv
,如果您想使用别名)是:
$task = Read-Host -Prompt "What do you want to do?"
if ($task -eq "Order a pizza") {
$pizza_sizes = @('Jumbo','Large','Standard','Medium','Small','Micro')
$size = $pizza_sizes | Out-GridView -Title "What size do you need?" -PassThru
Write-Host "You have selected $size"
}
考虑到这一点需要考虑很多因素,窗口可能不会出现在您希望的位置,也可能出现在其他窗口后面。此外,这是一个非常简单的示例,显然需要错误处理和内置的其他方面。我建议进行一些测试,或者从SO上获得其他人的第二意见。
你当然可以像你一样有创意。这是一个构建控制台菜单的小功能:
function Simple-Menu {
Param(
[Parameter(Position=0, Mandatory=$True)]
[string[]]$MenuItems,
[string] $Title
)
$header = $null
if (![string]::IsNullOrWhiteSpace($Title)) {
$len = [math]::Max(($MenuItems | Measure-Object -Maximum -Property Length).Maximum, $Title.Length)
$header = '{0}{1}{2}' -f $Title, [Environment]::NewLine, ('-' * $len)
}
# possible choices: didits 1 to 9, characters A to Z
$choices = (49..57) + (65..90) | ForEach-Object { [char]$_ }
$i = 0
$items = ($MenuItems | ForEach-Object { '[{0}] {1}' -f $choices[$i++], $_ }) -join [Environment]::NewLine
# display the menu and return the chosen option
while ($true) {
cls
if ($header) { Write-Host $header -ForegroundColor Yellow }
Write-Host $items
Write-Host
$answer = (Read-Host -Prompt 'Please make your choice').ToUpper()
$index = $choices.IndexOf($answer[0])
if ($index -ge 0 -and $index -lt $MenuItems.Count) {
return $MenuItems[$index]
}
else {
Write-Warning "Invalid choice.. Please try again."
Start-Sleep -Seconds 2
}
}
}
你可以像下面这样使用它:
$menu = 'Pizza', 'Steak', 'French Fries', 'Quit'
$eatThis = Simple-Menu -MenuItems $menu -Title "What would you like to eat?"
switch ($eatThis) {
'Pizza' {
$menu = 'Jumbo', 'Large', 'Standard', 'Medium', 'Small', 'Micro'
$eatThat = Simple-Menu -MenuItems $menu -Title "What size do you need?"
Write-Host "`r`nEnjoy your $eatThat $eatThis!`r`n" -ForegroundColor Green
}
'Steak' {
$menu = 'Well-done', 'Medium', 'Rare', 'Bloody', 'Raw'
$eatThat = Simple-Menu -MenuItems $menu -Title "How would you like it cooked?"
Write-Host "`r`nEnjoy your $eatThat $eatThis!`r`n" -ForegroundColor Green
}
'French fries' {
$menu = 'Mayonaise', 'Ketchup', 'Satay Sauce', 'Piccalilly'
$eatThat = Simple-Menu -MenuItems $menu -Title "What would you like on top?"
Write-Host "`r`nEnjoy your $eatThis with $eatThat!`r`n" -ForegroundColor Green
}
}
结果:
不幸的是,内置的内容很少,而且很难发现 - 见下文。
可能提供专用的Read-Choice
cmdlet或增强Read-Host
is being discussed on GitHub。
$host.ui.PromptForChoice()
方法支持提供一个选项菜单,但它有局限性:
?
选项。这是一个例子:
# The list of choices to present.
# Specfiying a selector char. explicitly is mandatory; preceded it by '&'.
# Automating that process while avoiding duplicates requires significantly
# more effort.
# If you wanted to include an explanation for each item, selectable with "?",
# you'd have to create each choice with something like:
# [System.Management.Automation.Host.ChoiceDescription]::new("&Jumbo", "16`" pie")
$choices = '&Jumbo', '&Large', '&Standard', '&Medium', 'Sma&ll', 'M&icro'
# Prompt the user, who must type a selector character and press ENTER.
# * Each choice label is preceded by its selector enclosed in [...]; e.g.,
# '&Jumbo' -> '[J] Jumbo'
# * The last argument - 0 here - specifies the default index.
# * The default choice selector is printed in *yellow*.
# * Use -1 to indicate that no default should be provided
# (preventing empty/blank input).
# * An invalid choice typed by the user causes the prompt to be
# redisplayed (without a warning or error message).
$index = $host.ui.PromptForChoice("Choose a Size", "Type an index and press ENTER:", $choices, 0)
"You chose: $($choices[$index] -replace '&')"
这产生如下:
所有的答案都是正确的,但我也写了几个可重复使用的PowerShell helper functions。 Readme。我自动生成基本的WinForms。看起来很丑,但很有效。
https://github.com/Zerg00s/powershell-forms
$selectedItem = Get-FormArrayItem (Get-ChildItem)
$Delete = Get-FormBinaryAnswer "Delete file?"
$newFileName = Get-FormStringInput "Enter new file name" -defaultValue "My new file"
# -------------------------------------------------------------------------------
# Prepare the list of inputs that user needs to populate using an interactive form
# -------------------------------------------------------------------------------
$preDeployInputs = @{
suffix = ""
SPSiteUrl = "https://ENTER_SHAREPOINT_SITE.sharepoint.com"
TimeZone = "Central Standard Time"
sendGridRegistrationEmail = "ENTER_VALID_EMAIL_ADDRESS"
sendGridRegistrationPassword = $sendGridPassword
sendGridRegistrationCompany = "Contoso & Tailspin"
sendGridRegistrationWebsite = "https://www.company.com"
fromEmail = "[email protected]"
}
$preDeployInputs = Get-FormItemProperties -item $preDeployInputs -dialogTitle "Fill these required fields"