Powershell modules

 

 

Powershell modules

Powershell modules are packages that contain one or more blocks of code such as scripts, cmdlets, manifests, and functions that have a related purpose - as well as aliases and variables.

Because of the way Powershell is constructed it is easier to use a function that is part of a module than it is to run a script - so I looked at the possibility of turning my Powershell firewall script into a single function module.

NB - this is all based on Powershell version 5.1 as that is the version installed on Windows 10 1809.

 

Module related commands

There are a number of Powershell commands that allow you to look at the modules that are installed as part of the Powershell installation.

The most basic one is

Get-Module

which shows the installed and active Powershell modules.

An extension of this command is

Get-Module -ListAvailable

which shows the list of all the installed modules that are available for use but not currently active.

It is possible to look inside each module to see what functions are available in that module -

Get-Command -Module <module-name>

Some modules may have only one block of code inside them, but others may have dozens.

 

File locations

The code for all these modules are stored in files on the computer - in Powershell 5.1 there are two default locations in Windows 10 1809 for the installed modules, and another third default location for added modules that are user specific.

The first default location is

C:\Windows\System32\WindowsPowerShell\1.0\Modules

and is the location used by Microsoft for modules that are included by Microsoft in the Windows installation - this location should not be used for user added modules.

The second default location is

C:\Program Files\WindowsPowerShell\Modules

and can be used to install add-on modules that need to be accessible to all users on the computer.

The third default location is

C:\Users\<Username>\Documents\WindowsPowerShell\Modules

and can be used to install add-on modules that are available for just that one user.

Module files don`t have to be stored in these locations, but it makes it more complicated if they are elsewhere because the path to them will have to be added.

Powershell 5.1 knows about these three paths and has a PATH environment built in - this can be viewed using the command

$env:PSModulePath

Easier to read is the output from

$env:PSModulePath -Split ';'

Note that the location

C:\Program Files\WindowsPowerShell\Modules

is added to the value of the PSModulePath environment variable by default in Windows PowerShell 4.0 and later. For earlier versions of Windows PowerShell, you will have to manually create the location and then add it to the PATH.

 

Changing the Powershell PATH

To add a new module location, use the following command format.

$Env:PSModulePath = $Env:PSModulePath + ";<path>"

The semi-colon (;) in the command separates the new path from the path that precedes it in the list.

However this is not permanent - when the Powershell session is closed it forgets the addition to the PATH.

The location of the PATH in the registry is

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PSModulePath

This shows the two system paths, but it is not modified by the above command to add the new path.

Microsoft publish a rather complicated way to change the PATH permamently using a three line Powershell script -

$p = [Environment]::GetEnvironmentVariable("PSModulePath")

$p += ";C:\Program Files\<new-folder>\Modules\"

[Environment]::SetEnvironmentVariable("PSModulePath",$p)

It does work but it isn`t permament unless you do an environment broadcast message - when you close the Powershell console the addition to the path is forgotten.

Another thing to watch is that the commands

$env:PsModulePath

and

[Environment]::GetEnvironmentVariable("PSModulePath")

may show that there is already a semi-colon at the end of the path - if you use this script as it stands you will end up with two semicolons, which Powershell will not like - you may need to take out the semicolon in the second line of the script.

It is quite straightforward to change the PATH in the registry - it could be done by editing the registry entry directly, but that is not really advisable.

Much easier to go to Control Panel / System / Advanced system settings / Environment Variables - on the lower pane scroll down to PSModulePath and edit that by adding the new path.

This will edit the registry entry, and the command

$env:PSModulePath -Split ';'

should now show the added path.

A restart may be advisable, as is quite common after changing the registry.

 

Downloading modules

Out there in the outside world there are several thousand modules that are available for download - the command

Install-Module

can be used to download one or more modules from a repository, and install them on the local computer.

The command has a Scope parameter that allows you to specify whether the module is installed for the current user or for all users.

By adding the parameter

Install-Module ..... -Scope AllUsers ......

the module will be installed in

C:\Program Files\WindowsPowerShell\Modules

By adding the parameter

Install-Module ..... -Scope CurrentUser ......

the module will be installed in

C:\Users\<Username>\Documents\WindowsPowerShell\Modules

If the "Scope" parameter is not used the default location depends on which version of Powershell is being used.

 

Importing modules

The command

Import-Module

adds one or more modules to the current session - and only the current session - close the Powershell session and they are gone on the next session.

Beginning in PowerShell 3.0, modules are imported automatically when any cmdlet or function in the module is used in a command as long as the module is included in the PATH in the PSModulePath environment variable.

If the module is not on a valid path you can still import them by providing the path.

So to use the default installed modules in a Powershell 5.1 environment this command is not required.

 

Turning my script into a module

A module can contain any number of components - scripts, cmdlets, manifests, and functions.

Probably the simplest component it can contain is a single script that contains a function - instead of naming the script with the " .ps1 " extension, the script is named with a " .psm1 " extension.

The name of the script has to have the same name as the name of the folder containing the module.

To turn the script into a function just involves adding a bit of text to the start of the script and ending the script with a curly bracket -

function Set-FirewallScript {

<whole script>

}

So the script is now a function with the name " Set-FirewallScript ".

I did it three times to see how the different locations behaved - I used the two default locations and created a new one as well.

So the paths to the default locations for my scripts are

C:\Program Files\WindowsPowerShell\Modules\FirewallScript\FirewallScript.psm1

and

C:\Users\<Username>\Documents\WindowsPowerShell\Modules\FirewallScript3\FirewallScript3.psm1

The path to the new location that I created is

C:\Program Files\Powershell-Dev\Modules\FirewallScript2\FirewallScript2.psm1

After updating the Powershell PATH as described above, the command

Get-Module -ListAvailable

shows the three functions in their various locations.

 

 

 

 

 

website design by ron-t

 

website hosting by freevirtualservers.com

 

© 2024   Ron Turner

 

+                                   +  

 

Link to the W3C website.   Link to the W3C website.