The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

Creating a Cmdlet without Parameters


This section describes how to create a cmdlet that retrieves information from the local computer without the use of parameters, and then writes the information to the pipeline. The cmdlet described here is a Get-Proc cmdlet that retrieves information about the processes of the local computer, and then displays that information at the command line.

Topics in this section include the following:


Be aware that when writing cmdlets, the Windows PowerShell® reference assemblies are downloaded onto disk (by default at C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0).They are not installed in the Global Assembly Cache (GAC).

A cmdlet name consists of a verb that indicates the action the cmdlet takes and a noun that indicates the items that the cmdlet acts upon. Because this sample Get-Proc cmdlet retrieves process objects, it uses the verb "Get", defined by the VerbsCommon enumeration, and the noun "Proc" to indicate that the cmdlet works on process items.

When naming cmdlets, do not use any of the following characters: # , () {} [] & - /\ $ ; : ” ’<> | ? @ ` .

You should choose a noun that is specific. It is best to use a singular noun prefixed with a shortened version of the product name. An example cmdlet name of this type is "Get-SQLServer".

You should use a verb from the set of approved cmdlet verb names. For more information about the approved cmdlet verbs, see Cmdlet Verb Names.

Once you have chosen a cmdlet name, define a .NET class to implement the cmdlet. Here is the class definition for this sample Get-Proc cmdlet:

[Cmdlet(VerbsCommon.Get, "Proc")]
  public class GetProcCommand : Cmdlet   

Notice that previous to the class definition, the CmdletAttribute attribute, with the syntax [Cmdlet(verb, noun, …)], is used to identify this class as a cmdlet. This is the only required attribute for all cmdlets, and it allows the Windows PowerShell runtime to call them correctly. You can set attribute keywords to further declare the class if necessary. Be aware that the attribute declaration for our sample GetProcCommand class declares only the noun and verb names for the Get-Proc cmdlet.


For all Windows PowerShell attribute classes, the keywords that you can set correspond to properties of the attribute class.

When naming the class of the cmdlet, it is a good practice to reflect the cmdlet name in the class name. To do this, use the form "VerbNounCommand" and replace "Verb" and "Noun" with the verb and noun used in the cmdlet name. As is shown in the previous class definition, the sample Get-Proc cmdlet defines a class called GetProcCommand, which derives from the Cmdlet base class.


If you want to define a cmdlet that accesses the Windows PowerShell runtime directly, your .NET class should derive from the PSCmdlet base class. For more information about this class, see Creating a Cmdlet that Defines Parameter Sets.


The class for a cmdlet must be explicitly marked as public. Classes that are not marked as public will default to internal and will not be found by the Windows PowerShell runtime.

Windows PowerShell uses the Microsoft.PowerShell.Commands namespace for its cmdlet classes. It is recommended to place your cmdlet classes in a Commands namespace of your API namespace, for example, xxx.PS.Commands.

The Cmdlet class provides three main input processing methods, at least one of which your cmdlet must override. For more information about how Windows PowerShell processes records, see How Windows PowerShell Works.

For all types of input, the Windows PowerShell runtime calls BeginProcessing to enable processing. If your cmdlet must perform some preprocessing or setup, it can do this by overriding this method.


Windows PowerShell uses the term "record" to describe the set of parameter values supplied when a cmdlet is called.

If your cmdlet accepts pipeline input, it must override the ProcessRecord method, and optionally the EndProcessing method. For example, a cmdlet might override both methods if it gathers all input using ProcessRecord and then operates on the input as a whole rather than one element at a time, as the Sort-Object cmdlet does.

If your cmdlet does not take pipeline input, it should override the EndProcessing method. Be aware that this method is frequently used in place of BeginProcessing when the cmdlet cannot operate on one element at a time, as is the case for a sorting cmdlet.

Because this sample Get-Proc cmdlet must receive pipeline input, it overrides the ProcessRecord method and uses the default implementations for BeginProcessing and EndProcessing. The ProcessRecord override retrieves processes and writes them to the command line using the WriteObject method.

