One source of input for a cmdlet is the command line. This section describes how to add a parameter to the Get-Proc cmdlet (described in Creating a Cmdlet without Parameters) so that the cmdlet can process input from the local computer based on explicit objects passed to the cmdlet. The Get-Proc cmdlet described here retrieves processes based on their name, and then displays information about the processes at the command line.
Note: |
|
You can download the C# source file (getproc02.cs) for this Get-Proc cmdlet using the Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components. For download instructions, see How to Install Windows PowerShell and Download the Windows PowerShell SDK.
The downloaded source files are available in the <PowerShell Samples> directory. |
Topics in this section include the following:
Defining the Cmdlet Class
The first step in cmdlet creation is always cmdlet naming and the declaration of the .NET class that implements the cmdlet. This cmdlet retrieves process information, so the verb name chosen here is "Get". (Almost any sort of cmdlet that is capable of retrieving information can process command-line input.) For more information about approved cmdlet verbs, see Cmdlet Verbs.
Here is the class definition for this Get-Proc cmdlet. Details of this definition are given in Creating a Cmdlet without Parameters.
[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand: Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
Inherits Cmdlet
Declaring Parameters
A cmdlet parameter allows the user to provide input to the cmdlet. In the following example, Get-Proc and Get-Member are the names of pipelined cmdlets, and MemberType is a parameter for the Get-Member cmdlet, with the argument "property".
PS> get-proc | get-member -membertype property
To declare parameters for a cmdlet, you must first define the properties that represent the parameters. In this sample Get-Proc cmdlet, the only parameter is Name, which in this case represents the name of the .NET process object to retrieve. Therefore, the cmdlet class defines a property of type string[] to accept an array of names.
Here is the parameter declaration for the Name parameter of this Get-Proc cmdlet.
/// <summary>
/// Specify the cmdlet Name parameter.
/// </summary>
[Parameter(Position = 0)]
[ValidateNotNullOrEmpty]
public string[] Name
{
get { return processNames; }
set { processNames = value; }
}
private string[] processNames;
#endregion Parameters
<Parameter(Position:=0), ValidateNotNullOrEmpty()> _
Public Property Name() As String()
Get
Return processNames
End Get
Set(ByVal value As String())
processNames = value
End Set
End Property
To inform the Windows PowerShell runtime that this property is the Name parameter, a ParameterAttribute attribute is added to the property definition. The basic syntax for declaring this attribute is [Parameter()].
Note: |
|
A parameter must be explicitly marked as public. Parameters that are not marked as public will default to internal and will not be found by the Windows PowerShell runtime. |
Be aware that this cmdlet uses an array of strings for the Name parameter. If at all possible, your cmdlet should also define a parameter as an array, because this allows the cmdlet to accept more than one item.
Things to Remember About Parameter Definitions
-
Predefined Windows PowerShell parameter names and data types should be reused as much as possible to ensure that your cmdlet will be compatible with Windows PowerShell cmdlets. For example, if all cmdlets use the predefined Id parameter name to identify a resource, the user will easily understand the meanings of the parameter, regardless of what cmdlet they are using. Basically, parameter names follow the same rules as those used for variable names in the common language runtime (CLR). For more information about parameter naming, see Cmdlet Parameter Names.
-
Windows PowerShell reserves a few parameter names to provide a consistent user experience. Do not use these parameter names: WhatIf, Confirm, Verbose, Debug, Warn, ErrorAction, ErrorVariable, OutVariable, and OutBuffer. Additionally, the following aliases for these parameter names are reserved: vb, db, ea, ev, ov, and ob.
-
Name is a simple and common parameter name, recommended for use in your cmdlets. It is better to choose a parameter name like this than a complex name that is unique to a specific cmdlet and hard to remember.
-
Parameters are case-insensitive in Windows PowerShell, although by default the shell preserves case. Case-sensitivity of the arguments depends on the operation of the cmdlet, with arguments passed to a parameter as specified at the command line.
-
For examples of other parameter declarations, see Cmdlet Parameters.
Declaring Parameters as Positional or Named
A cmdlet must set each parameter as either a positional or named parameter. Both kinds of parameters accept single arguments, multiple arguments separated by commas, and Boolean settings. A Boolean parameter, also called a "switch," handles only Boolean settings. The switch is used to determine the presence of the parameter. The recommended default is false.
Our sample Get-Proc cmdlet defines the Name parameter as a positional parameter with position 0. This means that the first argument the user enters on the command line will be automatically inserted for this parameter. If you wanted to define a named parameter, for which the user must specify the parameter name from the command line, you would leave out the Position keyword in the attribute declaration.
Note: |
|
Unless parameters must be named, it is recommended that you make the most-used parameters positional so that the user will not have to type the parameter name again and again. |
Declaring Parameters as Mandatory or Optional
A cmdlet must set each parameter as either an optional or required (mandatory) parameter. The sample Get-Proc cmdlet defines the Name parameter as optional by not setting the Mandatory keyword in the attribute declaration.
Support Parameter Validation
This sample Get-Proc cmdlet adds an input validation attribute, ValidateNotNullOrEmptyAttribute, to the Name parameter to enable validation that the input is neither null nor empty. This attribute is one of several validation attributes provided by Windows PowerShell. For examples of other validation attributes, see Validating Parameter Input.
[Parameter(Position = 0)]
[ValidateNotNullOrEmpty]
public string[] Name
Overriding an Input Processing Method
If your cmdlet is to handle command-line input, it must override the appropriate input processing methods. The basic input processing methods are introduced in Creating a Cmdlet without Parameters.
This Get-Proc cmdlet overrides the ProcessRecord method to handle the Name parameter input provided by the user or a script. This method will get the processes for each requested process name, or all processes if no name is provided. Notice that within ProcessRecord, the call to WriteObject is the output mechanism for sending output objects to the pipeline. The second parameter of this call, enumerateCollection, is set to true to tell the Windows PowerShell runtime to enumerate the output array of process objects, and write one process at a time to the command line.
protected override void ProcessRecord()
{
// If no process names are passed to the cmdlet, get all processes.
if (processNames == null)
{
// Write the processes to the pipeline making them available
// to the next cmdlet. The second argument of this call tells
// PowerShell to enumerate the array, and send one process at a
// time to the pipeline.
WriteObject(Process.GetProcesses(), true);
}
else
{
// If process names are passed to the cmdlet, get and write
// the associated processes.
foreach (string name in processNames)
{
WriteObject(Process.GetProcessesByName(name), true);
}
}
}
Protected Overrides Sub ProcessRecord()
'/ If no process names are passed to the cmdlet, get all processes.
If processNames Is Nothing Then
Dim processes As Process()
processes = Process.GetProcesses()
End If
'/ If process names are specified, write the processes to the
'/ pipeline to display them or make them available to the next cmdlet.
For Each name As String In processNames
'/ The second parameter of this call tells PowerShell to enumerate the
'/ array, and send one process at a time to the pipeline.
WriteObject(Process.GetProcessesByName(name), True)
Next
End Sub 'ProcessRecord
Code Sample
For complete sample code, see the following topics.
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
Testing the Cmdlet
When your cmdlet has been registered with Windows PowerShell, you can test it by running it on the command line. Here are two ways to test the code for the sample cmdlet. For more information about using cmdlets from the command line, see the Windows PowerShell Getting Started Guide.
-
At the Windows PowerShell prompt, use the following command to list the Internet Explorer process, named "IEXPLORE".
PS> get-proc -name iexplore
The following output appears.
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
354 11 10036 18992 85 0.67 3284 iexplore
-
List the Internet Explorer, Microsoft Outlook, and Notepad processes named "IEXPLORE", "OUTLOOK", and "NOTEPAD". If there are multiple processes, all of them are displayed.
PS> get-proc -name iexplore, outlook, notepad
The following output appears.
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
732 21 24696 5000 138 2.25 2288 iexplore
715 19 20556 14116 136 1.78 3860 iexplore
3917 62 74096 58112 468 191.56 1848 OUTLOOK
39 2 1024 3280 30 0.09 1444 notepad
39 2 1024 356 30 0.08 3396 notepad
See Also