PowerShell has a variety of powerful cmdlets built-in to the core language. But native functions only take you so far, and in most projects you will need more functionality. The PowerShell Gallery offers a wide range of downloadable third-party modules, but there’s also the option to create custom PowerShell modules. This article will guide you through the process of creating your first PowerShell module.
At its most basic, a PowerShell module consists of two required components and one optional. Together these components are the fewest recommended components to use in a PowerShell module.
psd1 File – PowerShell definition file
psm1 File – PowerShell module loading file
There are two types of modules, script modules, and binary modules. In this example, we are building a script module. Consisting of traditional PowerShell functions, a script function is easy to build. A binary module is a .NET framework compiled assembly. Written in .NET, cmdlets are not as approachable as script modules. First, we need to define the purpose of the PowerShell module. Not all aspects of a module need mapping before starting. Creating a clear plan makes defining necessary functions much easier.
Defining the Module’s Purpose
Crafting a module is not difficult, but structuring the exposed functionality can be. The purpose, of this article, is to create a simple module with three functions. Often modules contain functionality related to a single product or tool. The functions in our module target three different products but support a specific workflow. The workflow is to retrieve SharePoint members, trigger an onboarding Flow, and finally send the SharePoint group members in a Team’s message.
Structure of a Module
The structure of the module itself is pretty simple. The folder and file layout are as described below. One question you may have is why we prepend func_ to the function file. This is a personal preference and not necessary. This technique is useful to avoid dot-sourcing errant scripts in the module’s directories. You will see how to use this technique in the module loading file.
Private – Empty
Creating the Module
The fastest way to create a module definition file is the New-ModuleManifest command. Below, we are defining a handful of parameters that will create a usable module. CompatiblePSEditions defines both Desktop and Core as supported PowerShell versions. Command discovery works if you populate the FunctionsToExport parameter.
We export functions using Export-ModuleMember, but performance best practices dictate the use of empty arrays in the module definition. For unknown reasons, an empty array does not export correctly under VariablesToExport, but an empty string does output an empty array.
Running the New-ModuleManifest command creates a UtilityModule.psd1 file. Many comment blocks pertain to extra configurations. Below, we have removed all extra comments to show the configured parameters.
If all module functions are dot-sourced, then why do we need to list the functions to export? There are two primary reasons for explicitly listing exported functions. Private functions should not be made public, and exported functions will auto-complete on the command line even if the module is not yet loaded.
Next we need to create the module loading file. Again, there are several ways to approach this, but the below method has been reliable. The first section will only retrieve func_ prefixed files and dot-source them. The second will export all functions in the Public folder.
Next, we are defining a Power Automate Flow function. There is a simple way to do this by using the HTTP trigger, “When a HTTP request is received”. This uses the given URI displayed upon saving to call the trigger.
Get-SharePointMember supports our final workflow need of retrieving a SharePoint member list. This function gets all SharePoint site members for a given site and displays the results. Passing in a group will filter the results.
To test, run the various commands and make sure that they are functioning as you would expect. In the script below we are running the functions and utilizing their output.
# Get SharePoint Members
$Members = Get-SharePointMember
Invoke-PowerAutomateFlow -URI 'https://...'
New-TeamsMessage -Message $Groups -Title 'Group Members' -URI 'https://...'
Creating a module could not be simpler in PowerShell. To make a system administrator’s life easy, bundle common functions together into a module. There is a lot more functionality available and this tutorial only scratches the surface. Exploring the possibilities that PowerShell modules offer will unlock an easier administrative experience!
https://www.scriptrunner.com/wp-content/uploads/2021/03/powershell-best-practices.png10001000Philip Lorenzhttps://www.scriptrunner.com/wp-content/uploads/2018/05/ScriptRunner_Logo_RGB-300x45.pngPhilip Lorenz2021-03-10 10:00:042021-03-10 15:22:175 PowerShell Scripting Best Practices – From Runnable to Professional Code