powershell cmdlet 的枚举参数
Enum parameter for powershell cmdlet
我正在 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__
我会尝试这样的事情:
下面我用 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。
如果此脚本需要接受自定义枚举,则意味着您将从其他已存在枚举定义的地方调用它。现在您正试图在脚本中再次添加相同的定义。最好按照@Alex_P的建议将它推送到一个模块,这样定义就在一个地方,但缺点是 Import-Module
或 #Requires
不会导入它,因此需要 using module
子句。
但是如果您愿意接受更简单且安全性较低的解决方案,则可以利用您定义的任何枚举都派生自 System.Enum 这一事实。 [System.Enum]$Level
将只接受所有枚举,如果不是 LevelEnum,脚本将中断,但它仍然会在脚本执行之前过滤掉大多数可能的错误,并提供一些有关参数类型的信息。
与 PowerShell 语法的所有其他部分不同,类型定义(和 using
语句)在 parse-time 发出,您可以通过将enum
定义 在依赖于它的脚本或函数中(尽管它看起来有悖常理):
[cmdletbinding()]
param(
[Parameter(Mandatory=$True)]
[LevelEnum]$Level
)
begin {
enum LevelEnum { NC = 1; NML = 2; CS = 3 }
}
end {
# rest of your script goes here
}
[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
这行得通,但我相信人们很容易忘记编辑所有枚举定义...
我正在 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__
我会尝试这样的事情:
下面我用 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。
如果此脚本需要接受自定义枚举,则意味着您将从其他已存在枚举定义的地方调用它。现在您正试图在脚本中再次添加相同的定义。最好按照@Alex_P的建议将它推送到一个模块,这样定义就在一个地方,但缺点是 Import-Module
或 #Requires
不会导入它,因此需要 using module
子句。
但是如果您愿意接受更简单且安全性较低的解决方案,则可以利用您定义的任何枚举都派生自 System.Enum 这一事实。 [System.Enum]$Level
将只接受所有枚举,如果不是 LevelEnum,脚本将中断,但它仍然会在脚本执行之前过滤掉大多数可能的错误,并提供一些有关参数类型的信息。
与 PowerShell 语法的所有其他部分不同,类型定义(和 using
语句)在 parse-time 发出,您可以通过将enum
定义 在依赖于它的脚本或函数中(尽管它看起来有悖常理):
[cmdletbinding()]
param(
[Parameter(Mandatory=$True)]
[LevelEnum]$Level
)
begin {
enum LevelEnum { NC = 1; NML = 2; CS = 3 }
}
end {
# rest of your script goes here
}
[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
这行得通,但我相信人们很容易忘记编辑所有枚举定义...