当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 如何构建 PowerShell 菜单

作者:精品下载站 日期:2024-12-14 20:48:35 浏览:15 分类:玩电脑

如何构建 PowerShell 菜单


尽管 PowerShell 是一种功能强大的自动化脚本语言,但您还可以用它构建一些很酷的基于控制台的脚本。构建交互式菜单就是一个很好的例子。在这篇文章中,我们将深入介绍如何与 PowerShell 进行交互以及如何创建简单的 PowerShell 菜单的分步教程。

良好的 PowerShell 自动化脚本通常不需要交互性。毕竟,如果脚本是交互式的,则意味着必须有人在脚本前面才能按下按键。我们试图通过提前定义所有场景并在运行时将参数输入到我们的脚本中而不进行交互来避免这种情况。然而,有时我们需要收集无法提前定义场景的输入,或者我们正在为最终用户构建脚本。

PowerShell 有几种方法可以将交互性引入脚本中。今天,我们将讨论其中两个;使用 Read-Host 命令并使用 .NET System.Management.Automation.Host.ChoiceDescription 对象创建我们自己的自定义选择菜单。

读取主机

在脚本中添加交互性的最常见和最简单的方法是使用内置的 Read-Host 命令。此命令会暂停脚本(无论其位于何处)并等待某种输入。默认情况下,它只会停止代码执行,除了闪烁提示之外不会指示发生了什么,因此使用 Prompt 参数非常重要,该参数在提示输入之前显示一些文本。

PS C:\> Read-Host
Red
Red

当给出输入时,它会返回该输入。上面,我输入了 Red 作为输入,并返回了 Red。如果我们不以某种方式捕获该输入并据此做出决策,那么这并没有多大好处。我们最好将该输出发送到变量。此时,我们可以针对提供的输入执行一系列检查。

PS> $favColor = Read-Host -Prompt 'What is your favorite color?'
What is your favorite color?: Red
PS> $favColor
Red

现在您可以看到,Red 并不是简单地返回到控制台,而是被 $favColor 变量捕获。此时,我们可以在其中添加一些逻辑来根据该输入执行不同的操作。

if ($favColor -eq 'Red') {
    'My favorite, too!'
} else {
    "Eww..$favColor is not a nice color!"
}
My favorite, too!

使用 .NET 创建 Powershell 菜单

Read-Host 用途广泛,可以提示输入任何类型的文本,但它看起来并不真正“官方”。它看起来不像是 PowerShell 本身的一部分。对于请求输入(多个输入)的更专业的方式,我们可以使用 .NET System.Management.Automation.Host.ChoiceDescription 对象。该对象允许我们定义不同的选项,然后使用名为 PromptForChoice() 的 .NET 方法向用户显示这些选项。

这种请求输入的方法需要提前定义所有选项,方法是创建多个 System.Management.Automation.Host.ChoiceDescription .NET 对象,然后将这些对象传递给另一个显示它们的 .NET 对象到控制台要求用户选择。

显示选项的 .NET 方法是调用 $host.ui.PromptForChoice()。该方法需要四个参数才能运行;选项菜单的标题、要显示的消息、System.Management.Automation.Host.ChoiceDescription 对象数组以及用户只需按 Enter 键时默认的选择。

定义 Powershell 菜单选项

首先,我们将定义所有选项。使用前面的示例,让我们将最喜欢的颜色数量限制为红色、蓝色和黄色。为此,我们必须创建三个对象,每个对象代表一个选择。

$red = New-Object System.Management.Automation.Host.ChoiceDescription '&Red', 'Favorite color: Red'
$blue = New-Object System.Management.Automation.Host.ChoiceDescription '&Blue', 'Favorite color: Blue'
$yellow = New-Object System.Management.Automation.Host.ChoiceDescription '&Yellow', 'Favorite color: Yellow'

定义完所有选项后,我们会将它们全部分组到一个数组中。

$options = [System.Management.Automation.Host.ChoiceDescription[]]($red, $blue, $yellow)

最后,我们将首先定义提示标题和消息向用户显示它们。

$title = 'Favorite color'
$message = 'What is your favorite color?'
$result = $host.ui.PromptForChoice($title, $message, $options, 0)

运行后,您将看到一个提示,看起来像是来自 PowerShell 本身。

Favorite color
What is your favorite color?
[R] Red  [B] Blue  [Y] Yellow  [?] Help (default is "R"):

$result 的值不是指定的文本;它是一个从 0 开始的索引号,因此,例如,如果您选择红色,则结果将为 0,或者如果选择黄色,则值将为 2。您可以通过使用 switch 语句根据以下条件做出决定来进行区分:您提供的输入。

switch ($result)
{
    0 { 'Your favorite color is Red' }
    1 { 'Your favorite color is Blue' }
    2 { 'Your favorite color is Yellow' }
}

一旦您的代码位于 switch 语句中,您就可以创建一个方便的 PowerShell 函数,如下所示,以显示菜单并提示响应。请注意使用 using 关键字创建 [ChoiceDescription] 对象的快捷方式。感谢 Reddit 上的 twinlakkes 提供的提示。

using namespace System.Management.Automation.Host

function New-Menu {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Title,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Question
    )
    
    $red = [ChoiceDescription]::new('&Red', 'Favorite color: Red')
    $blue = [ChoiceDescription]::new('&Blue', 'Favorite color: Blue')
    $yellow = [ChoiceDescription]::new('&Yellow', 'Favorite color: Yellow')

    $options = [ChoiceDescription[]]($red, $blue, $yellow)

    $result = $host.ui.PromptForChoice($Title, $Question, $options, 0)

    switch ($result) {
        0 { 'Your favorite color is Red' }
        1 { 'Your favorite color is Blue' }
        2 { 'Your favorite color is Yellow' }
    }

}

一旦构建了该函数,您就可以通过调用 New-Menu 函数来动态构建菜单,如下所示。如果我是你,我也会将选项设置为参数,但我会将其留给你。

PS> New-Menu -Title 'Colors' -Question 'What is your favorite color?'

Colors
What is your favorite color?
[R] Red  [B] Blue  [Y] Yellow  [?] Help (default is "R"): B
Your favorite color is Blue

把它们放在一起

现在您已经掌握了创建菜单的所有知识,让我们将所有知识放在一起并创建一个保持交互式的交互式菜单!

创建一个名为 Show-Menu 的函数,如下所示。该菜单是静态的。

function Show-Menu {
    param (
        [string]$Title = 'My Menu'
    )
    Clear-Host
    Write-Host "================ $Title ================"
    
    Write-Host "1: Press '1' for this option."
    Write-Host "2: Press '2' for this option."
    Write-Host "3: Press '3' for this option."
    Write-Host "Q: Press 'Q' to quit."
}

Show-Menu 函数仅显示菜单。而已。

================ My Menu ================
1: Press '1' for this option.
2: Press '2' for this option.
3: Press '3' for this option.
Q: Press 'Q' to quit.

但是,您可以通过实现 do/until 循环使其成为实际的交互式菜单。使用 do/until 循环允许您对输入执行操作,并且如果用户想要选择多个选项, 可以保持菜单处于打开状态。

退出菜单的唯一方法是输入 Q。试试吧!

do
 {
    Show-Menu
    $selection = Read-Host "Please make a selection"
    switch ($selection)
    {
    '1' {
    'You chose option #1'
    } '2' {
    'You chose option #2'
    } '3' {
      'You chose option #3'
    }
    }
    pause
 }
 until ($selection -eq 'q')

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