In the example in the powershell documentation you need to implement a class, like:
Class SoundNames : System.Management.Automation.IValidateSetValuesGenerator { ... }
But, how can you do this in a script based cmdlet? (See "Parameters in scripts" in about_Scripts).
In a script cmdlet the first line must be param( ... ).
Unless "SoundNames" is already defined, then it fails with Unable to find type [SoundNames]
If this type is already defined in the powershell session, this works ... but I'd like a stand-alone script that doesn't require the user do something first to define this type (e.g. dot-sourcing some other file).
I want to define a parameter that accepts only *.txt filenames (for existing files in a specific directory).
You can't do this in a (stand-alone) script, for the reason you state yourself:
The param block (possibly preceded by a [CmdletBinding()] attribute, must be at the very start of the file (leaving using statements aside).
This precludes defining a custom class that implements the IValidateSetValuesGenerator interface for use in your param block.
To work around this limitation, use a [ValidateScript()] attribute:
param(
[ValidateScript({
if (-not (Get-Item -ErrorAction Ignore "$_.txt")) {
throw "$_ is not the (base) name of a *.txt file in the current dir."
}
return $true
})]
[string] $FileName
)
Note that this doesn't give you tab-completion the way that IValidateSetValuesGenerator-based validation would automatically give you.
To also provide tab-completion, additionally use an [ArgumentCompleter()] attribute:
param(
[ValidateScript({
if (-not (Get-Item -ErrorAction Ignore "$_.txt")) {
throw "$_ is not the (base) name of a *.txt file in the current dir."
}
return $true
})]
[ArgumentCompleter({
param($cmd, $param, $wordToComplete)
(Get-Item "$wordToComplete*.txt").BaseName
})]
[string] $FileName
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With