Author Posts

January 23, 2018 at 2:03 pm

I would like to have multiple modules/scripts nested and imported with one module, the problem is that I want to keep the actual files across multiple directories:


I want to keep 1 function per .ps1 file.
I have tried the following:
in BuildTests.psd1 define NestedModules = @('.\GenericTests\GenericTests.psd1','.\SpecificTests\SpecificTests.psd1')
in GenericTests.psd1 define ScriptsToProcess = @('GenericTest1.ps1','GenericTest2.ps1')
accordingly configure SpecificTests.psd1

Basically this works, however when checking get-module, I see all the functions from .ps1 files imported twice, checking further import-module with -verbose parameter, I can see that one time it is "loading module ...test1.ps1" and next line is "Dot-Sourcing the script file ....test1.ps1".
I have tried different variations in .psd1 (changing from .ps1 to .psm1 and including them in nestedmodules), but I always seem to end up with duplicates imported or no functions imported at all.

January 23, 2018 at 2:32 pm

None of your files are explicitly loading or dot-sourcing these outside of what you've mentioned here? I ask because, just sitting on this end, the logic you're describing is a little tough for me to follow. It might be easier (for me) if you started with _what you want to happen_ rather than what you've done...?

January 23, 2018 at 2:50 pm

None of my files are loading nor dot sourcing anything.

I would like multiple functions, each defined in its own .ps1 file across multiple folders, to be available in a single module.
I would also prefer to maintain one manifest per folder and have all of those manifests included in a "root" manifest, if that is possible.

or in other words:
RootModule – includes nested modules from different folders.
Each nested module includes .ps1 files in their respective folder.

January 23, 2018 at 2:54 pm

So... I suppose I'll start with how _I_ would do this.

I would build all fo your functions as modules. .psm1 files, with .psd1 manifests, stored in folders as discrete, standalone modules. I wouldn't try using .ps1's – I'm not sure I see any advantage to doing so. Then, in my "parent" modules, I could simply specify all the ones I wanted at that one level.

The nesting functionality wasn't really meant to support "sub-sub" multiple levels of nesting, and by combining modules and scripts, I feel you're making it unnecessarily complicated.

Now, if the only way you want to live life is by having the "child" modules use a .ps1 for some reason, then I'd just have them dot-source their respective .ps1 files in the module code itself, rather than in a manifest. Although I still don't see the advantage of building a module that way, I suppose it's a free world ;).

January 23, 2018 at 6:40 pm

It looks like it's working just fine, what got me confused was the verbose output listing exporting/importing same function multiple times:

PS D:\DevRepository\ParentModule> Import-Module .\ParentModule.psd1 -Verbose
VERBOSE: Loading module from path 'D:\DevRepository\ParentModule\ParentModule.psd1'.
VERBOSE: Loading module from path 'D:\DevRepository\ParentModule\Modules1\Modules1.psd1'.
VERBOSE: Loading module from path 'D:\DevRepository\ParentModule\Modules1\TestCase1.ps1'.
VERBOSE: Dot-sourcing the script file 'D:\DevRepository\ParentModule\Modules1\TestCase1.ps1'.
VERBOSE: Exporting function 'test-case1'.
VERBOSE: Importing function 'test-case1'.
VERBOSE: Exporting function 'test-case1'.
VERBOSE: Importing function 'test-case1'.

And then checking the module ExportedFunctions property:

PS D:\DevRepository\ParentModule> Get-Module ParentModule | select ExportedFunctions

{[test-case1, test-case1]}

Which actually lists key/value pairs:

PS D:\DevRepository\ParentModule> (Get-Module ParentModule).ExportedFunctions

Key        Value
---        -----
test-case1 test-case1

Regarding .ps1 vs .psm1 it just felt unnatural to have a .psm1 with just a single function, but otherwise I really have no preference, so might as well rename those to psm1.