Understanding and extending the SharePoint PowerShell snapin

SharePoint 2010 introduces the new, powerful SharePoint Management Shell, helping administrators better manage, maintain, and gain insight into their SharePoint environment, while providing a gateway into various aspects of the SharePoint object model for powerful scripting and reporting. The functionality of the new management shell is made available via the SharePoint PowerShell snapin, which like other PowerShell snapins is loaded into a standard PowerShell session to surface additional functionality such as new cmdlets. Like other parts of the SharePoint platform, the SharePoint Management Shell and snapin are easily extensible for seamless integration of PowerShell functionality for all features and applications added to the platform. Let's take a deeper dive into how SharePoint's PowerShell snapin works, and how it can be extended.

What are Snapins?

We begin with an overview of PowerShell snapins in general. Snapins are compiled assemblies containing cmdlets and providers to be loaded into a PowerShell session. In fact, not only are custom cmdlets added in this way, but all default cmdlets and providers are also implemented via PSSnapins loaded automatically in standard PowerShell sessions. For info about the default snapins, run Get-PSSnapin | ? { $_.IsDefault } in any PowerShell session. Going forward, Microsoft recommends that new extensions for PowerShell be implemented using modules, as discussed here; however, many existing extensions (including SharePoint's) are implemented via snapins, which are supported for PowerShell v1 as well as v2.

New custom PSSnapins are registered via creation of a subkey at HKLM:\SOFTWARE\Microsoft\PowerShell\1\PowerShellSnapIns. Each snapin registers its own subkey, and properties and values set on this key determine the configuration changes and additions made to a session when a snapin is added via the Add-PSSnapin cmdlet. Run Get-PSSnapin -Registered for a list of all non-default snapins registered on a given server (a list pulled directly from these registry keys). Note that the IsDefault property for these custom snapins is False.

When loading a custom snapin, the PowerShell runtime simply finds all types in the associated assembly marked with the Cmdlet or CmdletProvider attributes. These cmdlets and providers are then merged into the available cmdlets and providers for the current session. In addition, format and type files specified directly in the registry key (via the Formats and Types properties) are loaded directly from the file system. Note that in PowerShell v2, any PSSnapin-derived types in the custom snapin are ignored; all info needed to load new elements is stored in the registry.

Custom snapins can be further extended programmatically by including a type in their assembly derived from CustomPSSnapin and specifying this type in the snapin's registry key under the property CustomPSSnapinType. As we will see, the SharePoint snapin follows this pattern. While for standard custom snapins PowerShell simply analyzes the associated assembly and loads all cmdlets and providers, CustomPSSnapin snapins allow programmatic control of the specific providers, cmdlets, and format and type files to be added. The values returned by the Cmdlets, Providers, Types, and Formats properties on the CustomPSSnapin-derived class are the ones loaded into the current session by the PowerShell runtime.

The SharePoint snapin

With this background info out of the way, let's dive a bit deeper into the snapin utilized to load up SharePoint cmdlets. When SharePoint is installed on a server, the PowerShell snapin is registered at HKLM:\SOFTWARE\Microsoft\PowerShell\1\PowerShellSnapIns\Microsoft.SharePoint.PowerShell, and the associated assembly is installed in the Global Assembly Cache (GAC) (\windows\assembly). The SharePoint PowerShell snapin utilizes the CustomPSSnapInType paradigm, allowing it to programmatically determine what elements to add to the current session when Add-PSSnapin is called. Herein lies the starting point for the snapin's extensibility framework.

Instead of statically specifying the different configuration elements to be loaded, the SharePoint snapin dynamically determines what to load at runtime from configuration files. Because of the numerous editions, applications, and add-ons available for the SharePoint platform, this is central to simplifying the PowerShell experience for administrators. If each module and feature implemented its own PowerShell snapin (or module), finding the necessary cmdlets would quickly become difficult and unwieldy. To avoid this, the PowerShell snapin scans various folders and files in the 14\CONFIG\POWERSHELL folder to determine the elements to be loaded. The four configuration elements which can be added via custom snapins are cmdlets, providers, formats, and types; via its configuration files, the SharePoint snapin allows loading all but providers (here's hoping there will be a SharePoint PowerShell provider sometime in the future…).

SharePoint config files for PowerShell

Cmdlets

Adding cmdlets to be loaded by the SharePoint snapin is accomplished by adding proper XML files to the 14\CONFIG\POWERSHELL\Registration folder. The schema for these files, SPCmdletSchema.xsd, is available in this folder as well. It can be summarized as Config\Assembly\Cmdlet. Config is the root XML element and Assembly specifies the GAC-installed assembly containing the cmdlet classes. The four elements within the Cmdlet element are as follows:

VerbName

Full Verb-Noun name of cmdlet to be added.

ClassName

Fully-qualified name of .NET class implementing this cmdlet.

HelpFile

MAML help file stored in 14\CONFIG\POWERSHELL\Help containing help related to this cmdlet.

FeatureDependencyId

ID of farm-scoped feature upon which this cmdlet depends. If this feature is not available in the current farm, the cmdlet will not be added to the session.

 

As an example, cmdlets for managing the Managed Metadata service application are specified in the MetadataCmdlets.xml file. The assembly containing these cmdlets is specified in the Assembly element as Microsoft.SharePoint.Taxonomy (the full four-part assembly name). The first of several cmdlets listed within the Assembly element is named Get-SPTaxonomySession, which is implemented by the Microsoft.SharePoint.Taxonomy.Cmdlet.SPCmdletGetTaxonomySession class in the specified assembly. The associated help file is stored under 14\CONFIG\POWERSHELL\Help as Microsoft.SharePoint.Taxonomy.dll-help.xml (under a culture-specific subfolder). No FeatureDependencyId is specified. Note that a help file reference is also not required.

Use the out-of-the-box configuration files in the Registration folder for guidance when writing your own extension files.

Formats and types

Adding format and type files via the snapin is easy: just drop the appropriate files, with extension .ps1xml, into the POWERSHELL\Format and POWERSHELL\Types folders respectively (in 14\CONFIG\POWERSHELL). The snapin loads all files from these locations.

Deployment of new config files

As always, for the sake of manageability and scalability, it is best to only extend and customize SharePoint via farm-wide solutions. As such, the proper way to deploy new PowerShell cmdlet assemblies and configuration files for SharePoint is by using solutions, specifying new assemblies via Assembly elements, and new config files via RootFile elements. Although specifics are beyond the scope of this article, see the Solution Schema reference to get you started.

Conclusion

With the PowerShell for SharePoint snapin, the SharePoint team has as usual provided us with an extensible framework for the SharePoint platform. As we have seen, with just a little effort you can integrate custom PowerShell cmdlets into the SharePoint snapin and SharePoint Management Shell, unifying and simplifying the management experience for administrators.