Creating PowerShell Modules

When you store PowerShell functions inside a Module, your functions become first-class citizen and are always available from any PowerShell Host.

Start with a PowerShell Function

To create a new module, start creating a PowerShell Function first. Either use one of the automatic ways described earlier, or use the below function to test-drive:

function Out-Voice
{
  <#
    .SYNOPSIS
    Sends text to the text-to-speech engine. Make sure your volume is turned up.

    .DESCRIPTION
    Uses the built-in text-to-speech engine to convert text to speech.

    .EXAMPLE
    Out-Voice -Text 'Hello World'
    Speaks: "Hello World!" 

    .EXAMPLE
    Out-Voice -Text 'Hello World' -Rate -10
    Speaks: "Hello World!" very slowly. Allowable speed rates are -10 to 10.

    .EXAMPLE
    Get-Content -Path c:\text.txt | Out-Voice
    reads each line of the text file

    .LINK
    https://powershell.one
  #>


  param
  (
    [String]
    [Parameter(Mandatory, ValueFromPipeline)]
    $Text,
    
    [int]
    [ValidateRange(-10,10)]
    $Rate = 0
  )
    
  begin
  {
    $tts = New-Object -ComObject Sapi.SpVoice -Property @{
      Rate = $Rate
    }
  }
    
  process
  {
    $null = $tts.Speak($Text)
  }
}

Test-drive the function until you are convinced the function is doing what it is supposed to. Don’t forget to add a Comment Based Help like in the example above so users (and you) can find out what the function does and how to use it:

Out-Voice -Text 'Hey, I can speak!'

Move Function to Module

Once your function is done, saving the function to a new PowerShell Module is a matter of just a few clicks:

Click anywhere inside the function (but do not select anything). This wakes up a button in the navigation bar:

Image

Click the button to save the function to a new or existing PowerShell Module. A wizard opens:

Image

To create a brand new module, choose Create New Module, and fill in a name for your new module:

  • Module Name: The module name should not be the name of your function. It should be a generic name such as a topic because later you will want to store more functions into your module. So for the function Out-Voice , you could call your module FunCommands. Do not use special characters or whitespace in your module name!

    By default, the new module is saved to your local user profile. Click the link Select Location if you’d like to create the module in a different folder.

    If you want to bulk-save more than one function to your module (provided your script contains more than one function), click the radio button Exporting all functions. Optionally, you can individually select the functions to export.

  • Description: Click the button Export. A new dialog opens and requires a sentence that describes the purpose of your module, for example: “A collection of fun PowerShell commands”. Click OK.

  • Done: A confirmation dialog opens. Click Yes if you would like to load the newly created function into the ISE editor. That’s normally not required, though. So in most cases, just click No.

Test-Driving Your Module

Switch to a different PowerShell, or open a new PowerShell (console or ISE). Your command Out-Voice is available immediately! It is now a standard PowerShell command just like the other commands you use. Run the command to make sure all works:

Out-Voice -Text 'Wow that works!'

To understand what just has happened, run this now:

PS> Get-Module

ModuleType Version    Name                                ExportedCommands     
---------- -------    ----                                ----------------     
Script     1.0        FunCommands                         Out-Voice            
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add...
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-T...

PowerShell has automatically loaded your new module FunCommands and made all of its commands available. ExportedCommands shows that currently your module just contains one function Out-Voice, but that can change anytime.

So PowerShell Modules are a perfect way of providing eternal life to your PowerShell Functions and make them available in every PowerShell Host on your machine.

Adding Functions to Existing Modules

A PowerShell Module can store any number of functions. To add more functions to an existing module, just follow the same steps as above. In the wizard, instead of Create New Module, check Select Existing Module, and pick the module in the dropdown list.

You can add new functions only to modules that were created by ISESteroids. That’s a safety measure. It is generally not a good idea to add new functions to PowerShell Modules that you did not create yourself.

When you add new functions to an existing module, the minor version of the module is automatically incremented.

PowerShell caches Modules so once you have loaded and used a module in a PowerShell session, any changes to the module will not become effective. To see changes, either use the module in a new PowerShell Host, or force a complete module reload:

Import-Module -Name FunCommands -Force -Verbose

Updating Functions in Modules

To change and update functions that you have exported to a module before, simply follow the steps above and save the new version of your function to the module again.

The wizard will report that such a function is already present in your module and asks if it is ok to overwrite the function. When you confirm, your new version of the function replaces the old version, and the minor version of your module is bumped up by one.

If you would like to remove a function from a module, there is no way to do this from the user interface. We’ll look at the auto-generated module in a second, and you’ll learn how you can remove functions from an existing module.