Repository navigation
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.
Activity
[-]Getting error "Unable to find type" when using IValidateSetValuesGenerator[/-][+]Getting error "Unable to find type" when using IValidateSetValuesGenerator in a PowerShell module[/+]LethiferousMoose commentedon Dec 12, 2017
Steve Lee (@SteveL-MSFT) Do you think this issue needs to be looked at prior to GA?
SteveL-MSFT commentedon Dec 12, 2017
Tim Biggin (@LethiferousMoose) I don't think this blocks 6.0.0 release as it won't impact most users
lzybkr commentedon Dec 15, 2017
You should update the repro with specific details so nobody has to guess at what you are trying.
It's possible this is by design and there is a straightforward way to get it working.
markekraus commentedon Dec 15, 2017
I can repro this with the provided code. https://github.com/markekraus/PowerShellPowerShellRepro5661/tree/6292b92926128f2c6854e4dc4df04c0c870a7f00
LethiferousMoose commentedon Dec 15, 2017
Jason Shirk (@lzybkr) Updated description and referenced the original issue you created that lead the eventual implementation of supporting dynamically created values in the ValidateSetAttribute.
I'll leave it up to the development team to determine whether this is a viable solution, if another better solution exists, or if something else should be done as a defect fix.
lzybkr commentedon Dec 15, 2017
Yeah, that's a bug and I found the problem, PR submitted (but I'll ask someone else to add tests.)
LethiferousMoose commentedon Dec 15, 2017
Jason Shirk (@lzybkr) I was reading over the PR comments on #3784, do you know if anything more came out of the discussions around accessing the context?
iSazonov commentedon Dec 16, 2017
Tim Biggin (@LethiferousMoose) Thanks for your report! We started with the implementation for C# and later added for scripts. As far as the modules and contexts are concerned, we have not considered this until we receive feedbacks like your one, especially since we have a number of problems with the classes and modules that we plan to address in 6.1.0 phase as I understand.
Fix ValidateSet with generator in a module (#5702)
danstur commentedon Aug 27, 2021
Ilya (@iSazonov) Is there any way of sharing IValidateSetValuesGenerator between multiple files? Currently it seems like we're forced to duplicate the implementation (or at least define one generator and then forward to a shared implementation function) of generators in every file we want to use them.
Still much better than previously, but I'm wondering if there's a way around that too.
iSazonov commentedon Aug 27, 2021
Daniel Sturm (@danstur) Please open new issue and share more information with simple repro for your scenario.
Fix ValidateSet with generator in a module (PowerShell#5702)