Development Guidelines for SharePoint Foundation Cmdlets

SharePoint 2010

Last modified: March 24, 2010

Applies to: SharePoint Foundation 2010

When you write Windows PowerShell cmdlets for SharePoint – that is, custom cmdlets that derive from the SPCmdlet base class – be sure to use SharePoint-specific design guidelines to ensure that your cmdlets are fully compatible with cmdlets in the SharePoint cmdlet library that are exposed in the SharePoint Management Shell. Furthermore, the SharePoint Foundation also recommends design patterns that ensure full interoperability with your SharePoint deployment.

When you design SharePoint-specific cmdlets, always do the following:

  • Define cmdlet nouns.

  • Define cmdlet noun properties.

  • Define cmdlet verbs and parameters.

  • Define your cmdlet errors, progress, and pipeline.

When you follow this process, the result is a comprehensive definition of the cmdlet set for the component or feature that you are developing.

Define Cmdlet Nouns

  1. When you define a cmdlet noun, be very clear about what your feature will manage. Think of nouns as items that a system administrator will manage. These could be SharePoint objects like SPSite or SPWeb objects, or they could be installed features, such as SPFeature objects, form templates, or Web Parts.

    As a general rule, it is better to have a greater number of nouns that have fewer properties than to have a small number of nouns that have a great many properties. Any noun that has more than 15 properties is overburdened.

  2. Identify the nonpersisted, run-time state information that you want to expose to system administrators. Also, identify state information that may not be persisted but must nevertheless be returned to system administrators (for example, the running state of a service).

  3. Evaluate whether a newly defined noun should be split into two or more different nouns. Create separate nouns for items that are semantically distinct. Use feature or component specifications to identify whether a noun spans multiple concepts or features.

  4. If a noun spans multiple data sources (either physical or logical), split the noun along data-source boundaries. Identify a logically independent subset of properties that is persisted in a single database or SharePoint object only. In most cases this subset should become a separate noun, but only if the resulting nouns are logically independent, and only if they can be clearly understood as distinct entities (that is, easily separated) without confusing system administrators.

  5. For every persisted data source object that is used by more than one noun, unify these nouns into a single noun. Also, unify nouns whose primary difference is that they have different lifetimes, because their creation and deletion can be managed separately.

Define Cmdlet Noun Properties

  1. Define an Identity property. All nouns must have an Identity property whose value is unique and immutable, such as a GUID.

  2. Create a pipebind for the noun. The pipebind should combine all properties that can uniquely identify the object.

  3. Define the complete set of public properties for the noun. Treat the noun definition as though it were a public API. All related public properties are exposed in the command line when an instance of the noun is returned.

  4. Define a data type for each property. Properties should be strongly typed, so that format validation code can be attached to the property type rather than to the noun. For example, a property that represents an e-mail address should be of type EmailAddress rather than of type String.

  5. Identify atypically large properties. Ensure that unusually large properties (larger than 10 KB) are split into two or more properties.

  6. Identify collections of properties that have a large number of elements (for example, a collection with more than 100 elements). Remove such large property collections and split the elements into separate nouns. Then, define the New, Remove, Get, and Set verbs for the new nouns.

    For example, consider a scenario in which Users is a property of an SPWeb object, which can have a large number of elements. To avoid problems, create a separate noun called SPUser that represents one element in the list, then add the associated New, Remove, Get, and Set verbs.

Define Cmdlet Verbs and Parameters

