As SharePoint Developers and Administrators take advantage of PowerShell support
in SharePoint 2010 to automate configuration and maintenance tasks they inevitably
begin to run into issues. These include managing larger, more complex scripts, and
sharing and managing of snippets and functions they want to reuse across the team.
In PowerShell v1, creating a custom PowerShell Snapin required Visual Studio and managed code. PowerShell v2 introduced the ability to create reusable modules written entirely in PowerShell. In essence, Modules are the new Snapins.
Some of the advantages of PowerShell modules include the follow:
- Organizes PowerShell code into self-contained, reusable units.
- Does not require deploying a compiled DLL or updating the Registry.
- Supports embedded help information and the Get-Help CmdLet.
- Defines a restricted runspace with its own context that does not affect state, outside the module.
- Defines persistent script-scope variables that preserve their state across multiple calls.
- Explicitly defines which members are exported as public, outside the module.
PowerShell modules are essentially like classes, with private and public variables and functions.
Step 1 - Select a Module Path
The first step to creating a custom PowerShell module is to understand the Import-Module statement. Import-Module is used to load external PowerShell scripts and modules into a PowerShell session:
To avoid having to specify the full path, PowerShell provides the PSModulePath environment variable to store the locations of module folders. PowerShell uses the PSModulePath to search for modules when the full path is not specified as part of the Import-Module statement.
By default, the PSModulePath is loaded with two existing locations as a default for shared or per-user modules:
- $home\Documents\WindowsPowerShell\Modules => C:\Users\Chris.Beckett\Documents\WindowsPowershell\Modules
- $psHome\Modules => C:\Windows\system32\WindowsPowerShell\v1.0\Modules
You can deploy your modules to any folder of your choosing. Simply create a folder, and then add the folder path to the PSModulePath environment variable using the System Properties dialog in Control Panel, or by using PowerShell to add a User or Machine scoped path.
[Environment]::SetEnvironmentVariable("PSModulePath", "<path>", "<Machine|User>") Example: [Environment]::SetEnvironmentVariable("PSModulePath", "C:\PowerShell\SharePoint\Modules", "Machine")
Step 2 - Create a Module Folder
Module namespaces in PowerShell are mapped to folders located under a module path. Each module folder can contain one or more module files with the extension .PSM1. This is the standard file extension for PowerShell module scripts.
In this tip, I am creating a custom module to allow me to query and update the Property Bag on a SharePoint Web.
Once I have added my script files to this folder, I can import my module using the folder as the namespace. Any exported PowerShell functions contained in this folder will be imported as part of the following Import-Module statement:
Step 3 - Create a PSM1 Module File
Module files are just normal PowerShell scripts saved with the .PSM1 extension. You can use any text editor to develop your PowerShell module including NotePad or Visual Studio, but I prefer to use the PowerShell ISE (Integrated Scripting Environment) that can be installed as an optional feature on Windows Server 2008. In addition to providing a nice file editor with highlighting, it also provides easy script execution and debugging.
The above script demonstrates a minimal example of a custom PowerShell Module:
- In Section #1 located at the top of the module you can include anything you want loaded into the scope of your module including Snap-Ins, Modules or just references to external script files. You can also define any module level variables.
- In Section #2, I have created a PowerShell function to check if a property exists on a target SharePoint web. The important consideration here is that you need to dress your functions params with the [CmdletBinding()] attribute. My function takes two params; the target URL of the SharePoint web, and the name of the property to query.
- In Section #3, I have added the Export-ModuleMember to expose my function outside the module. Functions that are not exported will remain private within the scope of the module.
Now that we have completed our initial module, let's give it try:
Step 4 - Supporting PowerShell Integrated Help
PowerShell provides the ability for Snap-ins and Modules to provide integrated help. Modules support the ability through comment blocks to identify properties used to support the Get-Help command.
There are many properties that can be used to decorate module functions including Author information, minimum required PowerShell version, related links, etc. In the above example, I have provided the basics to help users understand my function and an example on how to use it.
Step 5 - Supporting Pipelined Input
The final step in finishing off our sample module is to add support for Pipelined Input. One of the incredibly powerful features of PowerShell is to pipe the output of one command to the input of another. To take greater control of function parameters including the ability to identify mandatory parameters, declare the parameter type, and map a parameter to pipelined input, we need to replace our simple parameter placeholders with a [Parameter()] definition.
In the above example, I have added the ValueFromPipelineByPropertyName attribute identifying that this parameter will map to properties of the same name passed in through the PowerShell Pipeline. It is also possible to add an additional [Alias] attribute to a parameter to allow it to map to additional names.
Let's try our updated Module again, and this time, pipe it a URL from the SP-GetWeb CmdLet:
Summary - Test Script
In this tip we learned how easy it is to create custom PowerShell modules to help organize and share the PowerShell scripts we develop to help manage a SharePoint deployment. Here is the final test script that pulls it all together:
- Create your own custom PowerShell Module.
- Check out these other tips about PowerShell:
Last Update: 2011-06-07
About the author
View all my tips