diff --git a/examples/DynamicParam.ps1 b/examples/DynamicParam.ps1 deleted file mode 100644 index c5af60f..0000000 --- a/examples/DynamicParam.ps1 +++ /dev/null @@ -1,42 +0,0 @@ -function Test-DynParam { - [CmdletBinding()] - param ( - [Parameter()] - [ValidateSet('A', 'B', 'C')] - [string]$Param1 - ) - - DynamicParam { - $ParamDictionary = New-ParamDictionary - - $dynParam2 = @{ - Name = 'Param2' - Type = [string] - ValidateSet = Get-Process | Select-Object -ExpandProperty Name - ParamDictionary = $ParamDictionary - } - New-DynamicParam @dynParam2 - - $dynParam3 = @{ - Name = 'Param3' - Type = [string] - ValidateSet = Get-ChildItem -Path C:\ | Select-Object -ExpandProperty Name - ParamDictionary = $ParamDictionary - } - New-DynamicParam @dynParam3 - - return $ParamDictionary - } - - process { - $Param1 = $PSBoundParameters['Param1'] - $Param2 = $PSBoundParameters['Param2'] - $Param3 = $PSBoundParameters['Param3'] - - Write-Verbose "Param1: $Param1" - Write-Verbose "Param2: $Param2" - Write-Verbose "Param3: $Param3" - } -} - -Test-DynParam -Param1 A -Param3 PerfLogs -Verbose diff --git a/examples/DynamicParam2.ps1 b/examples/DynamicParam2.ps1 deleted file mode 100644 index ae770be..0000000 --- a/examples/DynamicParam2.ps1 +++ /dev/null @@ -1,43 +0,0 @@ -function Test-DynParam { - [CmdletBinding()] - param ( - [Parameter()] - [ValidateSet('A', 'B', 'C')] - [string]$Param1 - ) - DynamicParam { - $DynamicParamDictionary = New-DynamicParamDictionary - - $dynParam = @{ - Name = 'Process' - Alias = 'proc' - Type = [string] - ValidateSet = Get-Process -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name -Unique - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam - - $dynParam2 = @{ - Name = 'Service' - Alias = 'svc' - Type = [string] - ValidateSet = Get-Service -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Name -Unique - DynamicParamDictionary = $DynamicParamDictionary - } - New-DynamicParam @dynParam2 - - return $DynamicParamDictionary - } - - process { - $PSBoundParameters.Keys | ForEach-Object { - Set-Variable -Name $_ -Value $PSBoundParameters[$_] - } - - Write-Verbose "Param1: $Param1" - Write-Verbose "Process: $Process" - Write-Verbose "Service: $Service" - } -} - -Test-DynParam -Param1 A -Service SDRSVC -Verbose diff --git a/src/public/New-DynamicParam.ps1 b/src/public/New-DynamicParam.ps1 index 76bda79..6e38925 100644 --- a/src/public/New-DynamicParam.ps1 +++ b/src/public/New-DynamicParam.ps1 @@ -96,6 +96,11 @@ [Parameter()] [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()] + [System.Text.RegularExpressions.RegexOptions[]] $ValidatePatternOptions, + # Specifies the validate number of items for the parameter. [Parameter()] [ValidateCount(2, 2)] @@ -118,6 +123,16 @@ [Parameter()] [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()] + [string] $ValidationErrorMessage, + # Specifies if the parameter accepts wildcards. [Parameter()] [switch] $SupportsWildcards, @@ -139,6 +154,14 @@ [System.Management.Automation.RuntimeDefinedParameterDictionary] $DynamicParamDictionary ) + $isDesktop = $PSVersionTable.PSEdition -eq 'Desktop' + + 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 @@ -168,6 +191,9 @@ 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')) { @@ -184,10 +210,19 @@ } 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')) { diff --git a/src/public/New-DynamicParamDictionary.ps1 b/src/public/New-DynamicParamDictionary.ps1 index 78d11e2..8c762c5 100644 --- a/src/public/New-DynamicParamDictionary.ps1 +++ b/src/public/New-DynamicParamDictionary.ps1 @@ -19,5 +19,5 @@ [CmdletBinding()] param() - return [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() + [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() } diff --git a/tests/DynamicParams.Tests.ps1 b/tests/DynamicParams.Tests.ps1 index 4b8c377..b191845 100644 --- a/tests/DynamicParams.Tests.ps1 +++ b/tests/DynamicParams.Tests.ps1 @@ -17,4 +17,131 @@ Describe 'DynamicParams' { { Import-Module -Name 'DynamicParams' -Verbose -RequiredVersion 999.0.0 -Force } | Should -Not -Throw } } + + Context 'Function: New-DynamicParamDictionary' { + It 'New-DynamicParamDictionary should not throw an exception' { + { New-DynamicParamDictionary } | Should -Not -Throw + } + + It 'New-DynamicParamDictionary should return a RuntimeDefinedParameterDictionary' { + $dictionary = New-DynamicParamDictionary + $dictionary | Should -BeOfType 'System.Management.Automation.RuntimeDefinedParameterDictionary' + } + } + + Context 'Function: New-DynamicParam' { + It 'New-DynamicParam should not throw an exception' { + $dictionary = New-DynamicParamDictionary + $dynParam = @{ + Name = 'Param1' + Type = [string] + ValidateSet = 'A', 'B', 'C' + DynamicParamDictionary = $dictionary + } + { New-DynamicParam @dynParam } | Should -Not -Throw + } + + It 'New-DynamicParam should add a RuntimeDefinedParameter to the dictionary' { + $dictionary = New-DynamicParamDictionary + $dynParam = @{ + Name = 'Param1' + Type = [string] + ValidateSet = 'A', 'B', 'C' + DynamicParamDictionary = $dictionary + } + New-DynamicParam @dynParam + $dictionary.Keys | Should -Contain 'Param1' + } + } + + Context 'Integration' { + BeforeAll { + filter Test-DynParam { + [CmdletBinding()] + param ( + [Parameter()] + [ValidateSet('A', 'B', 'C')] + [string]$Param1 + ) + + DynamicParam { + $DynamicParamDictionary = New-DynamicParamDictionary + + $dynVariable = @{ + Name = 'Variable' + Type = [string] + ValidateSet = Get-Variable | Select-Object -ExpandProperty Name + DynamicParamDictionary = $DynamicParamDictionary + } + New-DynamicParam @dynVariable + + $dynEnvironmentVariable = @{ + Name = 'EnvironmentVariable' + Type = [string] + ValidateSet = Get-ChildItem -Path env: | Select-Object -ExpandProperty Name + DynamicParamDictionary = $DynamicParamDictionary + } + New-DynamicParam @dynEnvironmentVariable + + return $DynamicParamDictionary + } + + process { + $Variable = $PSBoundParameters['Variable'] + $EnvironmentVariable = $PSBoundParameters['EnvironmentVariable'] + + Write-Verbose "Variable: $Variable" + Write-Verbose "EnvironmentVariable: $EnvironmentVariable" + } + } + + filter Test-DynParam2 { + [CmdletBinding()] + param ( + [Parameter()] + [ValidateSet('A', 'B', 'C')] + [string]$Param1 + ) + + DynamicParam { + $DynamicParamDictionary = New-DynamicParamDictionary + + $dynVariable = @{ + Name = 'Variable' + Type = [string] + ValidateSet = Get-Variable | Select-Object -ExpandProperty Name + DynamicParamDictionary = $DynamicParamDictionary + } + New-DynamicParam @dynVariable + + $dynEnvironmentVariable = @{ + Name = 'EnvironmentVariable' + Type = [string] + ValidateSet = Get-ChildItem -Path env: | Select-Object -ExpandProperty Name + DynamicParamDictionary = $DynamicParamDictionary + } + New-DynamicParam @dynEnvironmentVariable + + return $DynamicParamDictionary + } + + process { + $PSBoundParameters.Keys | ForEach-Object { + Set-Variable -Name $_ -Value $PSBoundParameters[$_] + } + + Write-Verbose "Variable: $Variable" + Write-Verbose "EnvironmentVariable: $EnvironmentVariable" + } + } + } + + It 'Test-DynParam should not throw an exception' { + { Test-DynParam -Variable HOME -EnvironmentVariable RUNNER_OS -Verbose } | Should -Not -Throw + } + + It 'Test-DynParam2 should not throw an exception' { + { Test-DynParam2 -Variable HOME -EnvironmentVariable RUNNER_OS -Verbose } | Should -Not -Throw + } + } }