【问题标题】:Enum parameter for powershell cmdletpowershell cmdlet 的枚举参数
【发布时间】:2020-10-12 03:31:47
【问题描述】:

我正在 powershell 上编写一个 cmdlet(脚本),我想使用 eunm 作为参数之一。但我不知道将枚举定义放在哪里,以便对 cmdlet 参数声明可见。

例如,我有一个像这样的脚本的参数定义

[cmdletbinding()]
param(
    [Parameter(Mandatory=$True)]
    [string]$Level
)

还有一个像这样的枚举

enum LevelEnum { NC = 1; NML = 2; CS = 3 }

我无法在参数定义中将[string] 替换为[LevelEnum],因为脚本将无法定位枚举定义。我不能把定义放在cmdletbinding 之前,这是不允许的。 如果这是一个函数,我知道该怎么做,我知道可以使用ValidateSet 解决它,但我需要有与枚举选项相对应的整数值。

[ValidateSet('NC','NML','CS')]

但问题是,我可以对 cmdlet 做同样的事情吗?


感谢大家。 我最终得到了不同答案的组合。

[cmdletbinding()]
param(
    [Parameter(Mandatory=$True)]
    [ValidateSet('NC','NML','CS')]
    [string]$Level
)
# Convert level from string to enum
enum PatchLevel { NC = 1; NML = 2; CS = 3 }
[PatchLevel]$l = $Level

# Use the numeric value
Write-Host $l.value__

【问题讨论】:

标签: powershell cmdlets cmdlet


【解决方案1】:

我会尝试这样的事情:

下面我创建了一个带有 LevelEnum 定义的普通 PSM1 文件。

enum LevelEnum{
  High
  Medium
  Low
}

之后,我使用using module 和 PSM1 文件的路径。

using module C:\Users\Path\To\Module\testmodule.psm1

function Get-Verb {
    [CmdletBinding()]
    param (
        [LevelEnum]$b
    )
    Write-Host $b
}

我使用了这个 microsoft 文档,About_Using,并且我还运行了 7.0.2 版。

【讨论】:

    【解决方案2】:

    如果此脚本需要接受自定义枚举,则意味着您将从其他地方调用它,其中枚举定义已经存在。现在您正尝试在脚本中再次添加相同的定义。根据@Alex_P 的建议将其推送到模块中是个好主意,这样定义就在一个地方,但缺点是Import-Module#Requires 不会导入它,因此需要using module子句。

    但是,如果您愿意接受更简单且安全性较低的解决方案,则可以利用您定义的任何枚举都派生自 System.Enum 的事实。 [System.Enum]$Level 将只接受所有枚举,如果不是 LevelEnum,脚本将中断,但它仍然会在脚本执行之前过滤大多数可能的错误并提供有关参数类型的一些信息。

    【讨论】:

    • 感谢所有回复的人。虽然大多数赞成的答案在技术上是最正确的,但这个答案实际上让我得出结论,我的方法和我的问题是错误的。所以我会将此标记为已接受。
    【解决方案3】:

    与 PowerShell 语法的所有其他部分不同,类型定义(和 using 语句)在解析时间发出,您可以通过放置 enum 定义来利用这一点在依赖它的脚本或函数中(尽管它可能看起来违反直觉):

    [cmdletbinding()]
    param(
        [Parameter(Mandatory=$True)]
        [LevelEnum]$Level
    )
    
    begin {
    enum LevelEnum { NC = 1; NML = 2; CS = 3 }
    }
    
    end {
     # rest of your script goes here
    }
    

    【讨论】:

    • 我将它完全复制到文件 test.ps1 中,并尝试运行 .\test.ps1 NC。我在 Powershell 5 和 7 中都得到了Unable to find type [LevelEnum].。有什么我可能错过的吗?它是否仅适用于某些 Powershell 版本?
    【解决方案4】:
    [cmdletbinding()]
    param(
        [ArgumentCompleter({
            enum LevelEnum { NC = 1; NML = 2; CS = 3 }
            [LevelEnum].GetEnumValues()
        })]
        [ValidateScript({
            enum LevelEnum { NC = 1; NML = 2; CS = 3 }
            [LevelEnum]$_
        })]
        $Level
    )
    
    enum LevelEnum { NC = 1; NML = 2; CS = 3 }
    [LevelEnum]$Level
    

    这行得通,但我敢肯定人们很容易忘记编辑所有枚举定义...

    【讨论】:

      猜你喜欢
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      相关资源
      最近更新 更多