Adding Parameters that Process Pipeline Input
One source of input for a cmdlet is an object on the pipeline that originates from an upstream cmdlet. This section describes how to add a parameter to the Get-Proc cmdlet (described in Creating Your First Cmdlet) so that the cmdlet can process pipeline objects.
This Get-Proc cmdlet uses a Name
parameter that accepts input from a pipeline object, retrieves
process information from the local computer based on the supplied names, and then displays
information about the processes at the command line.
Defining the Cmdlet Class
The first step in cmdlet creation is always naming the cmdlet and declaring 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 Verb Names.
The following is the definition for this Get-Proc cmdlet. Details of this definition are given in Creating Your First Cmdlet.
[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand : Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
Inherits Cmdlet
Defining Input from the Pipeline
This section describes how to define input from the pipeline for a cmdlet. This Get-Proc cmdlet
defines a property that represents the Name
parameter as described in
Adding Parameters that Process Command Line Input.
(See that topic for general information about declaring parameters.)
However, when a cmdlet needs to process pipeline input, it must have its parameters bound to input
values by the Windows PowerShell runtime. To do this, you must add the ValueFromPipeline
keyword
or add the ValueFromPipelineByProperty
keyword to the
System.Management.Automation.Parameterattribute
attribute declaration. Specify the ValueFromPipeline
keyword if the cmdlet accesses the complete
input object. Specify the ValueFromPipelineByProperty
if the cmdlet accesses only a property of
the object.
Here is the parameter declaration for the Name
parameter of this Get-Proc cmdlet that accepts pipeline input.
[Parameter(
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true)]
[ValidateNotNullOrEmpty]
public string[] Name
{
get { return this.processNames; }
set { this.processNames = value; }
}
<Parameter(Position:=0, ValueFromPipeline:=True, _
ValueFromPipelineByPropertyName:=True), ValidateNotNullOrEmpty()> _
Public Property Name() As String()
Get
Return processNames
End Get
Set(ByVal value As String())
processNames = value
End Set
End Property
The previous declaration sets the ValueFromPipeline
keyword to true
so that the Windows
PowerShell runtime will bind the parameter to the incoming object if the object is the same type as
the parameter, or if it can be coerced to the same type. The ValueFromPipelineByPropertyName
keyword is also set to true
so that the Windows PowerShell runtime will check the incoming object
for a Name
property. If the incoming object has such a property, the runtime will bind the Name
parameter to the Name
property of the incoming object.
Note
The setting of the ValueFromPipeline
attribute keyword for a parameter takes precedence over the
setting for the ValueFromPipelineByPropertyName
keyword.
Overriding an Input Processing Method
If your cmdlet is to handle pipeline input, it needs to override the appropriate input processing methods. The basic input processing methods are introduced in Creating Your First Cmdlet.
This Get-Proc cmdlet overrides the
System.Management.Automation.Cmdlet.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 System.Management.Automation.Cmdlet.ProcessRecord,
the call to WriteObject(System.Object,System.Boolean)
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 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);
} // End foreach (string name...).
}
}
Protected Overrides Sub ProcessRecord()
Dim processes As Process()
'/ If no process names are passed to the cmdlet, get all processes.
If processNames Is Nothing Then
processes = Process.GetProcesses()
Else
'/ 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 If
End Sub 'ProcessRecord
Code Sample
For the complete C# sample code, see GetProcessSample03 Sample.
Defining Object Types and Formatting
Windows PowerShell passes information between cmdlets using .Net objects. Consequently, a cmdlet may need to define its own type, or the cmdlet may 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 it must be registered 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. For example, test the code for the sample cmdlet. For more information about using cmdlets from the command line, see the Getting Started with Windows PowerShell.
At the Windows PowerShell prompt, enter the following commands to retrieve the process names through the pipeline.
PS> type ProcessNames | get-proc
The following output appears.
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 809 21 40856 4448 147 9.50 2288 iexplore 737 21 26036 16348 144 22.03 3860 iexplore 39 2 1024 388 30 0.08 3396 notepad 3927 62 71836 26984 467 195.19 1848 OUTLOOK
Enter the following lines to get the process objects that have a
Name
property from the processes called "IEXPLORE". This example uses theGet-Process
cmdlet (provided by Windows PowerShell) as an upstream command to retrieve the "IEXPLORE" processes.PS> get-process iexplore | get-proc
The following output appears.
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 801 21 40720 6544 142 9.52 2288 iexplore 726 21 25872 16652 138 22.09 3860 iexplore 801 21 40720 6544 142 9.52 2288 iexplore 726 21 25872 16652 138 22.09 3860 iexplore
See Also
Adding Parameters that Process Command Line Input
Extending Object Types and Formatting