2

I am trying to use a dynamic parameter in PowerShell, but the value for the parameter doesn't seem to exist after I have run through my script.

[CmdletBinding()]
Param (
    [Parameter(
         Mandatory=$true,
         Position=0,
         HelpMessage = "The entity ID for the Version"
    )]
    [string]$TPVersionID,

    [Parameter(
         Mandatory=$true,
         Position=1,
         HelpMessage = ""
    )]
    [string]$VersionNumber,

    [Parameter(
         Mandatory=$true,
         Position=2,
         HelpMessage = "This is a boolean value; enter any value to make it True, leave it blank to make it False."
    )]
    [bool]$PullVersionDoc
)


function Get-VersionParam{
    [CmdletBinding()]
    Param ([string]$TPVersionID, [string]$VersionNumber, [bool]$PullVersionDoc?)
    DynamicParam {
        if ($PullVersionDoc) {
            write-host("HEY!")

            $attributes = new-object System.Management.Automation.ParameterAttribute
            $attributes.Position = 3
            $attributes.Mandatory = $true
            $attributeCollection = new-object `
                -Type System.Collections.ObjectModel.Collection[System.Attribute]
            $attributeCollection.Add($attributes)

            $dynParam1 = new-object `
                -Type System.Management.Automation.RuntimeDefinedParameter('VersionDocumentID', [Int32], $attributeCollection)

            $paramDictionary = new-object `
                -Type System.Management.Automation.RuntimeDefinedParameterDictionary
            $paramDictionary.Add('VersionDocumentID', $dynParam1)
            return $paramDictionary
        }
    }
}


Get-VersionParam


#Write-Host "Dynamic Parameter PullVersionDoc? = " $PullVersionDoc
Write-Host $PSBoundParameters

I want the script to ask for a [VersionDocumentID] if the boolean value for [PullVersionDoc] is TRUE to use later on in the script, but when I write out the [$PSBoundParameters] the parameter doesn't exist. How did I get the value so that I can use it?

4
  • $a = Get-VersionParam; Write-host $a Commented Feb 18, 2017 at 17:34
  • There's also no point in using a [bool] parameter. Use [switch] instead. This way you add the param name to make Switch True or leave it off and it will evaluate to False. Also, you access $PSBoundParameters[$ParameterName] in the Begin block and work on items within the Process block. Commented Feb 19, 2017 at 1:09
  • I'm not sure I understand. The VersionDocumentID parameter will only exist inside the function, unless you add something like $script:VersionDocumentID = $VersionDocumentID to your function body (or outputs the value and store it like @4c74356b41 showed) . Your function doesn't do anything except ask for values it never uses. Commented Feb 19, 2017 at 12:54
  • I agree with @FrodeF. which prompted me to post my complete Dynamic Param example script in the hopes it will assist the OP. Commented Feb 19, 2017 at 20:46

1 Answer 1

4

Here's how I tried using dynamic parameters to get Configuration Manager logs.

Credit goes to the blog post here.

Usage: Get-CCMLogs -ComputerNames -Remote -RemoteLogName <Tab to complete lognames>

Local usage: Get-CCMLogs -ComputerNames -LocalLogName <Tab to complete lognames>

The dynamic parameter will return a remote log name if the switch -Remote is entered or return a local log name if the switch -Remote is not entered.

Function Get-CCMLogs {

    [CmdletBinding()]

    Param(
        [Parameter(Mandatory=$false,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            HelpMessage="Give me a list of computer names!")]
        [Alias('Hostname','cn')]
        [string[]]$ComputerNames = $env:COMPUTERNAME,

        [switch]$Remote
    )

    DynamicParam{

        If ($Remote) {

            $ParameterName = 'RemoteLogName'

            $RunTimeDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]

            $ParamAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParamAttribute.Mandatory = $true
            $ParamAttribute.Position = 1

            $AttributeCollection.Add($ParamAttribute)

            $ValidateItems = Get-ChildItem -Path "\\$ComputerNames\C$\Windows\CCM\Logs" | Where {$_ -notmatch '\d+'} | Select -ExpandProperty FullName
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidateItems)

            $AttributeCollection.Add($ValidateSetAttribute)

            $RunTimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)

            $RunTimeDictionary.Add($ParameterName, $RunTimeParam)

            Return $RunTimeDictionary
        }
        else {
            $ParameterName = 'LocalLogName'

            $RunTimeDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]

            $ParamAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParamAttribute.Mandatory = $true
            $ParamAttribute.Position = 1

            $AttributeCollection.Add($ParamAttribute)

            $ValidateItems = Get-ChildItem -Path C:\Windows\CCM\Logs | Select -ExpandProperty FullName | Where {$_ -notmatch '\d+'}
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidateItems)

            $AttributeCollection.Add($ValidateSetAttribute)

            $RunTimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)

            $RunTimeDictionary.Add($ParameterName, $RunTimeParam)

            Return $RunTimeDictionary
        }
    }

    Begin{
        $LogName = $PSBoundParameters[$ParameterName]
    }

    Process{
        cmtrace.exe $LogName
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.