Reputation: 55
What is a good practice to handle parameters, when do I choose what option?
Example: usually I write functions like this:
function Do-Something ($variable1, $variable2, $variable3....)
{ Do Stuff }
Now apparently this is also an option:
Param(
[Parameter(Position=0,
Mandatory=$True,
ValueFromPipeline=$True)]
[string]$userName,
...
)
I can, however, not find out why to use the second, or what the advantages really are to use this.
Upvotes: 4
Views: 69
Reputation: 11274
As @ConnorLSW wrote in the above answer, validation is one of the biggest benefits. With the Param
block you're able to use Validate
attributes, like:
Function Foo
{
Param(
[Parameter(Mandatory=$true,Position=0)]
[ValidateSet("Tom","Dick","Jane")]
[String]
$Name
,
[ValidateRange(21,65)]
[Int]
$Age
,
[ValidateScript({Test-Path $_ -PathType 'Container'})]
[string]
$Path
)
Process
{
write-host "New-Foo"
}
}
You are also able to define different parameter sets, if your function should support different parameter combination. Additionally you'll also get "out-of-box" documentation via Get-Help
if you are the Mandatory
and Positional
properties of the Parameter
attribute. E.g.:
get-help Foo -Detailed
NAME
Foo
SYNTAX
Foo [-Name] {Tom | Dick | Jane} [[-Age] <int>] [-Path <string>] [<CommonParameters>]
PARAMETERS
-Age <int>
-Name <string>
-Path <string>
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
ALIASES
None
REMARKS
None
Based on the out brackets of the Age
parameter you'll that it is an optional parameter. So its all about description, validation and documentation.
Hope that helps.
Upvotes: 3
Reputation: 3326
the second Param()
block allows you to do a lot of advanced param validation.
if I need to write a short function with minimal input validation i'll use something like this:
Function Test-Port ([string]$Server,[uint16]$Port=80,[uint16]$Timeout = 3000) {
#code here
}
but if I need to write something with advanced checking like this:
function Get-SiteCert{
[CmdletBinding(DefaultParameterSetName = "Return")]
Param(
[Parameter(Mandatory=$true,Position=0)]
[string]$Server,
[Parameter(Position=1)]
[uint16]$Port=443,
[Parameter(Mandatory=$false, ParameterSetName="RawObj")]
[switch]$Raw,
[Parameter(Mandatory=$false, ParameterSetName="Export")]
[switch]$Export,
[Parameter(Mandatory=$true, ParameterSetName="Export")]
[string]$Path,
[uint16]$Timeout=3000
)
#code here
}
I'm definitely not fitting it all into the top bar, even though they're similar scripts, the second one 'does' a lot more. it's really just a case by case basis.
you can check out this link for examples of what you can do with the expansive parameters, but if you don't need these feel free to keep using whichever you prefer.
Upvotes: 6