Jos
Jos

Reputation: 55

Proper use of parameters

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

Answers (2)

Moerwald
Moerwald

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

colsw
colsw

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

Related Questions