Reputation: 1307
Consider the following toy example script test.ps1
:
Param(
[Parameter(ParameterSetName='readfile',Position=0,Mandatory=$True)]
[string] $FileName,
[Parameter(ParameterSetName='arg_pass',Mandatory=$True)]
[switch] $Ping
)
if ($Ping.isPresent) {
&$env:ComSpec /c ping $args
} else {
Get-Content $FileName
}
The desired effect would be that
.\test.ps1 FILE.TXT
displays the contents of FILE.TXT
and
.\test.ps1 -Ping -n 5 127.0.0.1
pings localhost 5 times.
Unfortunately, the latter fails with the error
A parameter cannot be found that matches parameter name 'n'. At line:1 char:18 + .\test.ps1 -Ping -n 5 127.0.0.1 + ~~ + CategoryInfo : InvalidArgument: (:) [test.ps1], ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,test.ps1
This is just a minimal example, of course.
In general, I am looking for a way to introduce a [switch]
parameter to my script that lives inside its own parameter set and when that switch is present, I want to consume all remaining arguments from the commandline and pass them on to another commandline application. What would be the way to do this in PowerShell?
Upvotes: 1
Views: 252
Reputation: 24585
You can use the ValueFromRemainingArguments
parameter attribute. I would also recommend specifying a default parameter set name in CmdletBinding
. Example:
[CmdletBinding(DefaultParameterSetName="readfile")]
param(
[parameter(ParameterSetName="readfile",Position=0,Mandatory=$true)]
[String] $FileName,
[parameter(ParameterSetName="arg_pass",Mandatory=$true)]
[Switch] $Ping,
[parameter(ParameterSetName="arg_pass",ValueFromRemainingArguments=$true)]
$RemainingArgs
)
if ( $Ping ) {
ping $RemainingArgs
}
else {
Get-Content $FileName
}
(Aside: I don't see a need for & $env:ComSpec /c
. You can run commands in PowerShell without spawning a copy of cmd.exe.)
Upvotes: 4