PowerShell Scripts, Tips, Expert Advices, Forums, and Resources

Geek Sync Live

Welcome to PowerShell.com, the educational and community site for Windows PowerShell People. Get a quick overview.

Latest Blog Posts

07-28-2016 - .psd1 files
07-28-2016 - Get-ComputerInfo
07-28-2016 - PowerShell 5.1 preview

As a Powershell.com member you will have access to:

  • Daily PowerShell tips written by Microsoft MVPs and other leading Windows PowerShell experts
  • Free Windows PowerShell advice and training provided by Microsoft MVPs and other leading Windows PowerShell experts
  • Access to leading Windows PowerShell blogs
  • A free ebook, Mastering PowerShell, written by Microsoft MVP Dr. Tobias Weltner
PowerTip of the Day

Creating Parameters with Dynamic IntelliSense

PowerShell 3+

Today, we dive a little deeper in the programming part, and show you how a PowerShell function can have parameters that have dynamic intelliSense completion.

The goal is to define a function called “Manage-Service” with the –Service parameter, and when you enter this parameter, the PowerShell ISE IntelliSense should display the names of all currently running services, so you can easily select one.

Here is how this can be done:

function Manage-Service
{
  param
  (
    [Parameter(Mandatory)]
    [ValidateSet('Stop','Suspend')]
    $Action
  )
  dynamicparam
  {
    # dynamically add a new parameter called -Service
    # with a ValidateSet that contains all currently
    # running services
    $Bucket = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameterDictionary
    
    $AttributeList = New-Object -TypeName System.Collections.ObjectModel.Collection[System.Attribute]
    $Values = Get-Service | Where-Object { $_.Status -eq 'Running' } | Select-Object -ExpandProperty DisplayName
    $AttribValidateSet = New-Object System.Management.Automation.ValidateSetAttribute($Values)
    $AttributeList.Add($AttribValidateSet)
    
    $AttribParameter = New-Object System.Management.Automation.ParameterAttribute
    $AttribParameter.Mandatory = $true
    $AttributeList.Add($AttribParameter)
    $ParameterName = 'Service'
    $Parameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter($ParameterName,[String], $AttributeList)
    $Bucket.Add($ParameterName, $Parameter)
    $Bucket
  }
  end
  {
    # Important: Make sure dynamic parameters are
    # available. They only exist in $PSBoundParameters
    # and need to be manually transferred to a variable
    Foreach ($key in $PSBoundParameters.Keys)
    {
      if ($MyInvocation.MyCommand.Parameters.$key.isDynamic)
      {
        Set-Variable -Name $key -Value $PSBoundParameters.$key
      }
    }
    
    Switch($Action)
    {
      'Stop'     { Stop-Service $Service -WhatIf}
      'Suspend'  { Suspend-Service $Service -WhatIf}
    }
  }
}

Key is the “dynamicparam” section which can define “dynamic parameter” during runtime. Obviously, defining a parameter programmatically is not much fun, but it works. In the example, take a look at $Values: this is the variable that holds the list of allowed values for the parameter.

Note also that dynamic parameters deliver their values to the function inside of $PSBoundParameters only. That’s why the sample code reads all dynamic parameters from that variable, and turns them into easily usable variables.

Twitter This Tip! ReTweet this Tip!

Copyright 2012 PowerShell.com. All rights reserved.