【问题标题】:Enum like switch parameter in PowerShellPowerShell中的类似开关参数的枚举
【发布时间】:2020-06-02 15:09:15
【问题描述】:

我正在以这种方式在我的 PowerShell 脚本中使用开关参数。

param(
    [switch] $Word,
    [switch] $Excel,
    [switch] $powerpoint,
    [switch] $v2007,
    [switch] $v2010,
    [switch] $x86,
    [switch] $x64,
)

我正在尝试找出任何巧妙的方法来让它更具枚举风格。 任何人都可能猜到,我希望用户在 word、excel 和 powerpoint 之间进行选择。 在 x2007 和 v2010 之间。

有没有一种简洁的方法来获取输入参数枚举样式?

我是 PowerShell 新手。因此,如果这听起来像我不知道一些明显的事情,那么请指向我可以阅读的一些链接。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    我会改用ValidateSet 参数属性。

    发件人:about_Functions_Advanced_Parameters

    ValidateSet 属性指定一组有效值 参数或变量。如果 Windows PowerShell 生成错误 参数或变量值与集合中的值不匹配。

    示例函数:

    function test-value
    {
        param(
            [Parameter(Position=0)]
            [ValidateSet('word','excel','powerpoint')]
            [System.String]$Application,
    
            [Parameter(Position=1)]
            [ValidateSet('v2007','v2010')]
            [System.String]$Version
        )
    
    
        write-host "Application: $Application"
        write-host "Version: $Version"
    }   
    
    
    PS > test-value -application foo
    

    输出:

    test-value : Cannot validate argument on parameter 'Application'. The argument "foo" does not belong to the set "word,excel,powerpoint" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.

    【讨论】:

    • 这种方法迫使您使用并非总是可取的高级功能。您也不会在枚举值上获得任何形式的自动完成。 OTOH,您不必将枚举评估放在括号中,例如[MyEnum]::A。所以,我猜是一个混合包。 :-)
    • 谢谢基思。另一方面,该函数需要执行各种参数检查以查找是否指定了多个开关参数。顺便说一句,我们不是都在使用 PowerShell v2 吗 :)
    • Keith,如果您使用 PowerTab,您会在 ValidateSet 上获得选项卡扩展...只是说。 ;)
    • 你现在确实可以扩展集合了(在 Windows 8.1 中测试,在 Powershell 3.0 和 4.0 中,但不是 2.0)
    【解决方案2】:

    你可以使用ValidateSet属性:

    function My-Func
    {
        param (
            [Parameter(Mandatory = $true)]
            [ValidateNotNullOrEmpty()]
            [ValidateSet('Word', 'Excel', 'PowerPoint', 'v2007', 'v2010', 'x86', 'x64')]
            [String]$MyParam
        )
    
        Write-Host "Performing action for $MyParam"
    }
    
    My-Func -MyParam 'Word'
    My-Func -MyParam 'v2007'
    My-Func -MyParam 'SomeVal'
    

    输出:

    Performing action for Word
    Performing action for v2007
    My-Func : Cannot validate argument on parameter 'MyParam'. The argument "SomeVal" does not belong to the set "Word,Excel,PowerPoint,v2007,v2010,x86,x64" specified by the ValidateSet attribute. Supply an argument that is in the
     set and then try the command again.
    At C:\Users\George\Documents\PowerShell V2\ValidateSetTest.ps1:15 char:17
    + My-Func -MyParam <<<<  'SomeVal'
        + CategoryInfo          : InvalidData: (:) [My-Func], ParameterBindingValidationException
        + FullyQualifiedErrorId : ParameterArgumentValidationError,My-Func
    

    【讨论】:

      【解决方案3】:

      blog post by the PowerShell team 定义了如何在 PowerShell 1.0 中执行此操作。在 PowerShell 2.0 中,您可以像这样使用 Add-Type:

      C:\PS> Add-Type -TypeDefinition @'
      >> public enum MyEnum {
      >> A,
      >> B,
      >> C,
      >> D
      >> }
      >> '@
      >>
      

      更新:以下是枚举的使用方法:

      C:\PS> function foo([MyEnum]$enum) { $enum }
      C:\PS> foo ([MyEnum]::A)
      A
      

      您需要参数周围的括号将参数解析为类型。这是必需的,因为参数或多或少被视为字符串。知道了这一点,您还可以将它们以简单的字符串形式枚举传递给 powershell :

      C:\PS> foo A
      A
      C:\PS> $arg = "B"
      C:\PS> foo $arg
      B
      C:\PS> foo F
      error*
      

      错误 - F 不是枚举值之一 - 有效值包括 A、B、C、D *

      【讨论】:

      • 但是如何将这些枚举示例用于命令行“参数”目的?
      • 一个有趣的例子,但我认为在这种情况下它并不是很有用。
      • 是的,必须使用parens那种咬。 OTOH 我喜欢制表符完成 - 对枚举值进行真正的静态验证的下一个最佳选择。 ValidateSet 无疑是该语言中的一个不错的功能,可惜 PowerShell 不使用该信息来驱动制表符完成。顺便说一句,如果它只是一组选择,您可以使用 OP 使用的开关 - 只需将每个开关放在单独的参数集中并选择一个作为默认值(如果未指定)。
      • 对于它的价值,我认为值得一提的是,使用真正的枚举允许 Get-Help 为脚本用户提供帮助,而不会使其成为不透明的运行时雷区。在此处的示例中,Get-Help 将显示: SYNTAX foo -enum {A |乙| C | D}
      • 验证集成员的制表符完成现在似乎可以工作,因为我们在未来。
      【解决方案4】:

      从 PowerShell 5 开始,您实际上可以本机使用/创建 Enum

      enum OS {
          Windows
          Linux
          iOS
      }
      

      这也作为它的类型可见。

      IsPublic IsSerial Name                                     BaseType
      -------- -------- ----                                     --------
      True     True     OS                                       System.Enum
      

      4sysops 可能是一个有用的链接。

      【讨论】:

      • 按照 OP 的要求,您将如何在 powershell 脚本中使用它?因为据我所知,您不能将枚举放在初始参数调用之前。
      • @IvoMerchiers,这是一个关于在 Powershell 中使用枚举的 SO 问题。 stackoverflow.com/questions/62511588/…
      猜你喜欢
      • 1970-01-01
      • 2014-07-05
      • 2020-10-12
      • 1970-01-01
      • 2011-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多