Monday, June 22, 2015

Quick and Dirty Powershell Modules

So you have built some awesome scripts and turned them into advanced functions. Whats next? It is time to put them into a module. It can be a lot easier than you realize. Lets go step by step and build our first module to hold all of your advanced functions.

# Start in our profile powershell folder
CD ~\Documents\WindowsPowershell

# Create a folder for our module and functions
MD Modules\Other\Functions

# Create a module manifest
$Manifest = @{
    Path        = ".\Modules\Other\Other.psd1"
    RootModule  = ".\Other.psm1" # Module loader
    Author      = "Kevin Marquette"
    Description = "Odds and ends"   
}
New-ModuleManifest @Manifest -Verbose

# Create our module loader (that loads our advanced functions)
$ModuleLoader = @'
  $moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path

  Write-Verbose "Importing Functions"
  # Import everything in the functions folder
  "$moduleRoot\Functions\*.ps1" |
      Resolve-Path |
      Where-Object { -not ($_.ProviderPath.Contains(".Tests.")) } |
      ForEach-Object { . $_.ProviderPath ; Write-Verbose $_.ProviderPath}
'@

Set-Content -Value $ModuleLoader -Path .\Modules\Other\Other.psm1

# Now create a single file for each advanced function and place it in the functions folder
# Sample function
$TestFunction = @'
   function Test-Other
   {
        [cmdletbinding()]
        param()
        Write-Output "Hello World!!"
   }
'@
Set-Content -Value $TestFunction -Path .\Modules\Other\functions\Test-Other.ps1

# Load it and test it out
Import-Module Other -Verbose -Force
Test-Other


You could easily place all your functions into the Other.psm1 file and everything would still work. But this creates a framework that makes your functions easy to manage. That functions folder can now be a dumping ground for all your advanced functions. If you out grow this module, you can create a new one and just move the functions over.

The module loader is what enables that. Later we will add pester tests and this already accounts for this. This is a pattern that I seen used by other Powershell MVPs. It has greatly simplified my function management.

No comments: