Sunday, July 27, 2014

PowerShell Modules Make Life Easier

When I first started developing in PowerShell, I just dot sourced any code I needed. 

.  C:\Users\BryanCafferky\Documents\PowerShell\function\myfunction1.ps1

Myfunction1 “parm1” “parm2”

But as the complexity of code and number of functions increased, this became more and more of an issue.  Consider that when you move the code to run on a server, you now have to manually change all the paths to your functions.  
A quick and dirty fix would be to add a variable to the top of the script that has the path to the code, i.e.

$codepath = “C:\Users\BryanCafferky\Documents\PowerShell\function\”
. ($codepath + "ufn_copy_file.ps1")
. ($codepath + "ufn_move_file.ps1")
Ufn_copy_file “file” “file2”

However, a better idea is to use modules because PowerShell has the ability to automatically find modules via the environment variable $env:psmodulepath and it can load as many functions as you need via one line of code.

What is a module?

A module is just a collection of PowerShell functions that can be automatically loaded together as easy as:

Import-module “mymodule”

For example, entering,

Import-Module “sqlps”

Will load the SQL Server PowerShell module with all the useful command-lets it contains. 

There are several ways of creating modules but the easiest way is to simply take a bunch of functions you want included in the module and put them all in one file with an extension .psm1 .  Then place this file in a folder where PowerShell will find it.  To determine what folders that is, just type $env:psmodulepath and press enter as shown below.

As a rule, you will see \WindowsPowerShell\Module under your documents folder and you can place your module there, i.e. on my machine this is…


But you can place it in any folder listed in $env:psmodulepath.  

Is that All?

Not quite.  A module needs to have a folder of its own named for the module, i.e. MyModule and the script file that holds the functions needs to be in the module folder with the same name, i.e MyModule.psm1 as shown below.

That’s all there is to it and from now on when you need a function from that module, all you need to do is enter…

Import-Module “MyModule”

A couple of side notes here.  First, if you ever get a module from somewhere and PowerShell can't find it, check to make sure you put it in a folder contained in $env:psmodulepath.  Second, if you copy your module to another machine, make sure you place it in a folder contained in $env:psmodulepath.

Say good bye to dot sourcing and hello to automatically loaded functions.