One of the really cool things about PowerShell is that you aren’t limited to using Microsoft’s native set of cmdlets. You can add custom cmdlets to PowerShell by including them in a module. Even though this probably sounds like an advanced topic, it is surprisingly easy to do. Even a lot of the documentation about module creation is more complex than it needs to be. In this article, I’m going to show you a really simple way to create modules.
Before I begin
As previously noted, a module is nothing more than a collection of custom PowerShell cmdlets. You might have noticed in the past that when you install Microsoft Server products, they generally include some product-specific PowerShell cmdlets. These cmdlets are enabled through the use of modules.
From a practical standpoint, a module is essentially just a PowerShell script. Unlike normal scripts, modules must be stored in a specific location, and they have to use the PSM1 file extension. Aside from that, modules are just scripts.
So if a module is little more than a PowerShell script, where do the custom cmdlets come from? Well, like other PowerShell scripts, modules can contain functions. The names of the functions contained within a module become custom commands. If, for example, I created a function named Do-Something, then the mere existence of that function within the module (and one more command that I will show you later) would cause a new PowerShell cmdlet called Do-Something to be created.
Creating a normal script
When I create a module, I like to begin by creating a normal PowerShell script. That makes it easy to make sure that my function is working before I incorporate it into a module. So with that said, let’s create a sample script called Sample.ps1. This script will include a single function and a line of code that calls the function just to make sure that it works. Here is the code for my script.
So as you can see, this script is super-simple. It contains a function called Do-Something. That function doesn’t do anything other than to display a line of text saying “I am doing something” as confirmation that the function has been executed. The last line of the script calls the function. Here is what it looks like when the script runs.
So now that we have created a function and used a script to confirm that the function works let’s turn the script into a module. Before I do, though, there is something important that I need to mention. In the interest of keeping things simple, I am going to be building a module consisting of a single function. In the real world, however, it is very common for a module to contain multiple functions, each of which is treated as a PowerShell cmdlet.
The next thing that we need to do to create a custom PowerShell module is to pick out a name for the module. This sounds like a trivial step, and in some ways, it may be, but the module’s physical path on the system has to match the module name.
With that said, navigate through the Windows file system to \Windows\System32\WindowsPowerShell\v1.0\Modules. Now, create a folder within which your module will reside. The folder name must match the module name. For example, I am calling my module Demo, so my folder will also be named Demo.
Now, open the folder that you just created and create a .PSM1 file within the folder. This file’s filename must match the name of the module folder that you just created. In my case, for example, I named my folder Demo, so I am going to name my module file Demo.psm1.
Now that the module file has been created, go ahead and open it in your favorite editor. If you use Notepad as I do, be aware that Notepad no longer saves files in ANSI format by default. With the editor open, copy, and paste the function from your script into the module.
There are two things worth pointing out about this particular step. First, as you may recall, my test script included a line (it was the very last line in the script) that called the function. This line should not be included in the module.
The other thing to pay attention to is the name of your function. The function name will become a cmdlet name. Technically, you can call your functions anything that you want so long as the name isn’t already in use by another cmdlet. However, as a best practice, I recommend sticking to the verb-noun format used by standard PowerShell cmdlets. That’s why I called my function Do-Something.
The last thing that you will need to do is to add one line to the end of your module file. This line makes the function name available as a cmdlet. Here is what this line looks like for my Do-Something function:
Export-ModuleMember -Function ‘Do-Something’
If your module file contains multiple functions, then you will need to create a separate Export-ModuleMember command for each function. Here is what the finished module file looks like:
At one time, it was necessary to import a module before you could use the cmdlets within it. Today though, this is no longer necessary. Simply enter the name of your custom cmdlet into PowerShell, and the cmdlet should be available. You can see an example of this below.
Custom PowerShell cmdlets: Recycle your code
The nice thing about building your own custom PowerShell cmdlets with modules is that it is a great way to reuse code. If you have a particular function that you use from time to time, you could turn that function into a cmdlet so that you do not have to include the function in your PowerShell scripts in the future.
More PowerShell Basics articles
- Exchange 2019: Managing your distribution groups with PowerShell
- Cracking the code: Here are the best editors for PowerShell scripts
- Find what you need: Using PowerShell to parse Windows log files
- Neat trick: Organizing and formatting messy PowerShell output
- Adding help to your custom PowerShell cmdlets: Step-by-step guide