I’m currently writing a simple PowerShell(5) script. It should take user input and then perform some tasks based on the input. I assign ValidateScript to the input parameter to validate user input. According to the PowerShell documentation, validation occurs before the code runs, so I’m changing the value of the user’s input. However, this is causing an error.
Consider following simple example.
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateScript({ $_ -gt 0 })]
[int]$InputParameter
)
process {
$InputParameter = -1
}
}
Running
TEST-FUNCTION 0
Yields an error
TEST-FUNCTION : Cannot validate argument on parameter 'InputParameter'. The " $_ -gt 0 " validation script for the
argument with value "0" did not return a result of True. Determine why the validation script failed, and then try the
command again.
At line:1 char:15
+ TEST-FUNCTION 0
+ ~
+ CategoryInfo : InvalidData: (:) [TEST-FUNCTION], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,TEST-FUNCTION
This makes sense, as it's not passing the initial validation.
However, running
TEST-FUNCTION 1
also yields an error.
The variable cannot be validated because the value -1 is not a valid value for the InputParameter variable.
At line:12 char:9
+ $InputParameter = -1
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ValidationMetadataException
+ FullyQualifiedErrorId : ValidateSetFailure
The two function calls give two different errors. I’m not sure why I can’t change the value of the parameter after it has passed validation. Is there any workaround that can prevent the second round of evaluation? Thanks!
Because the attribute gets attached to the PSVariable
metadata, simple example no function needed:
[ValidateScript({ $_ -gt 0 })]
[int] $InputParameter = 1
(Get-Variable InputParameter).Attributes |
Where-Object TypeId -EQ ([System.Management.Automation.ValidateScriptAttribute])
# ErrorMessage ScriptBlock TypeId
# ------------ ----------- ------
# $_ -gt 0 System.Management.Automation.ValidateScriptAttribute
Since .Attributes
is a collection, you could remove it but really it's much easier to just use a different variable name in your function:
$psvar = Get-Variable InputParameter
$attributeToRemove = $psvar.Attributes |
Where-Object TypeId -EQ ([System.Management.Automation.ValidateScriptAttribute])
$InputParameter = -1
# MetadataError: The variable cannot be validated because the value -1 is not a valid....
$null = $psvar.Attributes.Remove($attributeToRemove)
$InputParameter = -1 # OK