Determine which of the base verbs (Get, Set, New, Remove) apply to your noun. At a minimum, system administrators must be able to get settings and to change (or Set) them. Additionally, administrators may also need to create new instances (New) and delete existing ones (Remove).

  1. Define the behavior of your Get cmdlet.

    The Get verb must retrieve all instances if no parameters are specified, and it must do so by writing the instances to the Windows PowerShell pipeline. However, any operation that can potentially return a very large result set should include a Limit parameter on which a default limit is specified. Of course, when limiting a result set in this way, you must alert users that additional results may be excluded from the limited result set.

    The Get verb must have an Identity parameter. When specified, the corresponding cmdlet must return only the instance associated with that identity. If the identity that is specified is not unique, the cmdlet should return all instances that have the specified identity value.

    The Get verb can have additional optional filtering parameters. For example, the cmdlet Get-SPSite might have a ContentDatabase parameter that restricts the result set to the site collections that are located in a specified content database. Furthermore, the Get verb must have a Server parameter if the cmdlet returns local (that is, machine-specific) configuration information.

  2. Define the behavior of the Set cmdlet.

    The Set verb must have an Identity parameter to identify the instance that is being changed. The parameter must be able to take either an identity (for example, a GUID) or a name. If a name is specified and this name matches more than one instance, the cmdlet must return an error.

    The Identity parameter of the Set cmdlet must accept pipeline input.

    The Set verb must expose all writable properties of the noun that are received using the corresponding Get cmdlet, except those that cause negative effects when set.

    The Set verb must have an optional Instance parameter that represents an entire instance of this noun type. The Instance parameter must accept pipeline input (by value).

  3. Define the behavior of the New cmdlet.

    The New verb must take a limited subset of the writable properties of the noun as parameters. The remaining properties should be set to default values. Furthermore, the New cmdlet must return the newly created instance object to the pipeline so that further cmdlets in the pipeline may act on the new instance.

  4. Define the behavior of the Remove cmdlet.

    Your Remove cmdlet must have an Identity parameter that can take either an identity value or a name. If a name is specified and it matches more than one instance, the cmdlet must return an error.

    The Identity parameter must accept pipeline input. Furthermore, any destructive operation must support Confirm and WhaIf parameters. This requires little effort, as Windows PowerShell and base classes of SharePoint Foundation 2010 provide means for supporting these parameters.

  5. Identify and define additional verbs for the noun.

    For example, an SPContentDatabase noun might need a Mount verb to support mounting the specified database. Use well-tested administrative scenarios and use cases to support selecting appropriate verbs.

    Remember that all additional cmdlets must have an Identity parameter that accepts pipeline input. The Identity parameter must accept the identity (PipeBind) of the object. Furthermore, any destructive operation must support Confirm and WhaIf parameters.

  6. Identify properties that have potential negative side effects.

    Properties that have potential negative side effects may require additional operations to mitigate the negative effects. These additional mitigating cmdlets must have an Identity parameter that accepts pipeline input.

  7. For each cmdlet that you define, do the following:

    (a) Identify the list of prerequisites for the cmdlet. For example, in a case where a cmdlet can be executed only in a certain system state, the cmdlet must verify that all state prerequisites are met before executing.

    (b) Identify the list of operations. Specify the complete list of operations that the cmdlet is able to perform. The cmdlet must perform and then validate these operations. This operation list comprises the functional breakdown of the cmdlet.

Define Cmdlet Errors, Progress and Pipeline

  1. Identify all error conditions and error-state behaviors. That is, list all conditions in which a cmdlet can error out. Then, for each condition, describe the expected behavior. Your cmdlets must provide basic error management.

    Your cmdlets must clean up partial changes when an error occurs, and they must return a meaningful (and localized, if appropriate) error message. Furthermore, cmdlets must determine and reveal how a system administrator can recover from any error condition.

  2. Differentiate between terminating and nonterminating errors.

  3. Identify long-running operations. If a cmdlet is expected to take longer than about twenty seconds, on average, to complete an operation, the cmdlet must provide progress information to avoid the appearance of a suspended operation.

  4. Ensure that cmdlets write their return objects directly to the pipeline. Avoid buffering retrieved objects to an internal array. Writing to the pipeline allows the downstream cmdlets to act upon preceding objects in the pipeline without delay.

  5. Group similar parameters. Limit cmdlets to 16 parameters (not including the Identity and Name parameters). In cases where object methods are rarely called, and where an object model method exists, no cmdlet parameter is needed. In cases where a large number of parameters can be grouped, write a single parameter that accepts the group object.

Show: