PowerShell: Simple way to add dynamic parameters to advanced function


I’ve been working on a module for Nimble Storage and I’ve been creating dynamic parameters for some of the functions and I thought, why not just create a helper function for this? So I did, here it is with a simple example. The code is actually not too bad once you look through it, mostly just populating some objects and dumping them in the DynamicParam block.

Thanks Bart for the initial help! :)

Two important notes about this:
1) You have to supply Begin/Process/End (dont need all, but need at least 1)
2) It does not populate the variable as you’d expect it to, you have to pull it from $PSBoundParameters

Function New-DynamicParam {
param(
[string]
$Name,
[string[]]
$Options,
[switch]
$mandatory,
[string]
$SetName="__AllParameterSets",
[int]
$Position,
[switch]
$ValueFromPipelineByPropertyName,
[string]
$HelpMessage

)
    #param attributes   
    $ParamAttr = New-Object System.Management.Automation.ParameterAttribute
    $ParamAttr.ParameterSetName = $SetName
    if($mandatory){ $ParamAttr.Mandatory = $True }
    if($Position -ne $null){$ParamAttr.Position=$Position}
    if($ValueFromPipelineByPropertyName){$ParamAttr.ValueFromPipelineByPropertyName = $True}
    if($HelpMessage){$ParamAttr.HelpMessage = $HelpMessage}

    ##param validation set
    $ParamOptions = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList $options

    $AttributeCollection = New-Object 'Collections.ObjectModel.Collection[System.Attribute]' 
    $AttributeCollection.Add($ParamAttr)
    $AttributeCollection.Add($ParamOptions)

    $Parameter = New-Object -TypeName System.Management.Automation.RuntimeDefinedParameter `
    -ArgumentList @($Name, [string], $AttributeCollection)
            
    $Dictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
    $Dictionary.Add($Name, $Parameter)
    $Dictionary
}

Here is an example of how you would use it.

function Show-Free
{
    [CmdletBinding()]
    Param()
    DynamicParam {
    New-DynamicParam -name Drive -options @(gwmi win32_volume |%{$_.driveletter}|sort) -Position 0 
    }
    begin{
    #have to manually populate
    $drive = $PSBoundParameters.drive
    }
    process{
    $vol = gwmi win32_volume -Filter "driveletter='$drive'"
    "{0:N2}% free on {1}" -f ($vol.Capacity / $vol.FreeSpace),$drive
    }
}

I’ve set this up to only work with strings, but if you look at the code there is actually nothing forcing you to use strings, just makes most sense for this.

Enjoy!

Advertisements

About jrich

I am the Solutions Architect for Apex Learning in Seattle WA. I've been working with computers since I was 13. Started programming when I was 14. Had my first IT job as tech support at an ISP at the age of 15 and became a network admin at the age of 17. Since then I've worked at a variety of small to mid size companies supporting, maintaining and developing all aspects of IT. Mostly working with Windows based networks but have recently been working with Solaris system as well. I created this blog mostly as a place for me to take my own notes, but also share things that I had a hard time finding the info for.

Posted on May 30, 2013, in WMF (Powershell/WinRM) and tagged , , , , , , , . Bookmark the permalink. 3 Comments.

  1. Can you explain more about the use case for this? Why not just build an object from a string parameter in the Begin Block?

    • Well it creates [ValidateSet(“x”,”y”,”z”)] param attributes, which allows for ISE intellisense to pop up, which is why i love it. For example I have a New-VMFromTemplate function, one of the params is the template to use. The dynamic param queries the vcenter server to find what templates are out there to present the end user a list of templates.

  1. Pingback: Dynamic parameters, ValidateSet and Enums | IT magician with a knack for automation

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: