Cmdlet Development Guidelines
Relevant source files
The following files were used as context for generating this wiki page:- src/System.Management.Automation/engine/CommandMetadata.cs
- src/System.Management.Automation/engine/CmdletInfo.cs
- src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs
- src/System.Management.Automation/help/HelpCommentsParser.cs
- src/System.Management.Automation/engine/Modules/NewModuleManifestCommand.cs
- src/System.Management.Automation/engine/GetCommandCommand.cs
Cmdlet development in PowerShell follows a metadata-driven architectural pattern where behavior is primarily defined through declarative attributes rather than imperative code. This system ensures consistency across the command-line interface by standardizing parameter binding, lifecycle management, and help documentation.
Guidelines encompass naming conventions, the implementation of the processing lifecycle, metadata configuration for pipeline support, and requirements for module-level command exposure. Developers must adhere to these standards to ensure compatibility with PowerShell's execution engine and provide a predictable experience for end users.
Command Naming and Structure
Cmdlets must follow a strict "Verb-Noun" naming convention. The engine validates this format during command discovery and metadata construction.
- Verb-Noun Format: Names must be in the form
Verb-Noun. The verb should ideally be one of the approved verbs defined inSystem.Management.Automation.Verbs. - Implementation Base: Compiled cmdlets are implemented as .NET classes deriving from
System.Management.Automation.CmdletorSystem.Management.Automation.PSCmdlet. - Separation: The engine uses a dash character to split the name into its constituent verb and noun components.
Sources: src/System.Management.Automation/engine/CmdletInfo.cs:23-45, src/System.Management.Automation/engine/CmdletInfo.cs:121-143
The diagram shows the logic used by the PowerShell engine to validate and parse a cmdlet name into its verb and noun components.
Sources: src/System.Management.Automation/engine/CmdletInfo.cs:121-143
Metadata and Attributes
The behavior of a cmdlet is dictated by attributes applied to the class and its properties. These attributes are processed via reflection to create a CommandMetadata object.
CmdletBinding Attribute
The [CmdletBinding()] attribute is the core configuration point for advanced cmdlets. It enables common parameters (e.g., -Verbose, -Debug) and defines high-level capabilities.
| Property | Description |
|---|---|
DefaultParameterSetName | Specifies the parameter set used when the engine cannot determine one from provided arguments. |
SupportsShouldProcess | Enables -WhatIf and -Confirm parameters for impact-heavy operations. |
ConfirmImpact | Defines the destructive level (Low, Medium, High) of the command. |
SupportsPaging | Enables paging parameters like -First, -Skip, and -IncludeTotalCount. |
PositionalBinding | Boolean indicating if parameters should be bound by position if not explicitly named. |
Sources: src/System.Management.Automation/engine/CommandMetadata.cs:608-644, src/System.Management.Automation/engine/CommandMetadata.cs:721-760
Parameter Sets
Cmdlets use parameter sets to define mutually exclusive groups of parameters. A parameter can belong to multiple sets or be assigned to ParameterAttribute.AllParameterSets.
Sources: src/System.Management.Automation/engine/CommandMetadata.cs:337-345
Cmdlet Processing Lifecycle
The execution of a cmdlet is divided into distinct stages. This structure is essential for proper pipeline operation, where data may be processed one object at a time.
- BeginProcessing: Called once per command instance. Used for one-time initialization (e.g., establishing database connections).
- ProcessRecord: Called once for every object received from the pipeline. This is where the core logic of the cmdlet resides.
- EndProcessing: Called once after all pipeline objects have been processed. Used for finalizing output and cleanup.
- Clean: Used for robust resource disposal regardless of execution success or failure.
Sources: src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs:1003-1087, src/System.Management.Automation/engine/CommandMetadata.cs:898-940
The sequence diagram illustrates the orderly execution of cmdlet lifecycle methods by the PowerShell pipeline engine.
Sources: src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs:1003-1087
Parameter Development Guidelines
Parameters must be decorated with the [Parameter()] attribute. Metadata derived from these attributes guides the Parameter Binder in assigning values.
- Mandatory Parameters: Use
Mandatory = $trueto ensure the engine prompts the user if the value is missing. - Pipeline Input: Parameters can accept input from the pipeline
ByValueorByPropertyName. - Validation Attributes: Constraints such as
[ValidateNotNullOrEmpty()],[ValidateSet()], and[ValidateRange()]should be used to offload input checking to the engine. - Default Values: Values should be initialized in the class constructor or via property initializers.
Sources: src/System.Management.Automation/engine/CommandMetadata.cs:780-805, src/System.Management.Automation/cimSupport/cmdletization/ScriptWriter.cs:494-550
Documentation and Help
Guidelines require cmdlets to provide metadata for help generation. This can be achieved through XML help files or comment-based help within scripts.
Comment-Based Help Directives
Developers should include the following directives in their source files to ensure Get-Help provides accurate information:
.SYNOPSIS: A brief description of the cmdlet..DESCRIPTION: A detailed explanation of functionality..PARAMETER <Name>: Specific documentation for an individual parameter..EXAMPLE: Real-world usage scenarios including code and expected output..LINK: URLs to online documentation or related commands.
Sources: src/System.Management.Automation/help/HelpCommentsParser.cs:476-538, src/System.Management.Automation/engine/ProxyCommand.cs:337-380
Module Integration and Exposure
When packaging cmdlets into modules, developers must explicitly define which commands are exposed to the user via the module manifest (.psd1).
- Explicit Exports: Best practices involve explicitly listing cmdlets in
CmdletsToExportand functions inFunctionsToExportrather than using wildcards (*). - Metadata Consistency: The
ModuleVersion,GUID, andAuthorfields in the manifest must be accurate for proper versioning and repository management. - Compatibility: Use the
CompatiblePSEditionsfield to specify if the cmdlet supportsCore(PowerShell 6+) orDesktop(Windows PowerShell).
Sources: src/System.Management.Automation/engine/Modules/NewModuleManifestCommand.cs:480-505, src/System.Management.Automation/engine/Modules/NewModuleManifestCommand.cs:567-610
The class diagram shows the inheritance hierarchy of command metadata objects within the engine, distinguishing between compiled cmdlets and script functions.
Sources: src/System.Management.Automation/engine/CmdletInfo.cs:13-30, src/System.Management.Automation/engine/GetCommandCommand.cs:721-744