#PowerShell, #PowerWiseScripting, #ProjectWise, PWPS_DAB

How To: Add Dynamic Parameters to Your PowerShell Functions

In this post, I am going to demonstrate how to add dynamic parameters to your PowerShell functions. I will create two functions which each contain one or more dynamic parameters. I am including a link to the completed .psm1 file which contains the entire function definitions.

  • Get-PWMember
    • The Get-PWMember function returns the member object. The list of available member names is based on the member type selected.
  • New-PWWorkArea
    • The New-PWWorkArea function creates a new ProjectWise Work Area and returns the new ProjectWise Folder object.

Function Get-PWMember

The Get-PWMember function contains two parameters. The first parameter is $MemberType which has a ValidateSet which limits the selection options to only three choices: User, Group, or Userlist.

[CmdletBinding()]
Param(     
    [ValidateSet("User","Group","UserList")]        
    [Parameter(
            Mandatory = $true,
            Position = 0,
            HelpMessage = "Specifies member type. (User, Group, UserList"
    )]
    [string]$MemberType
)

The second parameter $MemberName is the dynamic parameter. The available values will be determined by the $MemberType selected. For example, if you select Group, a drop-down list will be displayed which contains the name of all available Groups with the ProjectWise datasource. This is a bit more complex .

First we need to create a new DynamicParam code block.

 DynamicParam {}

Next, we need to add a parameter name within the DynamicParam code block.

DynamicParam {
    # Set the dynamic parameters' name
    $ParameterName = 'MemberName'
} # end DynamicParam

Next, we are going to create a few new variables containing new-objects. I will do my best to explain each part.  Go to docs.microsoft.com to get full indepth descriptions of each.

System.Management.RuntimeDefinedParameterDictionary is a collection of runtime-defined parameters that are keyed based on the name of the parameter. docs.microsoft

System.Collections.ObjectModel.Collection[System.Attribute] is a collection of type System.Attribute. docs.microsoft

System.Management.Automation.ParameterAttribute creates a new cmdlet parameter. docs.microsoft

DynamicParam {
    
    # Set the dynamic parameters' name
    $ParameterName = 'MemberName'

    # 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 = 1

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

Now, we will populate the $arrSet variable with the corresponding values based on the member type selected. The $arrSet variable will be used to populate variable $ValidateSetAttribute by creating a new System.Management.Automation.ValidateSetAttribute. docs.microsoft

Next we will add the new $ValidateSetAttribute to the attribute collection.

DynamicParam {
    
    # Set the dynamic parameters' name
    $ParameterName = 'MemberName'

    ...

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

    # Generate and set the ValidateSet 
    if($MemberType -like 'User') {
        $arrSet = (Get-PWUsersByMatch).Name
    } elseif($MemberType -like 'Group') {
        $arrSet = Get-PWGroupNames
    } else {
        $arrSet = Get-PWUserListNames
    }
            
    $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)

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

Next we display a drop-down menu containing the values returned based on the member type.  The $MemberName parameter is populated with the selected value.

Finally, the corresponding ProjectWise PowerShell cmdlet is run based on the Member Type and Member Name and resulting object is returned.

BEGIN {
    $MemberName = $PSBoundParameters[$ParameterName]
    Write-Verbose -Message "Member Type: $MemberType; Member Name: $MemberName" -Verbose
} # end BEGIN

PROCESS {
    if($MemberType -like 'User') {
        Get-PWUsersByMatch -UserName $MemberName
    } elseif($MemberType -like 'Group') {
        Get-PWGroup -GroupName $MemberName
    } else {
        Get-PWUserList -UserListName $MemberName
    }
} # end PROCESS

The following example use of the Get-PWMember will pass the group object returned via the pipeline to the Get-PWGroupMember cmdlet.

Get-PWMember -MemberType Group -MemberName 'ProjectWise Administrators' | 
Get-PWGroupMember

The following example will pass the resulting user object to the Get-PWUserSetting via the pipeline

Get-PWMember -MemberType User -MemberName pwadmin | Get-PWUserSetting

Function New-PWWorkArea

The New-PWWorkArea function contains four parameters. The first two parameters are $FolderPath which is the path to the parent folder to create the new work area in. And $WorkAreaName which is obviously the name of the new work area.

[CmdletBinding()]
Param(
    [Parameter(
        Mandatory=$true,
        Position=0,
        HelpMessage="ProjectWise folder to create new Work Area in."
    )]
    [string]$FolderPath,
                       
    [Parameter(
        Mandatory=$true,
        Position=1,
        HelpMessage="Name of new Work Area."
    )]
    [string]$WorkAreaName
)

The other two parameters are dynamic parameters, $TemplateName which is the name of the Work Area template to use and $StorageArea which is the name of the storage area to be used.

The process will be the same as the first function.  The following is the DynamicParam block of code.

DynamicParam {
    # Need dynamic parameters for Template, Storage, Project Type
    # Set the dynamic parameters' name
    $paramTemplate = 'TemplateName' 
    # 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 = 1
    # Add the attributes to the attributes collection
    $AttributeCollection.Add($ParameterAttribute)
    # Create the dictionary 
    $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
    # Generate and set the ValidateSet
    $ParameterValidateSet = (Get-PWProjectTemplates).Name 
    $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ParameterValidateSet)
    # Add the ValidateSet to the attributes collection
    $AttributeCollection.Add($ValidateSetAttribute) 
    # Create and return the dynamic parameter
    $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($paramTemplate, [string], $AttributeCollection)
    $RuntimeParameterDictionary.Add($paramTemplate, $RuntimeParameter) 

    # Set the dynamic parameters' name
    $paramStorage = 'StorageArea'
    # 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 = 2 
    # Add the attributes to the attributes collection
    $AttributeCollection.Add($ParameterAttribute) 
    # Generate and set the ValidateSet 
    $ParameterValidateSet = (Get-PWStorageAreaList).Name
    $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ParameterValidateSet)
    # Add the ValidateSet to the attributes collection
    $AttributeCollection.Add($ValidateSetAttribute)
    # Create and return the dynamic parameter
    $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($paramStorage, [string], $AttributeCollection)
    $RuntimeParameterDictionary.Add($paramStorage, $RuntimeParameter)

    return $RuntimeParameterDictionary
} # end DynamicParam

 

In the following section we populate the $Template and $Storage parameters with selected values from the corresponding dynamic parameters. We then create a new work area using the New-PWRichProject cmdlet.

PROCESS {
    $Template = $PSBoundParameters[$paramTemplate]
    $Storage = $PSBoundParameters[$paramStorage]
    Write-Host "Folder: $FolderPath\$WorkAreaName; Template: $Template; Storage: $Storage"

    try { 
        $NewRichProject = New-PWRichProject -NewFolderPath "$FolderPath\$WorkAreaName" -TemplateName $Template -StorageArea $Storage -Verbose -ErrorAction Stop
        Write-Output -InputObject $NewRichProject
    } catch {
        Write-Error -Message 'Failed to create new Work Area.'
    }
} # end PROCESS

The following example use of the New-PWWorkArea function will create a new work area using the parameter values with the New-PWRichProject cmdlet.

New-PWWorkArea -FolderPath 'Test' -WorkAreaName 'MyWorkArea' -Template 'TEMPLATE' -Storage 'Storage_01' -Verbose

 


 

Below is a link to a zip file containing the two example functions.

!bmf_projectwisefunctions

Experiment with it and have fun.

Hopefully, you find this useful. Please let me know if you have any questions or comments.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s