Defining parameter sets

A parameter set in PowerShell groups different parameters together. In some cases, this is used to change the output of a command; in others, it provides a different way of supplying a piece of information. For example, the output from the Get-Process command changes if the Module parameter or, to a lesser extent, the IncludeUserName parameter are supplied. The Get-ChildItem command also has two parameter sets: one that accepts a Path with wildcard support, and another that accepts a LiteralPath that does not support wildcards. That is, it has two different ways of supplying essentially the same information. Parameter sets are declared using the ParameterSetName property of the Parameter attribute.
The following example has two parameter sets; each parameter set contains a single parameter:

function Get-InputObject {
[CmdletBinding()]
param (
[Parameter(ParameterSetName = 'FirstSetName')]
$Parameter1,

[Parameter(ParameterSetName = 'SecondSetName')]
$Parameter2
)
}

As neither parameter set is the default, attempting to run the command using a positional parameter only will result in an error:

PS> Get-InputObject value
Get-InputObject : Parameter set cannot be resolved using the specified named parameters.
At line:1 char:1
+ Get-InputObject value
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-InputObject], ParameterBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,Get-InputObject

This can be resolved by setting a value for the DefaultParameterSetName property in the CmdletBinding attribute:

[CmdletBinding(DefaultParameterSetName = 'FirstSetName')]

Alternatively, an explicit position might be defined for one of the parameters; the set will be selected on the basis of explicit position:

[Parameter(Position = 1, ParameterSetName = 'FirstSetName')]
$Parameter1

The name of the parameter set in use within a function is visible using the ParameterSetName property of the pscmdlet automatic variable, that is $pscmdlet.ParameterSetName. The value may be used to choose actions within the body of a function. The following example shows a possible implementation that tests the value of ParameterSetName. The function accepts the name of a service as a string, a service object from Get-Service, or a service returned from the Win32_Service class. The function finds the process associated with that service:

function Get-ServiceProcess {
[CmdletBinding(DefaultParameterSetName = 'ByName')]
param (
[Parameter(Mandatory, Position = 1, ParameterSetName = 'ByName')]
[String]$Name,

[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FromService')]
[System.ServiceProcess.ServiceController]$Service,


[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'FromCimService')]
[PSTypeName('Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Service')]
[CimInstance]$CimService
)

process {
if ($pscmdlet.ParameterSetName -eq 'FromService') {
$Name = $Service.Name
}
if ($Name) {
$params = @{
ClassName = 'Win32_Service'
Filter = 'Name="{0}"' -f $Name
Property = 'Name', 'ProcessId', 'State'
}
$CimService = Get-CimInstance @params
}
if ($CimService.State -eq 'Running') {
Get-Process -Id $CimService.ProcessId
} else {
Write-Error ('The service {0} is not running' -f $CimService.Name)
}
}
}

The previous function accepts several different parameters. Each parameter is ultimately used to get to a value for the $CimService variable (or parameter), which has a ProcessID property associated with the service. Each of the examples so far has shown a parameter that is a member of a single, explicitly declared set. A parameter that does not describe a ParameterSetName is automatically part of every set. 
In the following example,
Parameter1 is part of every parameter set, Parameter2 is in a named set only:

function Test-ParameterSet {
[CmdletBinding(DefaultParameterSetName = 'Default')]
param (
[Parameter(Mandatory, Position = 1)]
$Parameter1,

[Parameter(ParameterSetName = 'NamedSet')]
$Parameter2
)
}

Get-Command may be used to show the syntax for the command; this shows there are two different parameter sets, both of which require Parameter1:

PS> Get-Command Test-ParameterSet -Syntax

Test-ParameterSet [-Parameter1] <Object> [<CommonParameters>]

Test-ParameterSet [-Parameter1] <Object> [-Parameter2 <Object>] [<CommonParameters>]

Parameters that do not use the Parameter attribute are also automatically part of all parameter sets. A parameter may also be added to more than one parameter set. This is achieved by using more than one Parameter attribute on a parameter:

function Test-ParameterSet {
[CmdletBinding(DefaultParameterSetName = 'NamedSet1')]
param (
[Parameter(Mandatory)]
$Parameter1,

[Parameter(Mandatory, ParameterSetName = 'NamedSet2')]
$Parameter2,


[Parameter(Mandatory, ParameterSetName = 'NamedSet3')]
$Parameter3,

[Parameter(Mandatory, ParameterSetName = 'NamedSet2')]
[Parameter(ParameterSetName = 'NamedSet3')]

$Parameter4
)
}

In the preceding example, Parameter1 is in all parameter sets. Parameter2 is in NamedSet2 only. Parameter3 is in NamedSet3 only. Parameter4 is mandatory in NamedSet2, and optional in NamedSet3.

This interplay of parameter sets is complex and difficult to describe without a complex command to use the parameters. Many existing commands use complex parameter sets and their parameter sets may be explored. For example, the parameter block for the Get-Process command may be shown by running the following command:

[System.Management.Automation.ProxyCommand]::GetParamBlock((Get-Command Get-Process))
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.146.139