You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell脚本菜单选择项追加字符串而非数组新条目问题

PowerShell菜单选项数组被意外转为字符串的问题解决

问题根源

你遇到的核心问题是PowerShell的自动类型拆箱行为:当使用Where-Object过滤数组时,如果过滤结果仅包含单个元素,PowerShell会自动将数组转换为单个字符串值,而非保留数组类型。后续再用+=添加元素时,会执行字符串拼接而非数组追加,最终出现"Option 1Option 3"这类错误结果。

举个例子:

  • 初始$choice是数组@("Option 1", "Option 2")
  • 删除其中一个选项后,过滤结果是单个字符串"Option 1",而非数组@("Option 1")
  • 此时再执行$choice += "Option 3",就会变成字符串拼接,得到"Option 1Option 3"

解决方案

方案1:强制保持数组类型

在每次使用Where-Object过滤后,用@()包裹结果,强制将输出转为数组类型,避免自动拆箱。修改所有删除选项的代码块:

# 原删除逻辑
$choice = $choice | Where-Object {$_ -ne "Option 1"}

# 修改后,强制转为数组
$choice = @($choice | Where-Object {$_ -ne "Option 1"})

方案2:使用ArrayList存储选择

改用System.Collections.ArrayList存储选中项,它不会触发自动拆箱,操作更稳定:

  • 初始化时替换数组声明:$choice = New-Object System.Collections.ArrayList
  • 添加元素用Add()方法:[void]$choice.Add("Option 1")([void]用于抑制Add方法返回的索引值)
  • 删除元素用Remove()方法:$choice.Remove("Option 1")

修改后的完整脚本(方案1版本)

# Set the initial choices
$choice = @()

# Use a while loop to keep the menu open until the user selects the "Exit" option
while ($true) {
    # Clear the screen
    Clear-Host

    # Use a foreach loop to display each menu option, including an asterisk on the selected options
    foreach ($option in "Option 1", "Option 2", "Option 3", "Option 0", "Exit") {
        if ($choice -contains $option) {
            Write-Host "$option *"
        } elseif ($option -eq "Option 0") {
            # "Option 0" is not a selectable option, so always display it as deselected
            Write-Host $option
        } else {
            Write-Host $option
        }
    }

    # Prompt the user to enter their selection
    $userInput = Read-Host "Enter your selection"

    # Use a switch statement to execute the selected options
    switch -regex ($userInput)
    {
        "0" {
            # Code for Option 0
            # Print the selected options and exit the script
            Write-Warning "Choices variable: $choice"
            Write-Host "Selected options: "
            switch ($choice) {
                "Option 1" { 
                    Write-Host "1"
                }
                "Option 2" {
                    Write-Host "2"
                }
                "Option 3" {
                    Write-Host "3"
                }
                default {
                    Write-Host "No selected options."
                }
            }
            # Return to exit the current iteration of the while loop
            return
        }
        "1" {
            # Code for Option 1
            # Check if the user has already selected this option
            if ($choice -contains "Option 1") {
                # Remove the option from the $choice variable, force array type
                $choice = @($choice | Where-Object {$_ -ne "Option 1"})
            } else {
                # Add the option to the $choice variable
                $choice += "Option 1"
            }
        }
        "2" {
            # Code for Option 2
            # Check if the user has already selected this option
            if ($choice -contains "Option 2") {
                # Remove the option from the $choice variable, force array type
                $choice = @($choice | Where-Object {$_ -ne "Option 2"})
            } else {
                # Add the option to the $choice variable
                $choice += "Option 2"
            }
        }
        "3" {
            # Code for Option 3
            # Check if the user has already selected this option
            if ($choice -contains "Option 3") {
                # Remove the option from the $choice variable, force array type
                $choice = @($choice | Where-Object {$_ -ne "Option 3"})
            } else {
                # Add the option to the $choice variable
                $choice += "Option 3"
            }
        }
        "4" {
            # Code for Exit
            # Break out of the while loop to end the script
            break
        }
        default {
            # Code for invalid selection or deselection
            # Check if the user has deselected an option
            if ($choice -contains $userInput) {
                # Remove the option from the $choice variable, force array type
                $choice = @($choice | Where-Object {$_ -ne $userInput})
            }   else {
                    # The user has entered an invalid selection
                    Write-Host "Invalid selection"
                }
        }
    }
}

内容的提问来源于stack exchange,提问作者SignalRaptor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:40:27