FredBainbridge

Nested PowerShell Modules

If you are curious about how to import a PowerShell module that has dependencies on other modules this can be done with the module manifest file (PSD1). You can do some pretty wild stuff with a PowerShell Module Manifest file. For starters here is a great outline how that file works with some decent examples.
Here is an example of how to have nested PowerShell modules. The nested module in this case being a C# compiled .dll. It is nothing fancy, just a custom class definition. More on PowerShell classes here.

First you use the NestedModules element of the psd1 file to reference the path of the nested module to be loaded. This requires a path relative to a location in the $env:PSModulePath. Aka, where you would normally look for modules. In this case the module would be expected to be found at [PSModulePath]\TCMABL\. This can be a comma separated list if you have multiple nested modules.

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
NestedModules = @("TCMABL\Player.dll")

Then use the ModuleList element to list all modules packaged with this module. Note – your nested modules do not have to be packaged with your module. But if you want to ensure it is present it may be a good idea to package them together.

# List of all modules packaged with this module
ModuleList = @("TCMABL\TCMABL.psm1","TCMABL\Player.dll")

That is it. Now the nested module will be available as long your original module is loaded. But the nested module itself won’t be listed as loaded if you do a Get-Module. But rest assured, it’s there and ready for use.

For fun, let's prove it!

First, clear all loaded modules:

Get-Module | Remove-Module

Import just the nested module. (I am not using relative paths in this example, but you can)

Import-Module .\TCMABL\Player.dll
Get-Module

PSGet-Module

Now I can instantiate my custom class if I so desire.
PSCustomClassInstantiation
Side note – This class was used for some sabremetric baseball stats for an amateur baseball league I play in. I'm so replacement level.

In order for the object type to no longer be available you have to restart the PowerShell instance. Close and open the ISE or whatever you are using for you PowerShell development. If you try to instantiate the custom object now, it won't work unless you have the module package present in your $env:PSModulePath.

Now load your PowerShell module that has this .dll listed as a nested module and do a Get-Module. Notice only the PowerShell module I imported is now available.

PSCustomModule

Notice you don't see the NestedModule listed but you can still instantiate the custom object!
PSCustomClassInstantiation2

Cool stuff.


Share