Tab completions in PowerShell

April 25th 2025 PowerShell

While learning about Fast Node Manager, I noticed completions for PowerShell being mentioned in the documentation. I wasn't aware of completions beyond filenames and cmdlets were even supported in PowerShell. I decided to try them out with Fast Node Manager first and then check if they are available for other command line tools I regularly use.

Unfortunately, the Fast Node Manager documentation doesn't give precise instructions on how to install completions in PowerShell. Since I didn't have any better ideas, I tried running the documented command to see what it does:

fnm completions --shell powershell

It emitted a bunch of PowerShell code, so I tried piping it to Invoke-Expression cmdlet, which turned out to be the right thing to do. I added the command to my PowerShell profile to enable them automatically for every PowerShell session:

fnm completions --shell powershell | Out-String | Invoke-Expression

The .NET CLI was the next command for which I wanted to get the completions working. Thanks to well documented built-in support, this was easy to do. I only had to add the following block of code (copied from the documentation) to my PowerShell profile:

# PowerShell parameter completion shim for the dotnet CLI
Register-ArgumentCompleter -Native -CommandName dotnet -ScriptBlock {
    param($wordToComplete, $commandAst, $cursorPosition)
        dotnet complete --position $cursorPosition "$commandAst" | ForEach-Object {
            [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
        }
}

To get completions working for git, I had to install posh-git:

  • First, I installed the module by running the following command in PowerShell:
    Install-Module posh-git
    
  • Then, I added the following command to my PowerShell profile to automatically enable the completions:
    Import-Module posh-git
    

This was the last of the command line tools I regularly use, for which I could find built-in or at least standalone support for PowerShell completions. But then I stumbled upon PSCompletions, an extensible PowerShell module dedicated to completions with quite an extensive list of supported commands.

The basic installation procedure for it is (almost) the same as for any other PowerShell module:

  • Run the following command to install the module:
    Install-Module PSCompletions
    
  • Add the following command to the PowerShell profile to automatically enable the module:
    Import-Module PSCompletions
    

However, this only enabled the completions for the PSCompletions (or psc for short) itself. Completions for any other commands have to be added explicitly. Of course, the first step is to list the available completions:

psc list --remote

From the commands in the list, I somewhat regularly use the following, so these are the ones I ended up adding completions for:

psc add docker
psc add npm
psc add choco

Any such configuration change to PSCompletions will only be applied after restarting the PowerShell session. For some reason, reimporting the module in the same session by executing the profile (. $PROFILE) results in an error:

Line |
  33 |  Import-Module PSCompletions
     |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Cannot write to function PSCompletions because it is read-only or constant.

After some testing, I decided to make another configuration change:

psc menu config enable_menu_enhance 0

This change limits the PSCompletions' custom enhanced completion menu to only its own completions, so that the completions from other sources still work the same as before. This way, I can still use the PSFzf's custom completion menu with file preview:

PSFzf's completion menu with file preview

Otherwise, PSCompletions overrides it and I get a nicer looking completion menu with no file preview:

PSCompletions' completion menu without file preview

Tab completion in PowerShell can make your work in the terminal more efficient with its IntelliSense-like functionality. I find it especially useful for functionalities I don't use often enough to remember the exact parameter names, so I don't have to look them up in the documentation.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License