So I implemented my first Powershell module with a bunch of .ps1
files (one per function) and the .psd1
manifest file.
I am trying to understand what is the purpose of the .psm1
files - do I need them at all in my module?
What is their added value?
EDIT 1
Here is my .psd1
file:
@{
ModuleVersion = "0.0.19106.59054"
GUID = "59bc8fa6-b480-4226-9bcc-ec243102f3cc"
Author = "..."
CompanyName = "..."
Copyright = "..."
Description = "..."
ScriptsToProcess = "vsts\config.ps1"
VariablesToExport = @(
"TfsInstanceUrl",
"TfsApiVersion",
"QANuGetRepoUrl"
)
NestedModules = @(
"db\Backup-Database.ps1",
...
"vsts\work\Get-WorkItems.ps1"
)
FunctionsToExport = @(
"Assert-ExtractionDestFolder",
...
"Write-HostIfNotVerbose"
)
PrivateData = @{
PSData = @{
ExternalModuleDependencies = "SqlServer"
}
}
}
Like I said, each function is in its own file.
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).
Typically, a script module manifest has a RootModule
entry pointing to (the main) *.psm1
file; for smaller modules it is not uncommon for all of the module's functionality to be implemented in this one *.psm1
file.
In fact, a stand-alone *.psm1
file can also act as a module, though it doesn't integrate with PowerShell's module auto-discovery and auto-loading feature.
Note that if you were to use a regular *.ps1
script directly in RootModule
, its definitions would be loaded into the caller's scope, not the module's; that is, you would lose the benefits of a module.
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
).
*.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.
.psm1 file is powershellmodule file. When we create script module we write all the functions of a module in a .psm1 file then we export the functions and then we can use those functions by importing module. .psm1 is basically refers the powershellmodule. Powershell directly identifies anything which is written in this file will be a part of module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With