All solutions below work in both functions and scripts.
Most robust solution that should work in any invocation scenario, PSv2+:
param (
[ValidateSet('Startup', 'Shutdown', 'LogOn', 'LogOff')]
[String]$Type = 'Startup'
)
# -> @('Startup', 'Shutdown', ...)
($MyInvocation.MyCommand.Parameters['Type'].Attributes |
Where-Object { $_ -is [ValidateSet] }).ValidValues
A simpler, but potentially fragile PSv3+ solution, which assumes:
param (
[ValidateSet('Startup', 'Shutdown', 'LogOn', 'LogOff')]
[String]$Type = 'Startup'
)
# Assumes that at most Set-StrictMode -Version 1 is in effect.
# You could explicitly run Set-StrictMode -Off or Set-StrictVersion -Version 1
# in here first.
(Get-Variable Type).Attributes.ValidValues
Optional background information
The PSv3+ shorthand syntax (Get-Variable Type).Attributes.ValidValues
is essentially the equivalent of:
(Get-Variable Type).Attributes | ForEach-Object { $_.ValidValues }
That is, PowerShell automatically enumerates the collection .Attributes
and collects the values of each element's .ValidValues
property.
In the case at hand, only one attribute in the .Attributes
collection - the one of subtype [System.Management.Automation.ValidateSetAttribute]
- has a .ValidValues
property, so that single value is returned.
Given that the other attributes have no such property, setting Set-StrictMode
to -version 2
or higher causes the attempt to access a nonexistent property to raise an error, and the command fails.
((Get-Variable Type).Attributes |
Where-Object { $_ -is [System.Management.Automation.ValidateSetAttribute] }).ValidValues
bypasses this problem by explicitly targeting the one attribute of interest (using the -is
operator to identify it by type) that is known to have a .ValidValues
property.
The more verbose alternative to accessing the attributes of parameter [variable] $Type
with (Get-Variable Type).Attributes
is to use $MyInvocation.MyCommand.Parameters['Type'].Attributes
.
Use of the $MyInvocation.MyCommand.Parameters
collection enables enumerating and inspecting all parameters without needing to know their names in advance.
David Brabant's answer is helpful, but (as of this writing):