How to Package and Distribute PowerShell Cmdlets, Functions, and Scripts

I have noticed quite a bit of discussions and questions in various online communities on how to package and distribute the PowerShell Cmdlets, Functions, and Scripts. What I love about PowerShell is that you can be fast and loose with distributing functionality, very rigorous, or anywhere in between, when it comes to code distribution. I have sent one-liners via IM to folks and I have checked code into Team Foundation Server. It all depends on what your goal is.

I would like to discuss distributing code with a little more rigor than using email or IM as a distribution vector, although that does work great in some situations. Whether you are a developer writing compiled binary cmdlets or an IT Pro writing functions, answer is Modules.  You can read all about them in the help documents. Just run

PS > Help about_module

 

The beauty of Modules in PowerShell is that they allow you to easily distribute and deploy your code or cmdlets to others using nothing but copy and paste.  Let’s say you have a module with a a lot of functions to Get, Set, and Remove Network Settings, and you named this module Network. All you need to do is create a folder called “Network” and put your module files into that folder.

There are 2 default locations for Modules. There is one at the system level and also one for the current user, similar to how profiles work. The System Modules directory is

%windir%\System32\WindowsPowerShell\v1.0\Modules

and the one for the current user can be found at

%UserProfile%\Documents\WindowsPowerShell\Modules 

There are three basic types of modules; Script, Manifest, and Binary. Let’s look at each one, as they tend to build on on another.

Script Modules

Script modules are really nothing more than a .PS1 file renamed to .PSM1. For example, if you have a script that has a list of functions you use everyday called myfunctions.ps1, you could turn it into a module by renaming the script to myfunctions.psm1. Then, instead of dot sourcing your script, you could just use Import-Module to bring all those functions into your PowerShell session.

Manifest Modules

Manifests can be used to add a bunch of useful information for code authors and users. A manifest is a separate file that you can include with your PSM1 file or your compiled Module, which is just a DLL. The manifest file is just a a PowerShell HashTable. You can use a cmdlet called New-ModuleManifest to create one with some very basic information. Manifests are really nice for adding version information and prerequisites for your module. If you create a folder called  c:\windows\sytem32\windowspowershell\v1.0\modules\myModule and drop in a PSM1 file and a PSD1 file, PowerShell will load the manifest.  You just need to put in the ModuleToProcess field to add your PSM1 or DLL.

#
# Module manifest for module 'demo'
#
# Generated by: Andy Schneider
#
# Generated on: 4/4/2011
#

@{

# Script module or binary module file associated with this manifest
ModuleToProcess = ''

# Version number of this module.
ModuleVersion = '1.0'

# ID used to uniquely identify this module
GUID = '8e420ad8-c7d7-4139-8d2e-02d4e31416a9'

# Author of this module
Author = 'Andy Schneider'

# Company or vendor of this module
CompanyName = 'get-powershell'

# Copyright statement for this module
Copyright = '2011 - Use at your own discretion - if it kills your cat - not my fault'

# Description of the functionality provided by this module
Description = 'To demo a module manifest'

# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = ''

# Name of the Windows PowerShell host required by this module
PowerShellHostName = ''

# Minimum version of the Windows PowerShell host required by this module
PowerShellHostVersion = ''

# Minimum version of the .NET Framework required by this module
DotNetFrameworkVersion = ''

# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = ''

# Processor architecture (None, X86, Amd64, IA64) required by this module
ProcessorArchitecture = ''

# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @()

# Assemblies that must be loaded prior to importing this module
RequiredAssemblies = @()

# Script files (.ps1) that are run in the caller's environment prior to importing this module
ScriptsToProcess = @()

# Type files (.ps1xml) to be loaded when importing this module
TypesToProcess = @()

# Format files (.ps1xml) to be loaded when importing this module
FormatsToProcess = @()

# Modules to import as nested modules of the module specified in ModuleToProcess
NestedModules = @()

# Functions to export from this module
FunctionsToExport = '*'

# Cmdlets to export from this module
CmdletsToExport = '*'

# Variables to export from this module
VariablesToExport = '*'

# Aliases to export from this module
AliasesToExport = '*'

# List of all modules packaged with this module
ModuleList = @()

# List of all files packaged with this module
FileList = @()

# Private data to pass to the module specified in ModuleToProcess
PrivateData = ''

}
 

Binary Modules

If you are a developer or an IT Pro that loves to code, you might want to create a compiled module. This is a module that contains Cmdlets and or Providers that are compiled, and are typically written in C# or VB.NET. A binary module is actually a DLL file. You can read all about creating a compiled cmdlets here on MSDN. Just like a PSM1 module, you can create a module manifest and add the DLL into ModulesToProcess in your manifest.

Using Modules

There are several cmdlets that allow you to interact with Modules

image

What most of these do should be pretty obvious from their names. One nifty trick is the –listAvailable switch on get-module. this will list all the modules that are available on your system, so you know which ones you can import. You can even filter this based on Module type.

image

Comments are closed