PowerShell 2.0 - Module Initializers

You might not know it, but when you import a PowerShell module you can pass it one or more arguments by way of Import-Module's -ArgumentList (aliased to -Args) parameter. While it looks like passing parameters to a standard ps1 file, there are some limitations. Take this module for an example:

# -- begin foo.psm1 --
param()
 
. {
  param(
     [validateset("a","b","c")]
     $letter
 
     function Get-Letter {
        "You initialized the module with $letter"
     }
} @args
# -- end foo.psm1

ps> import-module foo -args b
ps> get-letter
"You initialized the module with b"

You might notice that I am dotting (dot-sourcing or dot-executing) the scriptblock. By doing this, you are ensuring that anything declared in the scriptblock is imported into the calling scope. You can also apply advanced-function style validation to the module initializer by splatting (@) the module arguments ($args). If the scriptblock was called instead (via & { ... } @args) then the nested scope created from the call (&) operator prevents the function Get-Letter from being exported from the module because it goes out of scope when the called scriptblock completes. So, why not put the param block at the top of the module where param() is now you might ask? Because that mechanism is broken and/or partially implemented in v2, and completely ignores [cmdletbinding()] directives and validators. Note also that there is no way to use switches in the traditional sense with module arguments; instead you can pass boolean literals like $true or $false which will be mapped positionally to any declared switches.

So where might you use this technique of module initializers? You could create a generalized custom module that works with your various development environments, or SQL clusters/servers. You pass the name of the environment (or server) to the module on import, and all of the functions exported then are "bound" to that cluster (or server) so you don't have to continually pass each function the cluster (or server) name as an argument.

Have fun!

blog comments powered by Disqus

About the author

Irish, PowerShell MVP, .NET/ASP.NET/SharePoint Developer, Budding Architect. Developer. Montrealer. Opinionated. Montreal, Quebec.

Month List

Page List