Creating a PowerShell script that can install itself as module

Powershell advanced functions are a lightweight, yet pretty powerful way to extend the set of commands available in a Powershell sessions. Advanced functions look and feel almost exactly like proper cmdlets, but they are written in Powershell and therefore quick to develop.

By default, advanced functions are ephemeral though: If you run a script containing an advanced function, that function is going to be available for the rest of the Powershell session — after that, it is gone. To make an advanced function available permanently — like a cmdlet — you have to wrap it in a Powershell module, and install that module.

A module consists of at least two files:

  • a script module, which is a Powershell script containing the advanced functions. Unlike a regular Powershell script, it has to use the file suffix .psm1.
  • a module manifest (*.psd1) that defines some metadata for the module.

If you have a NuGet repository, you can publish your module there to make it easily installable across your environment. But what if you do not have a NuGet repository you could publish the module to, but still want to make it easily installable for other users?

Installing without Nuget

Installing a module entails taking the .psm1 and .psd1 file and copying them to a folder underneath [ProgramFiles]\WindowsPowerShell\Modules\ (to become visible globally) or [MyDocuments]\WindowsPowerShell\Modules (for the current user). That process is easy enough, but already adds a good amount of friction:

  • Comprising multiple files, the module is not as easy to download or copy as a plain script file anymore and you might have to package the files in a Zip archive.
  • Asking users to copy the files to the right folder is rarely an option, so you might have to create an extra installer script or package to take care of this.

As it turns out, there is a way to have your cake and eat it too — to take advantage of advanced functions and modules while still being able to distribute everything as a single script file. The idea is to create a Powershell script that, when run, installs itself permanently as a PowerShell module.

See powershell-install-as-module/Install-Template.ps1 on GitHub for an example of such a script.

The script can be run in three modes. If you dot-source it without arguments, the script will make the advanced functions available to the current session:

PS> . .\Install-Template.ps1

Name Value
---- -----
ModuleVersion 1.0
FunctionsToExport {Invoke-TemplateTest}
RootModule JP.TemplateModule.psm1

Advanced functions added to current session.
Use -Install to add functions permanenently.

PS> Invoke-TemplateTest
This is a test function

If you run .\Install-Template.ps1 -Install CurrentUser, the script generates a .psm1 and .psd1 file off of itself and saves them to [MyDocuments]\WindowsPowerShell\Modules\JP.TemplateModule. This causes the advanced functions to permanently become available for the current user:

PS> .\Install-Template.ps1 -Install CurrentUser

Name Value
---- -----
ModuleVersion 1.0
FunctionsToExport {Invoke-TemplateTest}
RootModule JP.TemplateModule.psm1

Advanced functions added to current session.
Advanced functions installed to C:\Users\jpassing\Documents\WindowsPowerShell\Modules\

In a new session:

PS&gt Invoke-TemplateTest
This is a test function

Finally, if you run .\Install-Template.ps1 -Install LocalMachine, the script generates a .psm1 and .psd1 file off of itself and saves them to [ProgramFiles]\WindowsPowerShell\Modules\JP.TemplateModule, causing the advanced functions to become visible to everyone.

Advertisements

Categories




About me

Johannes Passing lives in Berlin, Germany and works as a Solutions Architect at Google Cloud.

While mostly focusing on Cloud-related stuff these days, Johannes still enjoys the occasional dose of Win32, COM, and NT kernel mode development.

He also is the author of cfix, a C/C++ unit testing framework for Win32 and NT kernel mode, Visual Assert, a Visual Studio Unit Testing-AddIn, and NTrace, a dynamic function boundary tracing toolkit for Windows NT/x86 kernel/user mode code.

Contact Johannes: jpassing (at) hotmail com

LinkedIn Profile
Xing Profile
Github Profile
Advertisements

%d bloggers like this: