As you might know, the tab completion in Powershell 3.0 is much improved. This in part due to the use of expression trees because it is easy to traverse and discover tidbits of information about the command line or script. Some of the really crazy stuff is the ability to tab expand parameter values. Take for example the Get-Process cmdlet. The Get-Process cmdlet has a parameter for the Name of the process. In PowerShell 3.0, it is possible to tab expand the list of running processes.
Get-Process -Name <tab> Get-Process -Name Apoint<tab> Get-Process -Name armsvc<tab>
This is super neat! I had a fellow in my office question whether it was possible to do the same with a custom set of parameter values. It got me pondering. One way to accomplish this is to use the ValidateSetAttribute. Tab expansion will work for that particular parameter.
[ValidateSetAttribute("This","Is","A","Test")] [Parameter()] $MyParameter
Get-MyParameter -MyParameter <Tab>
Get-MyParameter -MyParameter This<Tab>
Get-MyParameter -MyParameter Is
But what this fellow was looking to do was something more dynamic: like the processes and services do in PowerShell 3.0. I did some digging into System.Management.Automation with Reflector and found this. There is a CompletionCompleters class (love the name) that contains a method NativeCommandArgumentCompletion. It is responsible for tab expanding a particular collection of “native” PowerShell cmdlets.
There is a real big switch statement that checks to see if the command is of the native set.
It also looks like there is no way to extend it. Maybe someone can prove me wrong. I wish it was a bit more dynamic because it would be pretty neat to be able to add this type of awesome functionality right to our own cmdlets. Maybe I’ll figure out a way to hack that later.
Edit: I’ve been notified that there is a way to extend this. Stay tuned!
It’s pretty interesting how the dynamic value completion works. If you take a look at, for instance, the completion method for services, you will see that it actually calls Get-Service and then sorts it alphabetically. It then returns this as the completion result.
Seeing how this is done, it would seem this would be pretty easy to extend to other cmdlets.
FYI, here is a full list of the supported cmdlets. Each one does the tab expansion a bit different and for different parameters: