2

I am attempting to add auto-complete features in powershell. In this case I would like to be able to type "test" in my console. After that to be able to type Get-Se[TAB] to auto complete to Get-Search using TAB Expansion.

PS > Get-Se[TAB]
PS > Get-Search

function test
{
    [CmdletBinding()]
    param()

    # label the while loop "outer"
    :outer while($true){
        $x = Read-Host

        # split $x into two parts
        $first,$second = $x -split '\s',2

        # switch evaluating the first part
        switch($first){
            Get-Search {
                 # Searching
            }
            default {
                Write-Host "False"
            }
        }
    }
}

Additional Information:

Goal: I'd like to be able to use arguments that look like cmdlets to have the Powershell feel.

About the original script:

I have created a script to automate queries from several API's, for many different users. What I have right now for search is "s" and I'd like it to be "Get-Search" So Read-Host waits for an input, the user would type "Get-Search 'value'" and a formatted JSON returns.

PS > Get-Search foobar
#Returns JSON
Alexander Sinno
  • 554
  • 5
  • 24
  • Poweshell already has auto-complete? If I type `Get-Se[TAB]` it cycles me through `Get-SecureBootPolicy, Get-SecureBootUEFI, Get-Service` See `gcm Get-Se*` To have switch react on not exact args you might look at the -wildcard or -regex options `get-help about_switch -show` –  Dec 27 '16 at 17:00

1 Answers1

2

I had a hard time understanding your intention at first, but I think I get it now.

You want to implement tab completion (tab expansion) inside the Read-Host prompt.

Unfortunately, there is no way to do that.

If you share why you want this, there may be better ways to achieve your ultimate goal.


Based on your additional information, I have a different approach.

  1. Create actual functions for each of your queries, like Get-Search, etc. You can even add aliases for them so that s corresponds directly if you want.
  2. Wrap all of these functions in a proper module, so that you can import them (see next step).
  3. Create a constrained runspace that only allows the user to execute the specific functions and aliases you want (this is easier with a module, but the module is not a requirement).

What this can do is give your end users access (even remotely) to a PowerShell session which can only use the functions you've created and allowed to be executed. Other cmdlets/functions and even language features like using variables will be restricted and unavailable.

That way, you get true PowerShell tab expansion and semantics, and you end up with a real set of functions that be used in an automated way as well.

You don't have to write any prompting or parsing.

Further, the session can be secured, allowing only specific users and groups to connect to it.

Community
  • 1
  • 1
briantist
  • 45,546
  • 6
  • 82
  • 127
  • I'd like to be able to use arguments that look like cmdlets to have a Powershell feel. – Alexander Sinno Dec 27 '16 at 16:55
  • 2
    @Badlarry what's the end goal? If you're using `Read-Host` then I assume it's for an end user? – briantist Dec 27 '16 at 16:57
  • Yes that's correct, I have created a script to automate queries from several API's, for many different users. What I have right now for search is "s" and I'd like it to be "Get-Search" So Read-Host waits for an input, the user would type "s 'value'" and a formatted JSON returns. – Alexander Sinno Dec 27 '16 at 17:00
  • @Badlarry see my edit; it's more work at first but I believe it will be a far more versatile solution in the long run. – briantist Dec 27 '16 at 17:15
  • 1
    Thank you, this is exactly what I am looking for. – Alexander Sinno Dec 27 '16 at 17:18