Repository navigation
ValidateSet should support a dynamically generated set from a script block #8651
Description
Activity
vexx32 commented
on Jan 15, 2019 CollaboratorMore actionsIt'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.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.ps1script file:[CmdletBinding()] param ( [ValidateSet({Remove-Item -Force -Recurse ~})] $Repo = "foo" )
Running arbitrary code when you are simply editing is problematic from a security standpoint.
That ship sailed a long time ago - parameter name completion has invoked the
dynamicparamblock since it was introduced.Reacted by Rain Sallow (/u/ta11ow)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?
- addedWG-Interactive-IntelliSensetab completiontab completionIssue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
on 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.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:[CmdletBinding()] param ( [ValidateSet({Remove-Item -Force -Recurse ~})] $Repo = "foo" )
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 commented
on Mar 18, 2019 ContributorMore actionsJosh 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.
function Get-TestArgumentValues { (get-module).name } Register-ArgumentCompleter -CommandName Test-ArgumentCompleter -ScriptBlock {Get-TestArgumentValues} function Test-ArgumentCompleter ($argument) { #This part is optional but recommended $TestArgumentValues = Get-TestArgumentValues if ($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.
vexx32 commented
on Mar 18, 2019 CollaboratorMore actionsI 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 commented
on Mar 18, 2019 ContributorMore actionsRain 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 OleI 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 ContributorMore actionsThis 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 ContributorMore actionsThis 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 ContributorMore actionsThis 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.
- addedResolution-No ActivityIssue has had no activity for 6 months or moreIssue has had no activity for 6 months or more
on Nov 16, 2023 microsoft-github-policy-service commented
on Nov 23, 2023 ContributorMore actionsThis issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.
Summary of the new feature/enhancement
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.Proposed technical implementation details
For example: