感谢StackOverflow上的优秀人才,我们收到了关于如何在脚本或函数的ValidateSet
子句中检索Param()
中定义的值的非常好的answer:
Param (
[ValidateSet('Startup', 'Shutdown', 'LogOn', 'LogOff')]
[String]$Type = 'Startup'
)
(Get-Variable Type).Attributes.ValidValues
唯一困扰我的是,当您在PowerShell ISE中运行此代码时,此代码仅适用于第一次。 第二次运行它,没有生成输出。
是否有解决方法让它始终有效?我们在Win 7和Win 2012上使用PowerShell 4.0。
答案 0 :(得分:3)
首先,这种行为只出现在PowerShell ISE中(它在外部完美运行)。这可能由following post解释。
阅读它,您会发现有一种解决方法:
Param (
[ValidateSet('Startup', 'Shutdown', 'LogOn', 'LogOff')]
[String] $Type = 'Startup'
)
(Get-Variable Type).Attributes.ValidValues
# Do your stuff here
Remove-Variable Type
答案 1 :(得分:2)
<强> TL;博士强>
从Windows PowerShell v5.1 / PowerShell Core v6.0-beta.4开始,观察到的行为可以说是 bug - 请参阅{{3} }。
要绕过没有副作用的问题,请使用以下方法:
Param (
[ValidateSet('Startup', 'Shutdown', 'LogOn', 'LogOff')]
[String] $Type = 'Startup'
)
$MyInvocation.MyCommand.Parameters['Type'].Attributes.ValidValues
如果Set-StrictMode -version 2
或更高版本有效或您正在使用PSv2,请使用
Param (
[ValidateSet('Startup', 'Shutdown', 'LogOn', 'LogOff')]
[String] $Type = 'Startup'
)
($MyInvocation.MyCommand.Parameters['Type'].Attributes |
Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] }).ValidValues
问题与 ISE 本身无关,而是与重复 dot-sourcing 有关(ISE恰好运行所有脚本)通过点源他们)。
this GitHub issue在当前作用域中运行脚本(在调用者的作用域本身,而不是在子作用域中),因此通常会修改当前作用域的状态,例如通过添加变量。
如果您从交互式会话中点源脚本,则可以有效地修改全局会话状态,例如,加载PS配置文件中的定义的方式。
在目前的情况下,脚本的点源调用有效地将参数变量$Type
作为常规添加到调用范围变量,按设计。
当您再次点源同一个脚本 时会出现错误(假设问题中的脚本显示为./script.ps1
:
在第一次点源调用之后,变量$Type
在其属性方面仍然完好无损:
> . ./script.ps1; (Get-Variable Type).Attributes.Count
Startup
Shutdown
LogOn
LogOff
3 # PS implicitly adds 2 add'l attributes behind the scenes
当你再次点源 时,属性丢失:
> . ./script.ps1; (Get-Variable Type).Attributes.Count
0