I have this script that can be called in two ways:
MyScript -foo path\to\folder
or
MyScript -bar path\to\folder
(That is, I can either pass a switch plus a folder or a string argument plus a folder.)
I have tried to put parameter declarations into my script as to reflect that syntax:
param(
[parameter(Mandatory=$false)] [switch]$foo,
[parameter(Mandatory=$false)] [String]$bar,
[parameter(Mandatory=$true)] [System.IO.FileInfo]$path
)
But then I have to pass path
explicitly to invoke the script:
MyScript -l -path path\to\folder
So (how) can I do that making both bar
and path
positional parameters?
Note: If I have picked an extraordinarily stupid syntax for invoking the script, I can still change it.
You can pass the parameters in the PowerShell function and to catch those parameters, you need to use the arguments. Generally, when you use variables outside the function, you really don't need to pass the argument because the variable is itself a Public and can be accessible inside the function.
To create a parameter set, you must specify the ParameterSetName keyword of the Parameter attribute for every parameter in the parameter set. For parameters that belong to multiple parameter sets, add a Parameter attribute for each parameter set.
The PowerShell parameter is a fundamental component of any script. A parameter is a way that developers enable script users to provide input at runtime. If a PowerShell script's behavior needs to change in some way, a parameter provides an opportunity to do so without changing the underlying code.
To pass multiple parameters you must use the command line syntax that includes the names of the parameters. For example, here is a sample PowerShell script that runs the Get-Service function with two parameters. The parameters are the name of the service(s) and the name of the Computer.
A couple of things: You need to use parameter sets to tell PowerShell that there are mutually exclusive ways to invoke your script; that is to say, you cannot use the switch and the string at the same time. The sets also serve to allow you to set the position of both $bar
and $filepath
to be at index 0. Switches don't need to be positionally placed as they are not ambiguous to the binder and be placed anywhere. Also, at least one parameter in each set should be mandatory.
function test-set {
[CmdletBinding(DefaultParameterSetName = "BarSet")]
param(
[parameter(
mandatory=$true,
parametersetname="FooSet"
)]
[switch]$Foo,
[parameter(
mandatory=$true,
position=0,
parametersetname="BarSet"
)]
[string]$Bar,
[parameter(
mandatory=$true,
position=1
)]
[io.fileinfo]$FilePath
)
@"
Parameterset is: {0}
Bar is: '{1}'
-Foo present: {2}
FilePath: {3}
"@ -f $PSCmdlet.ParameterSetName, $bar, $foo.IsPresent, $FilePath
}
The CmdletBinding
attribute is needed to specify which parameter set should be the default if the function is invoked without parameters.
Here's the syntax help for the above configuration:
PS> test-set -?
NAME
test-set
SYNTAX
test-set [-Bar] <string> [-FilePath] <FileInfo> [<CommonParameters>]
test-set [-FilePath] <FileInfo> -Foo [<CommonParameters>]
And here's the output for various invocations:
PS> test-set barval C:\temp\foo.zip
Parameterset is: BarSet
Bar is: 'barval'
-Foo present: False
FilePath: C:\temp\foo.zip
PS> test-set -foo c:\temp\foo.zip
Parameterset is: FooSet
Bar is: ''
-Foo present: True
FilePath: c:\temp\foo.zip
Hope this helps.
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