protected override void ProcessRecord()
  // Get the current processes
  Process[] processes = Process.GetProcesses();

  // Write the processes to the pipeline making them available
  // to the next cmdlet. The second parameter of this call tells 
  // PowerShell to enumerate the array, and send one process at a 
  // time to the pipeline.
  WriteObject(processes, true);

  • The default source for input is an explicit object (for example, a string) provided by the user on the command line. For more information, see Creating a Cmdlet to Process Command Line Input.

  • An input processing method can also receive input from the output object of an upstream cmdlet on the pipeline. For more information, see Creating a Cmdlet to Process Pipeline Input. Be aware that your cmdlet can receive input from a combination of command-line and pipeline sources.

  • The downstream cmdlet might not return for a long time, or not at all. For that reason, the input processing method in your cmdlet should not hold locks during calls to WriteObject, especially locks for which the scope extends beyond the cmdlet instance.


    Cmdlets should never call WriteLine or its equivalent.

  • Your cmdlet might have object variables to clean up when it is finished processing (for example, if it opens a file handle in the BeginProcessing method and keeps the handle open for use by ProcessRecord). It is important to remember that the Windows PowerShell runtime does not always call the EndProcessing method, which should perform object cleanup.

    For example, EndProcessing might not be called if the cmdlet is canceled midway or if a terminating error occurs in any part of the cmdlet. Therefore, a cmdlet that requires object cleanup should implement the complete IDisposable pattern, including the finalizer, so that the runtime can call both EndProcessing and Dispose at the end of processing.

For the complete C# sample code, see GetProcessSample01 Sample.

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 [ps].

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 [ps].

When your cmdlet has been registered with Windows PowerShell, you can test it by running it on the command line. The code for our sample Get-Proc cmdlet is small, but it still uses the Windows PowerShell runtime and an existing .NET object, which is enough to make it useful. Let's test it to better understand what Get-Proc can do and how its output can be used. For more information about using cmdlets from the command line, see the Getting Started with Windows PowerShell [OLD MSDN].

  1. Start Windows PowerShell, and get the current processes running on the computer.

    PS> get-proc

    The following output appears.

    Handles  NPM(K)  PM(K)  WS(K)  VS(M)  CPU(s)  Id   ProcessName
    -------  ------  -----  -----  -----  ------  --   ----------
    254      7       7664   12048  66     173.75  1200  QCTRAY
    32       2       1372   2628   31       0.04  1860  DLG
    271      6       1216   3688   33       0.03  3816  lg
    27       2       560    1920   24       0.01  1768  TpScrex
  2. Assign a variable to the cmdlet results for easier manipulation.

    PS> $p=get-proc
  3. Get the number of processes.

    PS> $p.length

    The following output appears.

  4. Retrieve a specific process.

    The following output appears.

    Handles  NPM(K)  PM(K)  WS(K)  VS(M)  CPU(s)  Id    ProcessName
    -------  ------  -----  -----  -----  ------  --    -----------
    1033     3       2400   3336   35     0.53    1588  rundll32
  5. Get the start time of this process.

    PS> $p[6].starttime

    The following output appears.

    Tuesday, July 26, 2005 9:34:15 AM
    PS> $p[6].starttime.dayofyear
  6. Get the processes for which the handle count is greater than 500, and sort the result.

    PS> $p | where {$_.HandleCount -gt 500 } | sort HandleCount

    The following output appears.

    Handles  NPM(K)  PM(K)  WS(K)  VS(M)  CPU(s)  Id   ProcessName
    -------  ------  -----  -----  -----  ------  --   ----------
    568      14      2164   4972   39     5.55    824  svchost
    716       7      2080   5332   28    25.38    468  csrss
    761      21      33060  56608  440  393.56    3300 WINWORD
    791      71      7412   4540   59     3.31    492  winlogon
  7. Use the Get-Member cmdlet to list the properties available for each process.

    PS> $p | get-member -membertype property
        TypeName: System.Diagnostics.Process

    The following output appears.

    Name                     MemberType Definition
    ----                     ---------- ----------
    BasePriority             Property   System.Int32 BasePriority {get;}
    Container                Property   System.ComponentModel.IContainer Conta...
    EnableRaisingEvents      Property   System.Boolean EnableRaisingEvents {ge...