PnP PowerShell and more...

Here I occasionally post about Microsoft 365 Patterns and Practices in general and PnP PowerShell more specifically.

Register your own parameter completer in PowerShell for PnP Cmdlets

2024-11-12 3 min read PowerShell

UPDATE:

While the information below is still relevant for basically any cmdlet in your PowerShell modules (so it does not only apply to PnP PowerShell), in the upcoming version 3.0 of PnP PowerShell we have built-in support for autocompletion on List names, Content Type names, Fields and Property Bag keys. For instance, typing Get-PnPList -Identity<tab> will automatically retrieve all the lists in the current site for you to pick from. You do not have to modify your $PROFILE file and add the code below.

Again, this works as of PnP PowerShell version 3.0 and higer which will come out soon

Say you’re using the Get-PnPList cmdlet a lot to retrieve a list, but you tend to forget what the list is called, or you only remember the first part of the name of it. Wouldn’t it be nice if you could just ’tab’ through the list names?

As we’re not doing that by default in a list cmdlet (it can be a bit slow at times to retrieve all the lists…) there is a way around it if you decide to want to have it anyway!

A bit of an unknown feature of PowerShell (and notice what I describe here applies to ALL PowerShell cmdlets) is that you can register your own Parameter Completer.

Look at the example below:

$listCompletionScriptBlock = 
{
    param($commandName, $parameterName, $stringMatch)
    $site = Get-PnPSite -Includes Id 
    $lists = Invoke-PnPGraphMethod -Method Get -Url "/sites/$($site.Id.Guid)/lists?`$select=name"   
    $lists.value | Where-Object { $_.name -like "$stringMatch*"} | Select-Object -ExpandProperty name
}

Register-ArgumentCompleter -Command "Get-PnPList" -ParameterName Identity -ScriptBlock $listCompletionScriptBlock

What we are doing here is that we first create a script block, effectively a small PowerShell script that will be invoked in certain scenarios. On the last line of the snippet above we register this script block to be invoked when someone requests parameter completion on the Get-PnPlist cmdlet, and more specifically on the Identity parameter.

The effect is that when you type Get-PnPList -Identity <tab> PowerShell will first retrieve the ID of the current Site collection you’re in. Then it will call the Graph API to retrieve the names of all the lists in that site, and it will return the names that match what you typed after Identity. So if you type Get-PnPList -Identity A<tab> it will return all lists starting with ‘A’.

As the method is pretty generic, it just returns a name of a list, you can simply extend other cmdlets that require a listname too by adding a simple additional registration. For example:

Register-ArgumentCompleter -Command "Get-PnPListItem" -ParameterName List -ScriptBlock $listCompletionScriptBlock

Now, where do you all put this? In your $PROFILE. If you’re on Windows, just enter

notepad $PROFILE

on Mac, I use VSCode:

code $PROFILE

Add the snippet, save the file and reload your PowerShell session.