---
title: "PowerShell Tab-Completion: Auto-Update ArgumentCompleters"
description: "Build handy PowerShell tab-completion parameters that auto-update with ArgumentCompleters."
canonical: "https://adamtheautomator.com/powershell-tab-completion/"
---

# PowerShell Tab-Completion: Auto-Update ArgumentCompleters

> Build handy PowerShell tab-completion parameters that auto-update with ArgumentCompleters.

Source: https://adamtheautomator.com/powershell-tab-completion/

---

ATA Learning

Tap to hide

[

ATA Learning

](/)

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Search for:  

*   [](https://twitter.com/adbertram)
*   [](https://github.com/Adam-the-Automator)
*   [](https://www.linkedin.com/company/adam-the-automator-llc)
*   [](/feed/)

![PowerShell Tab-Completion: Auto-Update ArgumentCompleters](https://adamtheautomator.com/wp-content/uploads/2019/09/laptop-work-1148958_1280.jpg)

# PowerShell Tab-Completion: Auto-Update ArgumentCompleters

[![](https://secure.gravatar.com/avatar/06ab692f58fa7256ef14d0c099c863b6a12b9692e9c117a0337cc6468f359714?s=192&d=mm&r=g)Nathan Kasco](https://adamtheautomator.com/author/nate/)17 September 20195 min. read

Categories: [IT Ops](/category/it-ops/)

Tags:[PowerShell](/tag/powershell/)

Table of Contents

*   [Simple Introduction to ArgumentCompleters](#simple-introduction-to-argumentcompleters)
*   [Creating a Scriptblock to Provide Values](#creating-a-scriptblock-to-provide-values)
*   [Dynamic Parameter Values with ArgumentCompleters](#dynamic-parameter-values-with-argumentcompleters)
*   [Passing Parameter Values to the Scriptblock](#passing-parameter-values-to-the-scriptblock)
*   [Positional Parameters and the Scriptblock](#positional-parameters-and-the-scriptblock)
*   [Passing User-Provided Values to the Scriptblock](#passing-user-provided-values-to-the-scriptblock)
*   [Adding PowerShell Tab Completion to Get-CimInstance CIM Classes](#adding-tab-completion-to-get-ciminstance-cim-classes)
*   [Gather all CIM Classes](#gather-all-cim-classes)
*   [Create the Scriptblock](#create-the-scriptblock)
*   [Register the ArgumentCompleter](#register-the-argumentcompleter)
*   [Try it Out!](#try-it-out-)
*   [Summary](#summary)
*   [Further Reading](#further-reading)

A handy PowerShell feature most people take advantage of is parameter value tab completion. Parameter value PowerShell tab completion allows you to tab through available values you can pass to PowerShell commands.

![PowerShell parameter value tab completion via argument completer](/wp-content/uploads/2019/09/powershell-tab-completion-2-1-1.gif)

PowerShell parameter value tab completion via argument completer

Parameter value tab-completion is a feature most commonly exposed through the [_ValidateSet_ parameter attribute](https://adamtheautomator.com/powershell-parameter/) and [PowerShell dynamic parameters](https://adamtheautomator.com/powershell-parameter-validation/). But there’s another, less known method that many people overlook, argument completers. Argument completers allow you to define tab completion on any of your PowerShell functions with just a few lines of code.

In this article, you’re going to learn how to create argument completers using the `Register-ArgumentCompleter` cmdlet. You’ll then learn how to apply the argument completers and integrate them with two key examples.

You’ll put `Register-ArgumentCompleter` to work and save time digging for valid parameter values by having parameter values readily available as part of the command itself.

## Simple Introduction to ArgumentCompleters

You can add argument completers to any PowerShell command to get PowerShell tab completion; either a default, built-in cmdlet, or a custom function. Let’s first cover how to create an argument for a custom function called `Do-Thing`.

The `Do-Thing` function is a simple function with a single parameter `Name`. This function simply returns the value it received via the `Name` parameter as shown below.

```powershell
function Do-Thing {
    [CmdletBinding()]
    param(
        [Parameter()]
        [string]$Name
    )
    
    $Name
}
```

Let’s say that you’d like to support values for the `Name` parameter as `foo` and `bar`.

### Creating a Scriptblock to Provide Values

You can register an argument completer to provide both the `foo` and the `bar` values by first creating a scriptblock. The scriptblock is what’s executed when you hit the tab key. Every time you hit the tab key, the scriptblock will execute the return a single string element in the array below.

```powershell
$scriptBlock = { 'foo','bar' }
```

Once you have the array of items to provide as values, you’ll then register the argument completer providing the command name and parameter name to associated the argument completer with. Notice below you will also provide the scriptblock just created.

```powershell
PS51> Register-ArgumentCompleter -CommandName Do-Thing -ParameterName Name -ScriptBlock $scriptBlock
```

Now when you type `Do-Thing -Name <tab>`, PowerShell will begin scrolling through all of the values defined in the scriptblock, in this case `foo` and `bar`.

For each parameter, you are only expecting a certain number of items. For `FoodType`, you’d like to support values of `Fruit` and `Vegetable`. Each food type category then has the name of the food under each like below.

### Dynamic Parameter Values with ArgumentCompleters

The previous example could easily be accomplished with the [ValidateSet](https://adamtheautomator.com/powershell-validateset/) parameter validation attribute but what if you need dynamic values? Maybe the values you want to provide can change at any time like files in a folder.

In that case, you simply need to change the code inside of the scriptblock. Since the code inside of the scriptblock is executed at run time, it doesn’t have to be a static list. It can dynamically return lists.

Below is another example you can try out.

```powershell
function Get-ProgramFilesFolder {
    [CmdletBinding()]
    param(
        [Parameter()]
        [string]$FolderName
    )
}

$scriptBlock = { Get-ChildItem -Path 'C:\Program Files' | Select-Object -ExpandProperty Name }

Register-ArgumentCompleter -CommandName Get-ProgramFilesFolder -ParameterName FolderName -ScriptBlock $scriptBlock
```

## Passing Parameter Values to the Scriptblock

The previous examples did not rely on any input into the scriptblock. They both simply executed the scriptblock when the user hit the Tab key. Taking argument completers a step further, you can also pass values into the scriptblock to change the behavior.

When you associate a scriptblock to a command with `Register-ArgumentCompleter`, PowerShell will pass each parameter value provided with `Register-ArgumentCompleter` via positional parameters and the parameters passed when the associated command executes via positional parameters.

To create a scriptblock to accept input, you first must pay attention to how you pass parameters to the `Register-ArgumentCompleter` upon creation. Both the way you register the argument completer once _and_ how you call the associated command is important.

### Positional Parameters and the Scriptblock

This concept can get confusing so let’s break it down with an example.

You’ll first need to create a scriptblock with at least two parameters regardless of how many parameters your associated command has. Below you can see I’ve defined a script with two parameters. The parameter placeholders can be any name. Why are they called `$commandName` and `$parameterName`?  Because they correlate to the value of the `CommandName` and `ParameterName` parameters passed to the `Register-ArgumentCompleter` command.

The scriptblock below will just return the value of `$commandName` and `$parameterName` when the user hits the tab key.

```powershell
$scriptblock = {
    param($commandName,$parameterName)
    
    $commandName,$parameterName
}
```

Once you’ve got the scriptblock created, run `Register-ArgumentCompleter` using our previous example command of `Get-ProgramFilesFolder`.

```powershell
Register-ArgumentCompleter -CommandName Get-ProgramFilesFolder -ParameterName FolderName -ScriptBlock $scriptBlock
```

Type `Get-ProgramFilesFolder -FolderName <tab>`. Notice that the tab-completion will cycle through the values of the name of the associated command and the parameter name. It’s pulling the values for `Register-ArgumentCompleter`‘s `CommandName` and `ParameterName` parameters.

> _Remember that if you want to pass parameters to the scriptblock, you must always add placeholders for all parameter values passed when you run `Register-ArgumentCompleter`._

### Passing User-Provided Values to the Scriptblock

Now that you understand the role that `Register-ArgumentCompleter` parameters play when passing values to the scriptblock, let’s know uncover how to pass user-provided values to it.

Let’s use the `Get-ProgramFilesFolder` function as an example again.

You’d like to allow the user to type a character as the `FolderName` parameter value, hit Tab and only return folder names that match that string. For example, if the user types an ‘a’ and starts hitting tab, you’d like to only return folders that start with ‘a’.

To build this behavior, you’ll need to add an additional parameter value placeholder to the scriptblock. Below I’ve called the placeholder `$stringMatch`. `$stringMatch` will hold the value of the `FolderName` parameter before the user hits the tab key.

```powershell
$scriptblock = {
    param($commandName,$parameterName,$stringMatch)
    
    Get-ChildItem -Path "C:\Program Files\$stringMatch*" | Select-Object -ExpandProperty Name
}

Register-ArgumentCompleter -CommandName Get-ProgramFilesFolder -ParameterName FolderName -ScriptBlock $scriptBlock
```

If you’ll now type `Get-ProgramFilesFolder -FolderName a<tab>`, you’ll see that you are cycling through all of the folder names that start with ‘a’.

## Adding PowerShell Tab Completion to Get-CimInstance CIM Classes

A real-world example of using argument completers is with the `ClassName` parameter on the `Get-CimInstance` cmdlet. Previously, you learned how to apply argument completers to custom functions but built-in cmdlets work just as well.

I can never remember all of the CIM classes when I’m querying WMI using the `ClassName` parameter with `Get-CimInstance`. When I type `Get-CimInstance -ClassName <tab>`, I want to cycle through all of the CIM classes.

### Gather all CIM Classes

The first step is to come up with the code to find all CIM classes and return them as strings in a list.

```powershell
Get-CimClass | Where-Object { $_.CimClassName -notlike '__*' } | Sort-Object -Property CimClassName | Select-Object -ExpandProperty CimClassName
```

### Create the Scriptblock

Next, create the scriptblock that will be executed when you attempt to tab-complete the `ClassName` parameter value.

```powershell
$scriptBlock = {
    Get-CimClass | Where-Object { $_.CimClassName -notlike '__*' } | Sort-Object -Property CimClassName | Select-Object -ExpandProperty CimClassName
}
```

### Register the ArgumentCompleter

Finally, provide the command name, the parameter name and the scriptblock to execute when you attempt to tab-complete the `ClassName` parameter.

```powershell
Register-ArgumentCompleter -CommandName Get-CimInstance -ParameterName ClassName -ScriptBlock $scriptBlock
```

### Try it Out!

Now type `Get-CimInstance -ClassName <tab>`. You’ll notice that you can now cycle through all of the available CIM classes!

> _Note: Argument completers only last for y0ur current session. This means if you close your PowerShell console, they will be gone! To get around this, I recommend adding them to your PowerShell profile to ensure they get registered in every session._

## Summary

PowerShell argument completors may not be the most widely used or best known but they can sure come in handy.

By adding on your own tab-completion functionality to any command inside of PowerShell will potentially save you tons of research time.

## Further Reading

*   **_[Register-ArgumentCompleter Microsoft docs](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/register-argumentcompleter?view=powershell-5.1)_**
*   **_[Completing Parameter Values with Other Parameter Values](https://rohnspowershellblog.wordpress.com/2017/01/17/completing-parameter-values-with-other-parameter-values/)_**

Share this article

[Share on X](https://twitter.com/intent/tweet?url=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-tab-completion%2F&text=PowerShell%20Tab-Completion%3A%20Auto-Update%20ArgumentCompleters)[Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-tab-completion%2F)[Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fadamtheautomator.com%2Fpowershell-tab-completion%2F)

## Related Posts

![](https://adamtheautomator.com/wp-content/uploads/2026/06/26995-troubleshoot-dns-issues-powershell-codex.webp)

### [Troubleshoot DNS Issues with PowerShell](/troubleshoot-dns-issues-powershell/)

Troubleshoot DNS issues with PowerShell by testing name resolution, DNS client settings, cache entries, and network connectivity in a repeatable workflow.

![](https://adamtheautomator.com/wp-content/uploads/2025/10/image_2025-10-24_095322075.png)

### [Migrating from PowerShell 6 to 7.5: Breaking Changes/New Features](/migrating-powershell-6-to-7-5/)

Migrate from PowerShell Core 6 to 7.5: breaking changes, features, and testing tips.

![](https://adamtheautomator.com/wp-content/uploads/2025/06/featured-image-6.png)

### [How to Add Timeouts to Pester Tests with PowerShell Runspaces](/pester-test-timeout-runspaces/)

Prevent Pester tests from hanging indefinitely using PowerShell runspaces. Learn to handle variable scoping, module loading, TestDrive access, and stream capture challenges with timeout protection.

## Categories

*   [IT Ops](/category/it-ops/)
*   [Cloud](/category/cloud/)
*   [DevOps](/category/devops/)
*   [Home Ops](/category/home-ops/)
*   [Information Security](/category/infosec/)
*   [Software Development](/category/software-development/)

## Site

*   [Home](/)
*   [Tutorials](/tutorials/)
*   [Instructors](/author/)
*   [Advertising](/advertising/)
*   [Recommended Resources](/resources/)
*   [About Adam](/about-adam/)

Copyright 2026© ATA Learning | [Privacy Policy](/privacy/)
