You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ValidateSet should support a dynamically generated set from a script block #8651
As a PowerShell user, I want [ValidateSet] to support a dynamically generated sets from script blocks so that I can make terse, reusable sets of data, and my coworkers are provided useful IntelliSense from my work. In issue #3744, it was proposed to support a dynamically generated set for [ValidateSet]. An example was given with a script block, which would resolve the set. However, the actual merged PR laid the groundwork and implemented a variant, using classes and interfaces. I'd like this issue to specifically track the ability to use [ValidateSet] with a script block and receive IntelliSense feedback.
It's important to remember that while the [ArgumentCompleter()] script block param can refer to other already-entered parameters via a $fakeBoundParameters param in the script block's param() block, the IValidateSetValuesGenerator interface does not provide the same capability as IArgumentCompleter's interface method does.
It may be possible to copy parts of the code from the [ArgumentCompleter()] constructor that utilises a script block, and the code from IArgumentCompleter in order to permit this much more dynamic and self-referential mode of using ValidateSet, which should make it a far more versatile attribute to work with.
and my coworkers are provided useful IntelliSense from my (arbitrary scriptblocks).
Are you talking about intellisense in an editor? Running arbitrary code when you are simply editing is problematic from a security standpoint. Consider all the problems that Word macros caused. Or an evil.ps1 script file:
Jason Shirk (@lzybkr) We don't instantiate functions until runtime. Without running the script, how is the dynamic parameter block getting turned into executable code?
It falls out naturally when asking for the parameter metadata - PSScriptCmdlet implements IDynamicParameters.
If you ask for the parameter metadata, e.g. to invoke the command or for parameter name completion, you must also query the cmdlet for it's dynamic parameters via IDynamicParameters.
The actual compilation is always on demand, so in this case, it's the implementation of PSScriptCmdlet.GetDynamicParameters that kicks off the compilation.
Are you talking about intellisense in an editor? Running arbitrary code when you are simply editing is problematic from a security standpoint. Consider all the problems that Word macros caused. Or an evil.ps1 script file:
I more so meant command completion in the PowerShell console window -- in which case, (my coworkers at least) have the source to every command and every command we maintain is code reviewed when changed/added. I don't really view this kind of completion as any more risky than running a command without digging into its source; it could do anything after all.
Josh Olson (@OlsonDev) I agree, not any more risky than running a command really, just occurs maybe a little sooner. I suppose the validation code could be put in a constrained runspace but seems like a lot of overhead for little benefit.
FYI as a workaround that is both Core and WinPS compatible, you can use Register-ArgumentCompleter for the autocomplete part and pass it a scriptblock, and (if you're really paranoid) then have one of the first lines of your code run the same scriptblock, compare the result, and throw an error. The error can have basically the same text as ValidateSet, so you get effectively the same result.
functionGet-TestArgumentValues {
(get-module).name
}
Register-ArgumentCompleter-CommandName Test-ArgumentCompleter-ScriptBlock {Get-TestArgumentValues}
functionTest-ArgumentCompleter ($argument) {
#This part is optional but recommended$TestArgumentValues=Get-TestArgumentValuesif ($argument-notin$TestArgumentValues) {throw"Parameter invalid, you must specify one of the following options: $($TestArgumentValues-join', ')"}
#End Optional Part
echo $argument
}
#Now try Test-ArgumentCompleter -Argument [tab]
You can also dynamically generate an enum on module import and set your parameter type to that, but then you have to get the enum into the "user" scope because of how dumb classes are. The above is "cleaner" in my opinion.
But yes, given that the implementation via class is already a thing, I don't really see how that's all that different to just accepting and using a script block just like ArgumentCompleter already does.
Rain Sallow (/u/ta11ow) (@vexx32) I agree, the class already has the functionality in PSCore so the decision has already been made that this is "OK", so going forward the syntax should be able to be simplified to just a scriptblock to make it more intuitive for less advanced powershell users :)
Reacted by Rain Sallow (/u/ta11ow), Aftab Hussain and Ole
I do wish this was implemented as for my current workflow, it would work a wonder. Trying to use IValidateSetValuesGenerator now, but it's just not very intuitive.
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commented on Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
Activity
vexx32 commentedon Jan 15, 2019
It's important to remember that while the
[ArgumentCompleter()]script block param can refer to other already-entered parameters via a$fakeBoundParametersparam in the script block'sparam()block, theIValidateSetValuesGeneratorinterface does not provide the same capability asIArgumentCompleter's interface method does.It may be possible to copy parts of the code from the
[ArgumentCompleter()]constructor that utilises a script block, and the code fromIArgumentCompleterin order to permit this much more dynamic and self-referential mode of using ValidateSet, which should make it a far more versatile attribute to work with.BrucePay commentedon Jan 15, 2019
Josh Olson (@OlsonDev)
Are you talking about intellisense in an editor? Running arbitrary code when you are simply editing is problematic from a security standpoint. Consider all the problems that Word macros caused. Or an
evil.ps1script file:lzybkr commentedon Jan 15, 2019
Bruce Payette (@BrucePay) -
That ship sailed a long time ago - parameter name completion has invoked the
dynamicparamblock since it was introduced.BrucePay commentedon Jan 16, 2019
Jason Shirk (@lzybkr) We don't instantiate functions until runtime. Without running the script, how is the dynamic parameter block getting turned into executable code?
lzybkr commentedon Jan 16, 2019
It falls out naturally when asking for the parameter metadata -
PSScriptCmdletimplementsIDynamicParameters.If you ask for the parameter metadata, e.g. to invoke the command or for parameter name completion, you must also query the cmdlet for it's dynamic parameters via
IDynamicParameters.The actual compilation is always on demand, so in this case, it's the implementation of
PSScriptCmdlet.GetDynamicParametersthat kicks off the compilation.OlsonDev commentedon Jan 19, 2019
Bruce Payette (@BrucePay)
I more so meant command completion in the PowerShell console window -- in which case, (my coworkers at least) have the source to every command and every command we maintain is code reviewed when changed/added. I don't really view this kind of completion as any more risky than running a command without digging into its source; it could do anything after all.
JustinGrote commentedon Mar 18, 2019
Josh Olson (@OlsonDev) I agree, not any more risky than running a command really, just occurs maybe a little sooner. I suppose the validation code could be put in a constrained runspace but seems like a lot of overhead for little benefit.
FYI as a workaround that is both Core and WinPS compatible, you can use Register-ArgumentCompleter for the autocomplete part and pass it a scriptblock, and (if you're really paranoid) then have one of the first lines of your code run the same scriptblock, compare the result, and throw an error. The error can have basically the same text as ValidateSet, so you get effectively the same result.
You can also dynamically generate an enum on module import and set your parameter type to that, but then you have to get the enum into the "user" scope because of how dumb classes are. The above is "cleaner" in my opinion.
vexx32 commentedon Mar 18, 2019
I have some other alternatives for this purpose listed in my blog post here:
https://vexx32.github.io/2018/11/29/Dynamic-ValidateSet/
But yes, given that the implementation via class is already a thing, I don't really see how that's all that different to just accepting and using a script block just like ArgumentCompleter already does.
JustinGrote commentedon Mar 18, 2019
Rain Sallow (/u/ta11ow) (@vexx32) I agree, the class already has the functionality in PSCore so the decision has already been made that this is "OK", so going forward the syntax should be able to be simplified to just a scriptblock to make it more intuitive for less advanced powershell users :)
exproject commentedon Aug 24, 2019
I do wish this was implemented as for my current workflow, it would work a wonder. Trying to use IValidateSetValuesGenerator now, but it's just not very intuitive.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 16, 2023
This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.
microsoft-github-policy-service commentedon Nov 23, 2023
This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.