Solutions
Markets
References
Services
Company
Reuse DynamicParam implementations in PowerShell

Reuse DynamicParam implementations in PowerShell

3. October 2017

Reuse DynamicParam implementations in PowerShell

As I wrote here, there is an easy way to enter into a PowerShell container session, which I enhanced a bit in the second iteration to do dynamic name resolution for the containers.

We now have the “NAV Container Helper” script which adds some convenience cmdlets when working with container based NAV installs. I wanted to also enhance that with dynamics name resolution without having to add all the code to every cmdlet which turned out to be not that easy. I tried a number of different things and search the Internet but couldn’t find the solution. Then I went to our resident PowerShell guru, Frank-Peter Schultze (follow @fpschultze) and he showed me how to do it:

First you create a helper function which defines the dynamic param. Specific for my usage is only line 20, everything else should be quite generic. If you have additional parameters, you’ll want to look into lines 12-14

function HelperGetContainersForDynParam {
    # Set the dynamic parameters name
    $ParameterName = 'containerName'
        
    # Create the dictionary 
    $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

    # Create the collection of attributes
    $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        
    # Create and set the parameters' attributes
    $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
    $ParameterAttribute.Mandatory = $true
    $ParameterAttribute.Position = 0

    # Add the attributes to the attributes collection
    $AttributeCollection.Add($ParameterAttribute)

    # Generate and set the ValidateSet 
    $arrSet =  docker ps -a --format '{{.Names}}'
    $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)

    # Add the ValidateSet to the attributes collection
    $AttributeCollection.Add($ValidateSetAttribute)

    # Create and return the dynamic parameter
    $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
    $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
    return $RuntimeParameterDictionary 
}

Second you add it to the existing cmdlet to reference your code which before the change looked e.g. like this

function Get-NavContainerCountry {
    Param(
        [Parameter(Mandatory=$true)]
        [string]$containerName
    )

    docker inspect --format='{{.Config.Labels.country}}' $containerName
}

And afterwards it looks like this

function Get-NavContainerCountry {
    [CmdletBinding()]
    Param
    ()

    DynamicParam {return (HelperGetContainersForDynParam)}

    Process {
        $containerName = $PsBoundParameters['containerName']

        docker inspect --format='{{.Config.Labels.country}}' $containerName
    }
}

You can find the enhanced version of the navcontainer-helper here, which might or might not find it’s way into Microsoft’s repository