2

Using ValidateSet for a parameter on a cmdlet, will give a list of possible parameters. But will not let the user of that cmdlet enter other values. Example the below

[ValidateSet('A','B')

Would let the users enter A or B, but nothing else.

I would like to provide a list that give the most common option, but also allow them to enter anything else.

For example, a parameter that takes a path to a build. Build A and B are shipped and stable builds. But there are many other builds. So, I want to provide a list of A and B build so they do not need to know the path to them but then also let them enter any other path to any other build.

Is this possible?

mklement0
  • 382,024
  • 64
  • 607
  • 775
deetle
  • 197
  • 8

1 Answers1

2

Use an ArgumentCompleter attribute, which specifies what values should be offered via tab-completion, while not limiting what values may be passed (by entering them manually / pasting them); e.g.:

function Get-Foo {
  param(
    # Suggest 'A' and 'B' as tab-completions, but allow any
    # other value to be passed as well.
    [ArgumentCompleter({ 
      param($cmd, $param, $wordToComplete) 
      'A', 'B' -like "$wordToComplete*" 
    })]
    [string] $MyParam
  )
 
  "[$MyParam]" # sample output
}

Typing Get-Foo <tab> then offers A and B as completions, while still allowing any other value to be passed too.

With single-character completion values such as A and B it isn't obvious, but the solution above allows you type a prefix of the completion values to narrow down the completions.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Seems to work in powershell.exe but not PowerShell ISE . In ISE tabbing is cycling threw files in the current folder. Let me play with it a bit – deetle Jan 22 '23 at 23:58
  • @deetle, it should work in the ISE as well; as an aside re the ISE, please see the next comment: – mklement0 Jan 23 '23 at 00:16
  • 3
    The PowerShell ISE is [no longer actively developed](https://docs.microsoft.com/en-us/powershell/scripting/components/ise/introducing-the-windows-powershell-ise#support) and [there are reasons not to use it](https://stackoverflow.com/a/57134096/45375) (bottom section), notably not being able to run PowerShell (Core) 6+. The actively developed, cross-platform editor that offers the best PowerShell development experience is [Visual Studio Code](https://code.visualstudio.com/) with its [PowerShell extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell). – mklement0 Jan 23 '23 at 00:16
  • 1
    Yet none of can do what ISE can do. Uder 1-minute learning curve for new users. I played with VS code for an hour, still didn't make sense. Way too many steps to get going. I can run 30 copies of ISE, on a 16 GB machines I cannot do that with VS Code. – deetle Jan 23 '23 at 00:30
  • @deetle, to close the tangent: The transition isn't easy, but if you don't want to be left behind in the long run, you'll eventually have to bit the bullet; as an aside: no IDE should require running multiple copies. Getting back on track: the solution should work in _any_ (interactive) PowerShell host, including the obsolescent ISE. – mklement0 Jan 23 '23 at 00:42
  • It's not me, but there is too much complexity for new user. Every new user would take 10 extra minutes out of my time. I currently have over ~100 hundred users. It didn't work for me on VS code as well. I will dig more into tomorrow. – deetle Jan 23 '23 at 01:01
  • 1
    Confirming that this works for me in both ISE using PowerShell 5.1, VSCode using PowerShell 7.3.1 and directly from PowerShell terminal – Daniel Jan 23 '23 at 01:10
  • Thanks, Daniel. In that vein, @deetle, to reiterate, without ambiguity: the choice of interactive PowerShell host (legacy console window (`conhost.exe`) / Windows Terminal / Visual Studio Code / ISE) is _incidental_ to the solution in this answer. If you find that one or more of these hosts do not behave as expected, and you have predictable ways to reproduce the unexpected behavior, I encourage you to file bugs against the relevant projects. – mklement0 Jan 23 '23 at 01:15
  • I tried it for cmdlets that use ValidateSet when I press [space] after the param switch. cmdlet -param[space] I get a list pf params specified in ValidateSet, For the Get-Foo cmdlets the [space] gives I list of files in VS Code. It behaves like ISE. – deetle Jan 23 '23 at 14:33
  • @deetle, the only plausible explanation for that is _you never actually defined the function_ in the integrated terminal you're using in VS Code. To do so, you must paste the function definition either it into the terminal or, assuming you're running the PIC (PowerShell Integrated Console) that comes with the PowerShell extension, open or create a `*.ps1` file, paste the code into it, and run it. – mklement0 Jan 23 '23 at 15:06
  • The ArgumentCompletions option says it was introduced in version 6 , We need to work in the version that gets installed with windows by default. When I define the function, it doesn't complain. But when getting help or run it we get Cannot find the type for custom attribute 'ArgumentCompletions' PS Version is 5.1.22000.832 – deetle Jan 23 '23 at 15:12
  • @deetle, the codes uses the [`[ArgumentCompleter]`](https://learn.microsoft.com/en-US/dotnet/api/System.Management.Automation.ArgumentCompleterAttribute) attribute (not ...*Completions*), which is also available in Windows PowerShell. The code works as-is in v5.1, I've just tried it. – mklement0 Jan 23 '23 at 15:15
  • 1
    Ok , I read up on the docs and the sample from the documentation of ArgumentCompleter I got to work now. It works in ISE & VS Code Thanks – deetle Jan 23 '23 at 15:34