I have a powershell script that starts with
Param([switch]$NoDownload, [switch]$NoUnpack, [switch]$NoExtract, [switch]$NoImport, [switch]$NoBackup)
and I was very happy because I thought that it would provide automatic parameter validation. Until one day I made a mistake and wrote:
powershell -f myscript.ps1 -NoDowload
(notice the lack of n), and it happily downloaded something I didn't want it to.
How do I tell the powershell parameter handling machinery that the only valid parameters are the ones I explicitly state in the Param
statement?
CodePudding user response:
Add a CmdletBinding
attribute to the param()
block - this makes PowerShell treat your script/function like a cmdlet - rather than a "simple" function - and it will apply much more rigorous parameter binding validation, including throwing errors when you attempt to bind a non-existing parameter name:
[CmdletBinding()]
param(
[switch]$NoDownload,
[switch]$NoUnpack,
[switch]$NoExtract,
[switch]$NoImport,
[switch]$NoBackup
)
PS ~> .\myScript.ps1 -NoDowload
myScript.ps1 : A parameter cannot be found that matches parameter name 'NoDowload'.
At line:1 char:16
.\myScript.ps1 -NoDowload
~~~~~~~~~~
CategoryInfo : InvalidArgument: (:) [myScript.ps1], ParentContainsErrorRecordException
FullyQualifiedErrorId : NamedParameterNotFound,myScript.ps1
Adding an explicit [Parameter()]
attribute to any defined parameter will also implicitly make PowerShell treat your script/function as "advanced", even in the absence of a [CmdletBinding()]
attribute:
param(
[switch]$NoDownload,
[switch]$NoUnpack,
[switch]$NoExtract,
[switch]$NoImport,
[switch]$NoBackup,
[Parameter(Mandatory = $false, DontShow = $true)]
$DummyParameterThatTriggersCmdletBinding
)