There are so many new things in Windows PowerShell that I often assume that I know the basics. But, while working on a project about modules, I ran into some new guidance from PowerShell developer Jason Shirk and a great blog post that demonstrates that information about variables in a TechNet topic about module manifests is wrong.
Here are some important reminders about modules and their manifests:
- By default, all functions and aliases are exported, but variables are not exported.
“By default, all variables are exported” in How to Write a Module Manifest (MSDN) is wrong. This topic is outdated anyway. It lingers from the time of the original New-ModuleManifest cmdlet, which prompted you for about 20 of the 49 parameters, even when only Path is mandatory
- The Export-ModuleMember cmdlet overrides the default export behavior. When you use it, only the commands that you specify are exported.
Therefore, by itself, this command prevents all functions and aliases, and all other variables in the module, from being exported.
Export-ModuleMember -Variable myVar
- You can have multiple Export-ModuleMember commands in a module. All of the statements are processed; none takes precedence. So, the result is the union of the statements.
Therefore, these statements, in any order…
Export-ModuleMember -Variable myProfiles Export-ModuleMember -Function Get-Profile, Set-Profile Export-ModuleMember -Function Get-Profile
…are equivalent to:
Export-ModuleMember -Variable myProfiles -Function Get-Profile, Set-Profile
As a best practice, mostly for visibility, I prefer one Export-ModuleMember command as the last statement in a module file, but that’s just a recommendation.
- The value of the Variable parameter of Export-ModuleMember must be a name, not a variable that begins with $.
This is correct:
Export-ModuleMember -variable myProfiles # Omits $
This has no effect, but it does not generate any errors.
Export-ModuleMember -variable $myProfiles # Includes $
- The *ToExport keys in a module manifest can only further restrict exports. They cannot add to exports.
Therefore, if the module includes:
Export-ModuleMember -Function Get-Widget
And, the manifest includes:
FunctionsToExport = 'Get-Widget', 'Set-Widget'
Only Get-Widget is exported.
Be very careful with this one. When the value of any *ToExport key is an empty array, no objects of that type are exported, regardless of the value the Export-ModuleMember.
FunctionsToExport = @()
- Redundant Export-ModuleMember and module manifest values do no harm and have no special effect.
# In module Export-ModuleMember -Function Get-Profile # In module manifest FunctionsToExport = 'Get-Profile'
- Use explicit names in the value of the *ToExport keys in the module manifest, instead of wildcard characters (*).Jason Shirk (@lzybkr), the PowerShell team developer who maintains the module discovery code, says:
“PowerShell does expensive work during command discovery if you use wildcards, skips that if you are explicit….[O]n a fresh Win10 system, if all modules do it correctly, can save 15 [seconds].”
FunctionsToExport = 'Get-Profile', 'Set-Profile'
FunctionsToExport = '*'
I needed the reminders and Jason’s performance report will change how I write my module manifests.