Home > Back-end >  What is the simplest form of Dynamic Parameters?
What is the simplest form of Dynamic Parameters?

Time:12-30

Trying to get a better understanding of Dynamic Parameters, but something keeps bothering me. All examples I've found across the outer-webs (internet), the parameter attributes are always defined/included.

Here's what I'm working with:

Function Test-DynamicParameters {
[cmdletbinding()]
    Param (
        [System.IO.DirectoryInfo]$Path
    )
    DynamicParam
    {
        if ($Path.Extension) {
              $parameterAttribute = [System.Management.Automation.ParameterAttribute]@{
                  Mandatory = $false
              }

              $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
              $attributeCollection.Add($parameterAttribute)

              $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new(
                'TestSwitch', [switch], $attributeCollection
              )

              $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
              $paramDictionary.Add('TestSwitch', $dynParam1)
              $paramDictionary
        }
    }
    Begin { }
    Process
    {
        $PSBoundParameters
    }
    End { }
}

. . .currently have tried numerous combinations of removing certain lines/code to see what would make my Dynamic Parameter show, but nothing works without the attributes being declared. Is this necessary?

Question: what is the simplest form of Dynamic Parameter declaration that I would need for it to work?

For Example - can it just be shortened to where I only define just the name? Or, would PowerShell insist a type is specified instead of defaulting to [object]? Something like:

$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
$paramDictionary.Add('TestSwitch')
$paramDictionary

CodePudding user response:

What kind of behavior are you looking for? Because dynamic parameters are usually not needed, even if the auto-completion is dynamic.

For example you could do

  • autocomplete module names for Get-Command -Module
  • or search for files by filetype, only complete filetypes if they exist in that directory

Windows Powershell

You can use DynamicValidateSet pattern in WindowsPowershell

gif using DynamicValidateSet

https://img.codepudding.com/202112/7be09b07431a448686c2e2b0c715e495.gif

New in PowerShell

6 adds Suggestions

New: [IValidateSetValuesGenerator] and [ArgumentCompletions]

It autocompletes like [ValidateSet], but the user is still free to enter others.

Note, [ArgumentCompletions] and [ArgumentCompleter] are two different classes.

[Parameter(Mandatory)]
[ArgumentCompletions('Fruits', 'Vegetables')]
[string]$Type,

7.2 Generic Completers

New [ArgumentCompleter] attribute with the [IArgumentCompleterFactory] interface

from the docs:

[DirectoryCompleter(ContainingFile="pswh.exe", Depth=2)]

[DateCompleter(WeekDay='Monday', From="LastYear")]

[GitCommits(Branch='release')]

CodePudding user response:

You can’t as the function add of the type System.Management.Automation.RuntimeDefinedParameterDictionary require to provide a key and value which is exactly a String (key) and a System::Management::Automation::RuntimeDefinedParameter for the value. For more information you can check the class documentation here https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.runtimedefinedparameterdictionary?view=powershellsdk-7.0.0. I have tested on my side and you need at least the ParameterAttribute Mandatory set to true in order to make it run, and the key/name used in the RuntimeDefinedParameter must match the key used in the dictionnary when you add it. So the minimum code that you need should be like this:

       Function Test-DynamicParameters {
[cmdletbinding()]
    Param (
        [System.IO.FileSystemInfo ]$Path
    )
    DynamicParam
    {
        if ($Path.Extension) {
              $parameterAttribute = [System.Management.Automation.ParameterAttribute]@{
               Mandatory = $true
              }

              $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
              $attributeCollection.Add($parameterAttribute)

              $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new("TestSwitch", [string], $attributeCollection)

              $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
              $paramDictionary.Add('TestSwitch', $dynParam1)
              $paramDictionary
        }
    }
    Begin { }
    Process
    {
        $PSBoundParameters
    }
    End { }
}
$FileNamePath = "C:\tmp\stackoverflow\test.txt";
$path = (Get-Item $FileNamePath )
Test-DynamicParameters -Path $path
  • Related