Microsoft Scripting Guy Ed Wilson here. One of the cool things about Windows PowerShell is that if you do not like the way it does things, you can change it. If there is something that is lacking in the released product, you can often find it in a module that someone has written and posted to the web. There are several good modules available on the Internet that are worth exploring and worth using.

One problem with using modules is you now have a dependency on external code, and this means that a script that uses the module must have the module installed or the script will fail. If you control the environment, taking an external dependency is not a bad thing; if you do not control the environment, an external dependency can be a disaster.

One thing that can be used to check for dependencies is the #requires statement in Windows PowerShell 2.0. It can be used to check for the specific version of Windows PowerShell, a specific shellID, or a particular pssnapin (including major and minor version). Unfortunately, the #requires statement cannot be used to check for a required module. This is where my Get-MyModule.ps1 script comes into play.

Get-MyModule.ps1

Function Get-MyModule
{
Param([string]$name)
if(-not(Get-Module -name $name))
{
if(Get-Module -ListAvailable |
Where-Object { $_.name -eq $name })
{
Import-Module -Name $name
$true
} #end if module available then import
else { $false } #module not available
} # end if not module
else { $true } #module already loaded
} #end function get-MyModule
get-mymodule -name "bitsTransfer"

The Get-MyModule function accepts a single string—the name of the module to check. The if statement is used to see if the module is currently loaded. If it is not loaded, the Get-Module cmdlet is used to see if the module exists on the system. If it does exist, the module is loaded.

If the module is already loaded in the current Windows PowerShell session, the Get-MyModule function returns $true to the calling code. Let’s dig into the function in a bit more detail to see how it works.

The first thing I do is use the if statement to see if the module is not loaded in the current session. To do this, I use the –not operator to see if the module is not loaded. The Get-Module cmdlet is used to search for the required module by name. This section of the script is shown here:

Function Get-MyModule
{
Param([string]$name)
if(-not(Get-Module -name $name))
{

To obtain a list of modules that are installed on a system, use the Get-Module cmdlet with the –ListAvailable switch. Unfortunately, there is no way to filter the results, and this necessitates piping the results to the Where-Object cmdlet to see if the required cmdlet is installed on the system. If the module exists on the system, the function uses the Import-Module cmdlet to import the module, and it returns $true to the calling code. This section of the script is shown here:

if(Get-Module -ListAvailable |
Where-Object { $_.name -eq $name })
{
Import-Module -Name $name
$true
} #end if module available then import

The last two things to do in the function are to handle two other cases. If the module is not available, the Where-Object cmdlet will not find anything. This triggers the first else clause, where $false is returned to the calling code. If the module is already loaded, the second else clause returns $true to the script. This section of the script is shown here:

else { $false } #module not available
} # end if not module
else { $true } #module already loaded
} #end function get-MyModule

A simple use of the Get-MyModule function is to call the function and pass the name of a module to it. This example is actually seen in the last line of the Get-MyModule.ps1 script:

get-mymodule -name "bitsTransfer"

When called in this manner, the Get-MyModule function will load the bitstransfer module if it exists on your system and if it is not already loaded. If the module is already loaded or if it is loaded by the function, $true is returned to the script. If the module does not exist, $false is returned. The use of the Get-MyModule function is shown in the following image.

Image of using Get-MyModule function

A better use of the Get-MyModule function is to use it as a prerequisite check for a script that uses a particular module. Your syntax might look something like this:

If(Get-MyModule –name “bitsTransfer”) { call your bits code here }

ELSE { “Bits module is not installed on this system.” ; exit }

I will be using my new function in the coming days when I talk about using Windows PowerShell to interact with Group Policy.

We invite you follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys