Skip to content

Instantly share code, notes, and snippets.

@0xNinshu
Last active January 2, 2024 05:54
Show Gist options
  • Save 0xNinshu/64426e6e51933f176634499e17ebfdd7 to your computer and use it in GitHub Desktop.
Save 0xNinshu/64426e6e51933f176634499e17ebfdd7 to your computer and use it in GitHub Desktop.
PowerShell function to create runtime defined dynamic parameters.
#Requires -PSEdition Core
using namespace System;
using namespace System.IO;
using namespace System.Reflection;
using namespace System.Collections.Generic;
using namespace System.Management.Automation;
using namespace System.Management.Automation.Language;
using namespace System.Collections.ObjectModel;
function New-RuntimeDefinedParameter {
<#
.SYNOPSIS
Simplifies defining runtime Parameters for a function.
.DESCRIPTION
Instead of many lines of code for each Parameter defined in the DynamicParam block of an Advanced function, this function can be used to define each runtime Parameter in 1-2 lines of code.
Microsoft Learn Example of defining one runtime Parameter:
$ParameterAttribute = [System.Management.Automation.ParameterAttribute]@{
ParameterSetName = "ByRegistryPath"
Mandatory = $false
}
$AttributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
$AttributeCollection.Add($ParameterAttribute)
$dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new(
'KeyCount', [Int32], $AttributeCollection
)
$ParamDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
$ParamDictionary.Add('KeyCount', $dynParam1)
return $ParamDictionary
Simplified version using this function:
$RuntimeParamDictionary = [RuntimeDefinedParameterDictionary]::new()
$RuntimeParamDictionary.Add('$KeyCount', $(New-RuntimeDefinedParameter -ParameterName 'KeyCount' -ParameterTypeName [int] -ParameterSetName "ByRegistryPath"))
return $RuntimeParamDictionary
.PARAMETER ParameterName
The ParameterName argument specifies the name of runtime Parameter that is returned by the function.
.PARAMETER ParameterTypeName
The ParameterTypeName argument specifies the name of runtime Parameter that is returned by the function.
.PARAMETER ParameterSetName
The ParameterSetName argument specifies the Parameter set a runtime Parameter belongs to.
.PARAMETER Attributes
A list of Attributes to add to the runtime Parameter. You you must surround your expression with '()' if defining the Attributes in line. Attributes could include Alias, Validation, etc.
.PARAMETER HelpMessage
The HelpMessage argument specifies a string that contains a brief description of the runtime Parameter or its value.
.PARAMETER HelpMessageBaseName
Specifies the location where resource identifiers reside for the runtime defined Parameter localized help.
.PARAMETER HelpMessageResourceId
Specifies the resource identifier for a help message.
.PARAMETER Position
The Position argument determines whether the runtime Parameter name is required when the Parameter is used in a command.
.PARAMETER Mandatory
The Mandatory argument indicates that the runtime Parameter is required.
.PARAMETER ValueFromPipeline
The ValueFromPipeline argument indicates that the runtime Parameter accepts input from a pipeline object.
.PARAMETER ValueFromPipelineByPropertyName
The ValueFromPipelineByPropertyName argument indicates that the runtime Parameter accepts input from a property of a pipeline object.
.PARAMETER ValueFromRemainingArguments
The ValueFromRemainingArguments argument indicates that the runtime Parameter accepts all the Parameter's values in the command that aren't assigned to other Parameters of the function.
.PARAMETER DontShow
The DontShow argument indicates that the runtime Parameter will be hidden.
.EXAMPLE
DynamicParam {
if(<SomeCondition>) {
$RuntimeParamDictionary = [RuntimeDefinedParameterDictionary]::new()
$RuntimeParamDictionary.Add('MyParam', $(New-RuntimeDefinedParameter -ParameterName 'MyParam' -ParameterTypeName [string] -ValueFromPipelineByPropertyName -ParameterSetName "Paramset1"))
return $RuntimeParamDictionary
}
}
.EXAMPLE
DynamicParam {
# You can also define validation Attributes on the RuntimeDefinedParameter
switch ($Condition)
Condition1
{
$RuntimeParamDictionary = [RuntimeDefinedParameterDictionary]::new()
$RuntimeParamDictionary.Add('MyParam', $(New-RuntimeDefinedParameter -ParameterName 'MyParam' -ParameterTypeName [string] -ValueFromPipelineByPropertyName -ParameterSetName "Paramset1"))
return $RuntimeParamDictionary
}
}
.LINK
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced_Parameters?view=powershell-7.3#dynamic-Parameters
#>
[CmdletBinding(PositionalBinding = $false)]
[OutputType([RuntimeDefinedParameter])]
Param (
[Parameter(Mandatory, ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][string]$ParameterName,
[Parameter(Mandatory, ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][PSTypeName]$ParameterTypeName,
[Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()]$Value,
[Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][switch]$IsSet,
[Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][Attribute[]]$Attributes,
[Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][string]$ParameterSetName,
[Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][string]$HelpMessage,
[Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][string]$HelpMessageBaseName,
[Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][string]$HelpMessageResourceId,
[Parameter(ValueFromPipelineByPropertyName)][ValidateScript({ $_ -ge 0 })][int]$Position,
# [Parameter(ValueFromPipelineByPropertyName)][ValidateNotNullOrEmpty()][string]$ExperimentName,
# [Parameter(ValueFromPipelineByPropertyName)][ValidateSet([ExperimentActionOptions])][string]$ExperimentAction,
[Parameter(ValueFromPipelineByPropertyName)][switch]$Mandatory,
[Parameter(ValueFromPipelineByPropertyName)][switch]$ValueFromPipeline,
[Parameter(ValueFromPipelineByPropertyName)][switch]$ValueFromPipelineByPropertyName,
[Parameter(ValueFromPipelineByPropertyName)][switch]$ValueFromRemainingArguments,
[Parameter(ValueFromPipelineByPropertyName)][switch]$DontShow
)
Begin {
$ParameterAttributes = [ParameterAttribute]::new()
}
Process {
try {
foreach ($Param in $PSBoundParameters.Keys) {
if (-not ($Param.Equals("ParameterName") -or $Param.Equals("ParameterTypeName") -or $Param.Equals("Value") -or $Param.Equals("Attributes"))) {
$ParameterAttributes.$Param = $PSBoundParameters.$Param
}
}
$RuntimeParam = [RuntimeDefinedParameter]@{
Name = $ParameterName
ParameterType = $ParameterTypeName.Type
Value = $Value
IsSet = $IsSet
}
$RuntimeParam.Attributes.Add($ParameterAttributes)
foreach ($Attribute in $Attributes) {
$RuntimeParam.Attributes.Add($Attribute)
}
}
catch {
Write-Error $_
}
}
End {
return $RuntimeParam
}
}
# Class ExperimentActionOptions : IValidateSetValuesGenerator {
# [string[]] GetValidValues () {
# $ExperimentActions = [ExperimentAction].GetEnumValues()
# return [string[]]$ExperimentActions
# }
# }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment