what is the purpose of the .psm1
files - do I need them at all in my module?
In script modules, i.e., modules authored in PowerShell (as opposed to compiled binary cmdlets), it is only *.psm1
files that provide the module-specific behaviors distinct from regular *.ps1
script files (separate, isolated scope, private commands, control over exported commands).
Even though you're listing regular *.ps1
scripts in your NestedModules
manifest entry, by virtue of using that specific entry these scripts are dot-sourced in the module's context and thereby become part of the module:
This is conceptually equivalent to creating and referencing a root *.psm1
script in RootModule
, and - instead of defining a NestedModules
entry - explicitly dot-sourcing your *.ps1
scripts from there - see bottom section.
Note that if you were to reference *.psm1
files in NestedModules
, they would truly become nested modules, with their own scopes; a nested module is usable from the enclosing module, but not visible to the outside world (though you can list it among the loaded modules with Get-Module -All
).
Listing *.ps1
files in NesteModules
vs. dot-sourcing them from the RootModule
While there should be no difference in functionality, using a *.psm1
RootModule
to dot-source the *.ps1
files containing your module's functions can potentially simplify things, if you simply need to dot-source all *.ps1
files located in your module directory's subtree:
# Add this to the *.psm1 file specified in 'RootModule'
# Find all *.ps1 files in the module's subtree and dot-source them
foreach ($script in
(Get-ChildItem -File -Recurse -LiteralPath $PSScriptRoot -Filter *.ps1)
) {
. $script
}
If you need to load the scripts in a specific order, need only a subset of the scripts, or want to speed things up slightly (though I doubt that the speed difference will be noticeable), you can dot-source the files individually from a RootModule
*.psm1
file, as an alternative to listing them in the NestedModules
entry:
# Add this to the *.psm1 file specified in 'RootModule'
# Dot-source the *.ps1 files individually.
. "$PSScriptRoot/db/Backup-Database.ps1"
# ...
. "$PSScriptRoot/vsts/work/Get-WorkItems.ps1"
Again, all of the above approaches are functionally equivalent.
Given that you explicitly export functions via the ExportedFunctions
entry (as is advisable), the use of *.ps1
files that must be dot-sourced is ultimately an implementation detail that is not relevant for the purposes of command discovery and module auto-loading - it only matters at actual import time.