Advisory Development Guidelines
This section describes guidelines that you should consider to ensure good development and user experiences. Sometimes they might apply, and sometimes they might not.
Use Serialization-friendly Parameter Types (AC05)
The following guidelines should be considered when designing cmdlets. When you find a Design guideline that applies to your situation, be sure to look at the Code guidelines for similar guidelines.
Because Windows PowerShell works directly with Microsoft .NET Framework objects, a .NET Framework object is often available that exactly matches the type the user needs to perform a particular operation. InputObject is the standard name for a parameter that takes such an object as input. For example, the sample Stop-Proc cmdlet in the StopProc Tutorial defines an InputObject parameter of type Process that supports the input from the pipeline. The user can get a set of process objects, manipulate them to select the exact objects to stop, and then pass them to the Stop-Proc cmdlet directly.
Occasionally, a cmdlet needs to protect the user from performing a requested operation. Such a cmdlet should support a Force parameter to allow the user to override that protection if the user has permissions to perform the operation.
For example, the Remove-Item cmdlet does not normally remove a read-only file. However, this cmdlet supports a Force parameter so a user can force removal of a read-only file. If the user already has permission to modify the read-only attribute, and the user removes the file, use of the Force parameter simplifies the operation. However, if the user does not have permission to remove the file, the Force parameter has no effect.
A cmdlet should define a Credential parameter to represent credentials. This parameter must be of type PSCredential and must be defined using a Credential attribute declaration. This support automatically prompts the user for the user name, for the password, or for both when a full credential is not supplied directly. For more information about the Credential attribute, see Credential Attribute Declaration.
If your cmdlet reads or writes text to or from a binary form, such as writing to or reading from a file in a filesystem, then your cmdlet has to have Encoding parameter that specifies how the text is encoded in the binary form.
The following guidelines should be considered when writing cmdlet code. When you find a guideline that applies to your situation, be sure to look at the Design guidelines for similar guidelines.
By following standard naming conventions, you make your cmdlets more discoverable, and you help the user understand exactly what the cmdlets do. This practice is particularly important for other developers using Windows PowerShell because cmdlets are public types.
You normally define the class for a cmdlet in a .NET Framework namespace that appends ".Commands" to the namespace that represents the product in which the cmdlet runs. For example, cmdlets that are included with Windows PowerShell are defined in the Microsoft.PowerShell.Commands namespace.
When you name the .NET Framework class that implements a cmdlet, name the class “<Verb><Noun><Command>", where you replace the <Verb> and <Noun> placeholders with the verb and noun used for the cmdlet name. For example, the Get-Process cmdlet is implemented by a class called GetProcessCommand.
If your cmdlet does not accept input from the pipeline, processing should be implemented in the BeginProcessing method. Use of this method allows Windows PowerShell to maintain ordering between cmdlets. The first cmdlet in the pipeline always returns its objects before the remaining cmdlets in the pipeline get a chance to start their processing.
Override the StopProcessing method so that your cmdlet can handle stop signal. Some cmdlets take a long time to complete their operation, and they let a long time pass between calls to the Windows PowerShell runtime, such as when the cmdlet blocks the thread in long-running RPC calls. This includes cmdlets that make calls to the WriteObject method, to the WriteError method, and to other feedback mechanisms that may take a long time to complete. For these cases the user might need to send a stop signal to these cmdlets.
If your cmdlet has objects that are not disposed of (written to the pipeline) by the ProcessRecord method, your cmdlet might require additional object disposal. For example, if your cmdlet opens a file handle in its BeginProcessing method and keeps the handle open for use by the ProcessRecord method, this handle has to be closed at the end of processing.
The Windows PowerShell runtime does not always call the EndProcessing method. For example, the EndProcessing method might not be called if the cmdlet is canceled midway through its operation or if a terminating error occurs in any part of the cmdlet. Therefore, the .NET Framework class for a cmdlet that requires object cleanup should implement the complete IDisposable interface pattern, including the finalizer, so that the Windows PowerShell runtime can call both the EndProcessing and Dispose methods at the end of processing.
To support running your cmdlet on remote computers, use types that can be easily serialized on the client computer and then rehydrated on the server computer. The follow types are serialization-friendly.
Byte, SByte, Decimal, Single, Double, Int16, Int32, Int64, Uint16, UInt32, and UInt64.
Boolean, Guid, Byte, TimeSpan, DateTime, Uri, and Version.
Char, String, XmlDocument.
Built-in rehydratable types:
DirectorySecurity, FileSecurity, RegistrySecurity
Containers (lists and dictionaries of the above type)