Easy Installation of Your Own PowerShell Modules

I’ve been working a lot with PowerShell of late, developing modules and deploying them to my own Modules folder. This is a pretty basic set of tasks, something I do over and over. As such, I decided to script it!

First thing I wanted to do was ensure the WindowsPowerShell\Modules folder exists under the users Documents folder. To do that I created a simple function, Add-WindowsPowerShellFolder. If the WindowsPowerShell folder, and under it the Modules folder, don’t exist, they are created.

#—————————————————————————–#
# This checks to see if the WindowsPowerShell folder is in the users
# document folder, then checks to see if the Modules folder exists under
# the WindowsPowerShell folder. If they do not exist, they are created.
# This is primarily a helper function for the Install-MyModule function
#—————————————————————————–#
function Add-WindowsPowerShellFolder()
{
 
  $psUserPath = "C:\Users\$([Environment]::UserName)\Documents\WindowsPowerShell"
  if($(Test-Path $psUserPath) -eq $false)
  {
    New-Item -ItemType Directory -Force $psUserPath
  }

  $psUserModulePath = "$($psUserPath)\Modules"
  if($(Test-Path $psUserModulePath) -eq $false)
  {
    New-Item -ItemType Directory -Force $psUserModulePath
  }

}

Next, I check to see if the folder for the specific Module I’m wishing to deploy exists, and if not create it.

#—————————————————————————–#
# This checks to see if the folder for the Module you want to install
# exists, and if not it adds it.
# This is primarily a helper function for the Install-MyModule function
#—————————————————————————–#
function Add-ModuleFolder($ModuleName)
{
 
  $psUserModulePath = "C:\Users\$([Environment]::UserName)\Documents\WindowsPowerShell\Modules"

  $psModulePath = "$($psUserModulePath)\$($moduleName)"
  if($(Test-Path $psModulePath) -eq $false)
  {
    New-Item -ItemType Directory -Force $psModulePath
  }

}

Finally I call the main function, the Install-MyModule. This has two parameters, the name of the Module and a collection of files to copy.

First, I use the functions above to validate the needed folders exist. There is also a switch, –Replace, which will delete all files and subfolders in the target module folder.

After this is a simple routine that loops over each file and copies it to the target. This allows you to copy files from multiple folders all to the same target.

This routine does assume there are no subfolders to be deployed to the target module folder, which is pretty common.

 

#—————————————————————————–#
# This is the main function of this script. It first ensures the requisite
# folders exist in order to deploy.
#
# If the -Replace switch is used, the target folder will be cleaned out
# prior to the copy.
#
# Next, it iterates over the list of files passed in and copies them to the
# target folder.
#—————————————————————————–#
function Install-MyModule()
{
  [CmdletBinding()]  
  param ( 
         [Parameter( Mandatory = $true,
                     ValueFromPipeline = $false,
                     ValueFromPipelineByPropertyName = $false,
                     HelpMessage = ‘Module Name.’
                     )]
         [string] $ModuleName,
         [Parameter( Mandatory = $true,
                     ValueFromPipeline = $false,
                     ValueFromPipelineByPropertyName = $false,
                     HelpMessage = ‘File to deploy.’
                     )]
         [string[]] $Files,
         [switch] $Replace
        )  # End the parameter block

  begin
  {
    # Validate the PS folder exists
    Add-WindowsPowerShellFolder

    # Set the path to the users modules folder
    $psUserModulePath = "C:\Users\$([Environment]::UserName)\Documents\WindowsPowerShell\Modules"

    # Add a new folder for the module name being installed
    Add-ModuleFolder -ModuleName $ModuleName

    # Set the path to the users module folder including the module to create
    $psModulePath = "$($psUserModulePath)\$($ModuleName)"

    # If the user passed the -Replace switch delete all files from
    # the target folder
    if ($Replace -eq $true)
    {
      Remove-Item "$psModulePath\*.*" -Force -Recurse
    }

  }
 
  process
  {

    foreach($file in $files)
    {
      # Copy our module to the users module folder (force will overwrite if there)
      Copy-Item $file `
                $psModulePath `
                -Force
    }
  }
 
}

Using it is straight forward. First, place the above code into a PS1, then execute it to load the functions into memory. You could also put it in your profile if it is something you do often.

In this example I’ve developed a module called ZipCodeLookup. This example installs it for me into my modules folder.

Install-MyModule ‘ZipCodeLookup’ ‘C:\PS\MyCode\ZipCodeLookup.*’ –Replace

Now you have a simple function you can call to deploy your modules, making your development life a little easier. It can also come in useful when sending a module to a coworker or setting up some common scripts on a different machine. It takes care of making sure the folders are in place as well as copying in your module.