Adding Parameter Sets to a Cmdlet
Things to Know About Parameter Sets
Windows PowerShell defines a parameter set as a group of parameters that operate together. By grouping the parameters of a cmdlet, you can create a single cmdlet that can change its functionality based on what group of parameters the user specifies.
An example of a cmdlet that uses two parameter sets to define different functionalities is the
Get-EventLog
cmdlet that is provided by Windows PowerShell. This cmdlet returns different
information when the user specifies the List
or LogName
parameter. If the LogName
parameter is
specified, the cmdlet returns information about the events in a given event log. If the List
parameter is specified, the cmdlet returns information about the log files themselves (not the event
information they contain). In this case, the List
and LogName
parameters identify two separate
parameter sets.
Two important things to remember about parameter sets is that the Windows PowerShell runtime uses only one parameter set for a particular input, and that each parameter set must have at least one parameter that is unique for that parameter set.
To illustrate that last point, this Stop-Proc cmdlet uses three parameter sets: ProcessName
,
ProcessId
, and InputObject
. Each of these parameter sets has one parameter that is not in the
other parameter sets. The parameter sets could share other parameters, but the cmdlet uses the
unique parameters ProcessName
, ProcessId
, and InputObject
to identify which set of parameters
that the Windows PowerShell runtime should use.
Declaring the Cmdlet Class
The first step in cmdlet creation is always naming the cmdlet and declaring the .NET class that implements the cmdlet. For this cmdlet, the lifecycle verb "Stop" is used because the cmdlet stops system processes. The noun name "Proc" is used because the cmdlet works on processes. In the declaration below, note that the cmdlet verb and noun name are reflected in the name of the cmdlet class.
Note
For more information about approved cmdlet verb names, see Cmdlet Verb Names.
The following code is the class definition for this Stop-Proc cmdlet.
[Cmdlet(VerbsLifecycle.Stop, "Proc",
DefaultParameterSetName = "ProcessId",
SupportsShouldProcess = true)]
public class StopProcCommand : PSCmdlet
<Cmdlet(VerbsLifecycle.Stop, "Proc", DefaultParameterSetName:="ProcessId", _
SupportsShouldProcess:=True)> _
Public Class StopProcCommand
Inherits PSCmdlet
Declaring the Parameters of the Cmdlet
This cmdlet defines three parameters needed as input to the cmdlet (these parameters also define the
parameter sets), as well as a Force
parameter that manages what the cmdlet does and a PassThru
parameter that determines whether the cmdlet sends an output object through the pipeline. By
default, this cmdlet does not pass an object through the pipeline. For more information about these
last two parameters, see
Creating a Cmdlet that Modifies the System.
Declaring the Name Parameter
This input parameter allows the user to specify the names of the processes to be stopped. Note that
the ParameterSetName
attribute keyword of the
System.Management.Automation.Parameterattribute
attribute specifies the ProcessName
parameter set for this parameter.
[Parameter(
Position = 0,
ParameterSetName = "ProcessName",
Mandatory = true,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true,
HelpMessage = "The name of one or more processes to stop. Wildcards are permitted."
)]
[Alias("ProcessName")]
public string[] Name
{
get { return processNames; }
set { processNames = value; }
}
private string[] processNames;
<Parameter(Position:=0, ParameterSetName:="ProcessName", _
Mandatory:=True, _
ValueFromPipeline:=True, ValueFromPipelineByPropertyName:=True, _
HelpMessage:="The name of one or more processes to stop. " & _
"Wildcards are permitted."), [Alias]("ProcessName")> _
Public Property Name() As String()
Get
Return processNames
End Get
Set(ByVal value As String())
processNames = value
End Set
End Property
Private processNames() As String
Note also that the alias "ProcessName" is given to this parameter.
Declaring the Id Parameter
This input parameter allows the user to specify the identifiers of the processes to be stopped. Note
that the ParameterSetName
attribute keyword of the
System.Management.Automation.Parameterattribute
attribute specifies the ProcessId
parameter set.
[Parameter(
ParameterSetName = "ProcessId",
Mandatory = true,
ValueFromPipelineByPropertyName = true,
ValueFromPipeline = true
)]
[Alias("ProcessId")]
public int[] Id
{
get { return processIds; }
set { processIds = value; }
}
private int[] processIds;
<Parameter(ParameterSetName:="ProcessId", _
Mandatory:=True, _
ValueFromPipelineByPropertyName:=True, _
ValueFromPipeline:=True), [Alias]("ProcessId")> _
Public Property Id() As Integer()
Get
Return processIds
End Get
Set(ByVal value As Integer())
processIds = value
End Set
End Property
Private processIds() As Integer
Note also that the alias "ProcessId" is given to this parameter.
Declaring the InputObject Parameter
This input parameter allows the user to specify an input object that contains information about the
processes to be stopped. Note that the ParameterSetName
attribute keyword of the
System.Management.Automation.Parameterattribute
attribute specifies the InputObject
parameter set for this parameter.
[Parameter(
ParameterSetName = "InputObject",
Mandatory = true,
ValueFromPipeline = true)]
public Process[] InputObject
{
get { return inputObject; }
set { inputObject = value; }
}
private Process[] inputObject;
<Parameter(ParameterSetName:="InputObject", _
Mandatory:=True, ValueFromPipeline:=True)> _
Public Property InputObject() As Process()
Get
Return myInputObject
End Get
Set(ByVal value As Process())
myInputObject = value
End Set
End Property
Private myInputObject() As Process
Note also that this parameter has no alias.
Declaring Parameters in Multiple Parameter Sets
Although there must be a unique parameter for each parameter set, parameters can belong to more than one parameter set. In these cases, give the shared parameter a System.Management.Automation.Parameterattribute attribute declaration for each set to which that the parameter belongs. If a parameter is in all parameter sets, you only have to declare the parameter attribute once and do not need to specify the parameter set name.
Overriding an Input Processing Method
Every cmdlet must override an input processing method, most often this will be the System.Management.Automation.Cmdlet.ProcessRecord method. In this cmdlet, the System.Management.Automation.Cmdlet.ProcessRecord method is overridden so that the cmdlet can process any number of processes. It contains a Select statement that calls a different method based on which parameter set the user has specified.
protected override void ProcessRecord()
{
switch (ParameterSetName)
{
case "ProcessName":
ProcessByName();
break;
case "ProcessId":
ProcessById();
break;
case "InputObject":
foreach (Process process in inputObject)
{
SafeStopProcess(process);
}
break;
default:
throw new ArgumentException("Bad ParameterSet Name");
} // switch (ParameterSetName...
} // ProcessRecord
Protected Overrides Sub ProcessRecord()
Select Case ParameterSetName
Case "ProcessName"
ProcessByName()
Case "ProcessId"
ProcessById()
Case "InputObject"
Dim process As Process
For Each process In myInputObject
SafeStopProcess(process)
Next process
Case Else
Throw New ArgumentException("Bad ParameterSet Name")
End Select
End Sub 'ProcessRecord ' ProcessRecord
The Helper methods called by the Select statement are not described here, but you can see their implementation in the complete code sample in the next section.
Code Sample
For the complete C# sample code, see StopProcessSample04 Sample.
Defining Object Types and Formatting
Windows PowerShell passes information between cmdlets using .NET objects. Consequently, a cmdlet might need to define its own type, or the cmdlet might need to extend an existing type provided by another cmdlet. For more information about defining new types or extending existing types, see Extending Object Types and Formatting.
Building the Cmdlet
After implementing a cmdlet, you must register it with Windows PowerShell through a Windows PowerShell snap-in. For more information about registering cmdlets, see How to Register Cmdlets, Providers, and Host Applications.
Testing the Cmdlet
When your cmdlet has been registered with Windows PowerShell, test it by running it on the command
line. Here are some tests that show how the ProcessId
and InputObject
parameters can be used to
test their parameter sets to stop a process.
With Windows PowerShell started, run the Stop-Proc cmdlet with the
ProcessId
parameter set to stop a process based on its identifier. In this case, the cmdlet is using theProcessId
parameter set to stop the process.PS> stop-proc -Id 444 Confirm Are you sure you want to perform this action? Performing operation "stop-proc" on Target "notepad (444)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y
With Windows PowerShell started, run the Stop-Proc cmdlet with the
InputObject
parameter set to stop processes on the Notepad object retrieved by theGet-Process
command.PS> get-process notepad | stop-proc Confirm Are you sure you want to perform this action? Performing operation "stop-proc" on Target "notepad (444)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): N
See Also
Creating a Cmdlet that Modifies the System
How to Create a Windows PowerShell Cmdlet
Extending Object Types and Formatting
PowerShell