DynamicParams.psm1
[Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidAssignmentToAutomaticVariable', 'IsWindows', Justification = 'IsWindows doesnt exist in PS5.1' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseDeclaredVarsMoreThanAssignments', 'IsWindows', Justification = 'IsWindows doesnt exist in PS5.1' )] [CmdletBinding()] param() $baseName = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath) $script:PSModuleInfo = Import-PowerShellDataFile -Path "$PSScriptRoot\$baseName.psd1" $script:PSModuleInfo | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ } $scriptName = $script:PSModuleInfo.Name Write-Debug "[$scriptName] - Importing module" if ($PSEdition -eq 'Desktop') { $IsWindows = $true } #region [functions] - [public] Write-Debug "[$scriptName] - [functions] - [public] - Processing folder" #region [functions] - [public] - [New-DynamicParam] Write-Debug "[$scriptName] - [functions] - [public] - [New-DynamicParam] - Importing" function New-DynamicParam { <# .SYNOPSIS Creates a new dynamic parameter for a function. .DESCRIPTION Creates a new dynamic parameter for a function. .EXAMPLE dynamicparam { $DynamicParamDictionary = New-DynamicParamDictionary $dynParam = @{ Name = 'GitignoreTemplate' Alias = 'gitignore_template' Type = [string] ValidateSet = Get-GitHubGitignoreList DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam $dynParam2 = @{ Name = 'LicenseTemplate' Alias = 'license_template' Type = [string] ValidateSet = Get-GitHubLicenseList | Select-Object -ExpandProperty key DynamicParamDictionary = $DynamicParamDictionary } New-DynamicParam @dynParam2 return $DynamicParamDictionary } .OUTPUTS [void] .OUTPUTS [System.Management.Automation.RuntimeDefinedParameterDictionary] .LINK https://psmodule.io/DynamicParams/Functions/New-DynamicParam/ #> [Alias('DynamicParam')] [OutputType(ParameterSetName = 'Add to dictionary', [void])] [OutputType(ParameterSetName = 'Return parameter', [System.Management.Automation.RuntimeDefinedParameter])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSAvoidLongLines', '', Justification = 'Long links' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Function does not change state.' )] [CmdletBinding(DefaultParameterSetName = 'Return parameter')] param( # Specifies the name of the parameter. [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string] $Name, # Specifies the aliases of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [string[]] $Alias, # Specifies the data type of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [type] $Type, # Specifies the parameter set name. [Parameter(ValueFromPipelineByPropertyName)] [string] $ParameterSetName = '__AllParameterSets', # Specifies if the parameter is mandatory. # Parameter Set specific [Parameter(ValueFromPipelineByPropertyName)] [switch] $Mandatory, # Specifies the parameters positional binding. # Parameter Set specific [Parameter(ValueFromPipelineByPropertyName)] [int] $Position, # Specifies if the parameter accepts values from the pipeline. # Parameter Set specific [Parameter(ValueFromPipelineByPropertyName)] [switch] $ValueFromPipeline, # Specifies if the parameter accepts values from the pipeline by property name. # Parameter Set specific [Parameter(ValueFromPipelineByPropertyName)] [switch] $ValueFromPipelineByPropertyName, # Specifies if the parameter accepts values from the remaining command-line arguments that are not associated with another parameter. # Parameter Set specific [Parameter(ValueFromPipelineByPropertyName)] [switch] $ValueFromRemainingArguments, # Specifies the help message of the parameter. # Parameter Set specific [Parameter(ValueFromPipelineByPropertyName)] [string] $HelpMessage, # Specifies the comments of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [string] $Comment, # Specifies the validate script of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [scriptblock] $ValidateScript, # Specifies the validate regular expression pattern of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [regex] $ValidatePattern, # Specifies the validate regular expression pattern options of the parameter. # For more info see [RegexOptions](https://learn.microsoft.com/dotnet/api/system.text.regularexpressions.regexoptions). [Parameter(ValueFromPipelineByPropertyName)] [System.Text.RegularExpressions.RegexOptions[]] $ValidatePatternOptions, # Specifies the validate number of items for the parameter. [Parameter(ValueFromPipelineByPropertyName)] [ValidateCount(2, 2)] [int[]] $ValidateCount, # Specifies the validate range of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [object] $ValidateRange, # Specifies the validate set of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [object] $ValidateSet, # Specifies the validate length of the parameter. [Parameter(ValueFromPipelineByPropertyName)] [ValidateCount(2, 2)] [int[]] $ValidateLength, # Specifies if the parameter accepts null or empty values. [Parameter(ValueFromPipelineByPropertyName)] [switch] $ValidateNotNullOrEmpty, # The custom error message pattern that is displayed to the user if validation fails. # This parameter is not supported on Windows PowerShell Desktop Edition, if specified it will be ignored. # # Examples of how to use this parameter: # - `ValidatePattern` -> "The text '{0}' did not pass validation of the regular expression '{1}'". {0} is the value, {1} is the pattern. # - `ValidateSet` -> "The item '{0}' is not part of the set '{1}'. {0} is the value, {1} is the set. # - `ValidateScript` -> "The item '{0}' did not pass validation of script '{1}'". {0} is the value, {1} is the script. [Parameter(ValueFromPipelineByPropertyName)] [string] $ValidationErrorMessage, # Specifies if the parameter accepts wildcards. [Parameter(ValueFromPipelineByPropertyName)] [switch] $SupportsWildcards, # Specifies if the parameter accepts empty strings. [Parameter(ValueFromPipelineByPropertyName)] [switch] $AllowEmptyString, # Specifies if the parameter accepts null values. [Parameter(ValueFromPipelineByPropertyName)] [switch] $AllowNull, # Specifies if the parameter accepts empty collections. [Parameter(ValueFromPipelineByPropertyName)] [switch] $AllowEmptyCollection, # Specifies the dynamic parameter dictionary. [Parameter(ParameterSetName = 'Add to dictionary')] [System.Management.Automation.RuntimeDefinedParameterDictionary] $DynamicParamDictionary ) begin { $isDesktop = $PSVersionTable.PSEdition -eq 'Desktop' } process { if ($isDesktop) { if ($PSBoundParameters.ContainsKey('ValidationErrorMessage')) { Write-Warning "Unsupported parameter: 'ValidationErrorMessage' is not supported in Windows PowerShell Desktop Edition. Skipping it." } } $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] # foreach ParameterSet in ParameterSets , Key = name, Value = Hashtable $parameterAttribute = New-Object System.Management.Automation.ParameterAttribute $parameterAttribute.ParameterSetName = $ParameterSetName if ($PSBoundParameters.ContainsKey('HelpMessage')) { $parameterAttribute.HelpMessage = $HelpMessage } if ($PSBoundParameters.ContainsKey('Position')) { $parameterAttribute.Position = $Position } $parameterAttribute.Mandatory = $Mandatory $parameterAttribute.ValueFromPipeline = $ValueFromPipeline $parameterAttribute.ValueFromPipelineByPropertyName = $ValueFromPipelineByPropertyName $parameterAttribute.ValueFromRemainingArguments = $ValueFromRemainingArguments $attributeCollection.Add($parameterAttribute) if ($PSBoundParameters.ContainsKey('Alias')) { $Alias | ForEach-Object { $aliasAttribute = New-Object System.Management.Automation.AliasAttribute($_) $attributeCollection.Add($aliasAttribute) } } # TODO: Add ability to add a param doc/comment if ($PSBoundParameters.ContainsKey('ValidateSet')) { $validateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidateSet) if ($PSBoundParameters.ContainsKey('ValidationErrorMessage') -and -not $isDesktop) { $validateSetAttribute.ErrorMessage = $ValidationErrorMessage } $attributeCollection.Add($validateSetAttribute) } if ($PSBoundParameters.ContainsKey('ValidateNotNullOrEmpty')) { $validateNotNullOrEmptyAttribute = New-Object System.Management.Automation.ValidateNotNullOrEmptyAttribute $attributeCollection.Add($validateNotNullOrEmptyAttribute) } if ($PSBoundParameters.ContainsKey('ValidateLength')) { $validateLengthAttribute = New-Object System.Management.Automation.ValidateLengthAttribute($ValidateLength[0], $ValidateLength[1]) $attributeCollection.Add($validateLengthAttribute) } if ($PSBoundParameters.ContainsKey('ValidateCount')) { $validateCountAttribute = New-Object System.Management.Automation.ValidateCountAttribute($ValidateCount[0], $ValidateCount[1]) $attributeCollection.Add($validateCountAttribute) } if ($PSBoundParameters.ContainsKey('ValidateScript')) { $validateScriptAttribute = New-Object System.Management.Automation.ValidateScriptAttribute($ValidateScript) if ($PSBoundParameters.ContainsKey('ValidationErrorMessage') -and -not $isDesktop) { $validateScriptAttribute.ErrorMessage = $ValidationErrorMessage } $attributeCollection.Add($validateScriptAttribute) } if ($PSBoundParameters.ContainsKey('ValidatePattern')) { $validatePatternAttribute = New-Object System.Management.Automation.ValidatePatternAttribute($ValidatePattern) if ($PSBoundParameters.ContainsKey('ValidationErrorMessage') -and -not $isDesktop) { $validatePatternAttribute.ErrorMessage = $ValidationErrorMessage } if ($PSBoundParameters.ContainsKey('ValidatePatternOptions')) { $validatePatternAttribute.Options = $ValidatePatternOptions } $attributeCollection.Add($validatePatternAttribute) } if ($PSBoundParameters.ContainsKey('ValidateRange')) { $validateRangeAttribute = New-Object System.Management.Automation.ValidateRangeAttribute($ValidateRange) $attributeCollection.Add($validateRangeAttribute) } if ($PSBoundParameters.ContainsKey('SupportsWildcards')) { $supportsWildcardsAttribute = New-Object System.Management.Automation.SupportsWildcardsAttribute $attributeCollection.Add($supportsWildcardsAttribute) } if ($PSBoundParameters.ContainsKey('AllowEmptyString')) { $allowEmptyStringAttribute = New-Object System.Management.Automation.AllowEmptyStringAttribute $attributeCollection.Add($allowEmptyStringAttribute) } if ($PSBoundParameters.ContainsKey('AllowNull')) { $allowNullAttribute = New-Object System.Management.Automation.AllowNullAttribute $attributeCollection.Add($allowNullAttribute) } if ($PSBoundParameters.ContainsKey('AllowEmptyCollection')) { $allowEmptyCollectionAttribute = New-Object System.Management.Automation.AllowEmptyCollectionAttribute $attributeCollection.Add($allowEmptyCollectionAttribute) } $runtimeDefinedParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($Name, $Type, $attributeCollection) switch ($PSCmdlet.ParameterSetName) { 'Add to dictionary' { $DynamicParamDictionary.Add($Name, $runtimeDefinedParameter) } 'Return parameter' { return $runtimeDefinedParameter } } } end {} } Write-Debug "[$scriptName] - [functions] - [public] - [New-DynamicParam] - Done" #endregion [functions] - [public] - [New-DynamicParam] #region [functions] - [public] - [New-DynamicParamDictionary] Write-Debug "[$scriptName] - [functions] - [public] - [New-DynamicParamDictionary] - Importing" function New-DynamicParamDictionary { <# .SYNOPSIS Creates a new RuntimeDefinedParameterDictionary .DESCRIPTION Creates a new RuntimeDefinedParameterDictionary .EXAMPLE New-DynamicParamDictionary Returns a new RuntimeDefinedParameterDictionary .EXAMPLE New-DynamicParamDictionary -ParameterDefinition $param1, $param2 Outputs: ```powershell Key Value --- ----- Variable System.Management.Automation.RuntimeDefinedParameter EnvironmentVariable System.Management.Automation.RuntimeDefinedParameter ``` Returns a new RuntimeDefinedParameterDictionary with the specified parameters. .EXAMPLE DynamicParams @( @{ Name = 'Variable' Type = [string] ValidateSet = Get-Variable | Select-Object -ExpandProperty Name }, @{ Name = 'EnvironmentVariable' Type = [string] ValidateSet = Get-ChildItem -Path env: | Select-Object -ExpandProperty Name } ) Outputs: ```powershell Key Value --- ----- Variable System.Management.Automation.RuntimeDefinedParameter EnvironmentVariable System.Management.Automation.RuntimeDefinedParameter ``` Returns a new RuntimeDefinedParameterDictionary with the specified parameters. .EXAMPLE $params = @( @{ Name = 'Variable' Type = [string] ValidateSet = Get-Variable | Select-Object -ExpandProperty Name }, @{ Name = 'EnvironmentVariable' Type = [string] ValidateSet = Get-ChildItem -Path env: | Select-Object -ExpandProperty Name } ) $params | ForEach-Object { New-DynamicParam @_ } | New-DynamicParamDictionary Outputs: ```powershell Key Value --- ----- Variable System.Management.Automation.RuntimeDefinedParameter EnvironmentVariable System.Management.Automation.RuntimeDefinedParameter ``` Returns a new RuntimeDefinedParameterDictionary with the specified parameters. .LINK https://psmodule.io/DynamicParams/Functions/New-DynamicParamDictionary/ #> [Alias('DynamicParams')] [OutputType([System.Management.Automation.RuntimeDefinedParameterDictionary])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Function does not change state.' )] [CmdletBinding()] param( # An array of hashtables or RuntimeDefinedParameter objects to add to the dictionary. [Parameter(Position = 0, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [object] $ParameterDefinition ) begin { $dictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() } process { foreach ($param in $ParameterDefinition) { if ($param -is [hashtable]) { $param = New-DynamicParam @param } $dictionary.Add($param.Name, $param) } } end { return $dictionary } } Write-Debug "[$scriptName] - [functions] - [public] - [New-DynamicParamDictionary] - Done" #endregion [functions] - [public] - [New-DynamicParamDictionary] Write-Debug "[$scriptName] - [functions] - [public] - Done" #endregion [functions] - [public] #region Member exporter $exports = @{ Alias = '*' Cmdlet = '' Function = @( 'New-DynamicParam' 'New-DynamicParamDictionary' ) Variable = '' } Export-ModuleMember @exports #endregion Member exporter |