First, I do apologize for posting another question concerning PowerShell and tab completion. The StackOverflow system identified several excellent questions with answers concerning this very topic, but they all seemed too cumbersome to implement into this simple New-ADComputer script.

The params are going into a Splat to keep the script readable. The following code correctly tab completes in the ISE, but must be wrapped in double quotes.

Is there any native method in PowerShell to allow for tab completion of Parameter Sets that include spaces?

<!-- language: lang-psh -->
Param(
  [Parameter(Mandatory=$true)]
  [string]$Server,
  [Parameter(Mandatory=$true)]
  [ValidateSet('Env1','Env 2','Env 3')]
  [string]$Environment,
  [Parameter(Mandatory=$true)]
  [ValidateSet('Application','Database','File and Print','Web Server')]
  [string]$Type
)
$NewADitems = @{
  Name        = $server
  Path        = "OU=$Type,OU=$Environment,OU=Smaller DN string"
  Location    ='MySite'
  Description = "Test Description"
  ManagedBy   = "Huge Distingushed Name string"
  WhatIf      = $true
}
Write-Host @NewADitems
<!-- language: none -->

Command used and error received:

PS C:\Scripts> .\ADComputer-ParamTest.ps1 -Server ThisTest -Environment Env 3 -Type File and Print
C:\Scripts\ADComputer-ParamTest.ps1 : Cannot validate argument on parameter
'Environment'. The argument "Env" does not belong to the set "Env1,Env 2,Env3"
specified by the ValidateSet attribute. Supply an argument that is in the
set and then try the command again.At line:1 char:58
+ .\ADComputer-ParamTest.ps1 -Server ThisTest -Environment Env 3 -Type File and Pr ...
+                                                          ~~~

Edit: More information. If you leave off the single/double quotes in my example script for the parameter Environment, tab completion will not work for the final parameter Type. Enclosing the 2nd set in quotes will correct this but it's a way to keep watch for this behavior.

This has been entered as a bug since 2013. According to the workarounds listed in Auto-completed parameter values, with spaces, do not have quotes around them, you can update the TabExpansion2 function that Powershell uses for autocompletion. To do so, just run the following code:

function TabExpansion2
{
    [CmdletBinding(DefaultParameterSetName = 'ScriptInputSet')]
    Param(
        [Parameter(ParameterSetName = 'ScriptInputSet', Mandatory = $true, Position = 0)]
        [string] $inputScript,
    
        [Parameter(ParameterSetName = 'ScriptInputSet', Mandatory = $true, Position = 1)]
        [int] $cursorColumn,

        [Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 0)]
        [System.Management.Automation.Language.Ast] $ast,

        [Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 1)]
        [System.Management.Automation.Language.Token[]] $tokens,

        [Parameter(ParameterSetName = 'AstInputSet', Mandatory = $true, Position = 2)]
        [System.Management.Automation.Language.IScriptPosition] $positionOfCursor,
    
        [Parameter(ParameterSetName = 'ScriptInputSet', Position = 2)]
        [Parameter(ParameterSetName = 'AstInputSet', Position = 3)]
        [Hashtable] $options = $null
    )

    End
    {
        if ($psCmdlet.ParameterSetName -eq 'ScriptInputSet')
        {
            $completion = [System.Management.Automation.CommandCompletion]::CompleteInput(
                $inputScript,
                $cursorColumn,
                $options)
        }
        else
        {
            $completion = [System.Management.Automation.CommandCompletion]::CompleteInput(
                $ast,
                $tokens,
                $positionOfCursor,
                $options)
        }

        $count = $completion.CompletionMatches.Count
        for ($i = 0; $i -lt $count; $i++)
        {
            $result = $completion.CompletionMatches[$i]

            if ($result.CompletionText -match '\s')
            {
                $completion.CompletionMatches[$i] = New-Object System.Management.Automation.CompletionResult(
                    "'$($result.CompletionText)'",
                    $result.ListItemText,
                    $result.ResultType,
                    $result.ToolTip
                )
            }
        }

        return $completion
    }
}

It's worth noting that string insertion works properly for native cmdlets like Get-EventLog -LogName which will properly encase 'Internet Explorer'. Although if you look at the source for Get-EventLog, you'll see that $LogName doesn't actually use ValidateSet so it's intellisense must be provided through another mechanism.


Other Instances: