PowerShell modules allow you to combine multiple scripts to simplify code management, accessibility and sharing.
If you’re like any other IT pro, this situation probably sounds familiar to you. It's not until you begin thinking about creating solutions -- rather than scripts -- that you begin to dabble in PowerShell modules.
PowerShell modules aren’t required to show that you know how to write PowerShell scripts, but they are highly recommended -- especially once you’ve graduated past those one-off, ad hoc scripts. Modules enable a scripter to combine like scripts into a single, cohesive unit. This makes managing code much easier, makes code more easily accessible, and allows you to easily share your code with others.
What is a PowerShell module?
Now that you know why you'd want to write a module, let's discuss briefly what makes a PowerShell module. In simplest terms, a module is just a grouping of functions and code around a central theme. Modules are created for applications (like Microsoft Exchange, Active Directory, VMware, and so on) to manage all aspects of different applications. They are created for print management, network adapter configurations, and more. There's always a central theme or object that modules are created to manage.
There are four different PowerShell modules:
- Script Modules -- PSM1 files that typically contain mostly functions, but can contain any valid PowerShell code.
- Binary Modules -- Compiled DLL files typically not created by IT pros; these are usually left up to developers.
- Manifest Modules -- Script modules that contain a manifest.
- Dynamic Modules -- Modules that are never written to disk and are only available in memory.
Each module serves specific purposes, but the module type you'll be creating will most likely be script modules. Script modules don't require knowledge of C# or the compilation process, and they are the most common, especially among IT pros.
When do I create a PowerShell module?
You can easily decide whether to create a module by answering the following questions while writing a script:
- Will the code I'm writing need to be used more than once?
- Does this code essentially manage a single object or entity?
- As I write this code, do I find that I'm breaking it apart into functions because it's getting too complex to be in a single script?
- Do I need to share the code with others?
If you answered yes to at least three of these four questions, it's a good bet you should be writing a module instead of a PS1 script.
How do I create a PowerShell module?
Open up Notepad. Save the file with a PSM1 extension. Done.
No, really, that’s it. That's all it takes to create a script module. Granted, it won't be a very functional module, but technically it is a script module. Let's concentrate on something more useful, though. Examples are always a great way to demonstrate a concept, so let's create a module to manage houses in a subdivision. This isn't a practical example (at least not until the PowerShell team figures out how to integrate PowerShell into the physical world) but it will show off a little of what a module is capable of.
I've got every function I need to create new houses, find all the houses I've created, modify the houses, and finally, remove houses. The houses I'm managing with this module happen to be in the 'Fancy subdivision' neighborhood, so it's good practice to set that as a module variable at the top. This way, I can reference that variable in any of my functions.
Because I'm sharing this module with my contractors, I don't want them to build any new houses or remove any houses without my permission, so I'm only allowing them Get-* functions and Set-* functions. I want my contractors to be able to tell what neighborhood we'll be working in, so I allow them to see the value of $Neighborhood in their PowerShell console.
How do I use a PowerShell module?
I've got the house module created, and I've called it House.psm1. Now I want my contractors to use it, so I place it in a shared folder called HOMESERVERfileshare on my network. Then I tell each contractor to open up their PowerShell console and import it.
Importing the module brings all of the functions and variables into each contractor's PowerShell session.
You can see that they can run Get-House and Set-House, but the moment they try to run Remove-House, PowerShell throws an error. This is because PowerShell doesn't recognize this function, because I didn't allow it to load into the current session. At this point, they can still use this module with no problem. However, if they close the console and open it again, the Remove-House function won't be available.
Whenever you run Import-Module (or use PowerShell's auto-loading feature), it only loads the module in the current session. It will not load it again. The contractor must either load the module again or, preferably, place the module into the PsModulePath so that it auto-loads the next time a House function is needed.
This should get you started using modules. However, there's a lot of other great functionality that PowerShell modules provide. If you'd like a deeper look at modules, the best resource I've found that covers nearly all features of modules is entitled, Further Down the Rabbit Hole: PowerShell Modules and Encapsulation. It's an older article, but a lot still applies today.