-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
Steps to reproduce
- Create a module file (*.psm1) and add the following code block.
- Attempt to call Test-ValidateSet -Item 'Hello' from PowerShell
class ValidateSetTest : System.Management.Automation.IValidateSetValuesGenerator
{
[string[]] GetValidValues()
{
return 'Hello', 'World'
}
}
function Test-ValidateSet
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[ValidateSet([ValidateSetTest])]
[string[]]
$Item
)
$Item
}Expected behavior
Hello
Actual behavior
Unable to find type [ValidateSetTest].
At C:\PSTest\PSTest.psm1:1364 char:9
+ [ValidateSet([ValidateSetTest])]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ([ValidateSet([ValidateSetTest])]:AttributeAst) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
Environment data
Name Value
---- -----
PSVersion 6.0.0-rc
PSEdition Core
GitCommitId v6.0.0-rc
OS Microsoft Windows 10.0.15063
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0This happens because the defined class is only known to the module. In order for this feature to work currently "Using Module <ModuleName>" must be called from PowerShell to load the class definitions or a second option is to define a *.ps1 file that contains your class definitions, then in the *.psd1 file, add that script path to the ScriptsToProcess attribute list.
The advantages of modifying the manifest file is that it does not require anything from the end user to get the module to work, however since the class definition lives in an external file, that also means it cannot reference of the internal workings of the module. On the flip side, "using module" allows for the class to remain within the module, but also mean a script must be written or end user action must be taken to bring the class definition into the current session. Additionally this will load any internal class definitions inside the module into their session as well.
Without doing something around these lines, this new feature #3744 cannot be used in modules and only works if you dot-source a script file. As this feature was added to get around having to create dynamic parameters to simply add dynamic ValidateSet values, I feel like modules were the intended use case for this feature as they typically are responsible for exposing multiple functions to the end user whereas scripts as generally just called as a script.
Also note that when using the workaround solutions mentioned above, it also exposes those class definitions to the end users session, something that they really should not care about.