Reputation: 694
I am working on a PowerShell script that requires a specific PowerShell module to be installed on the machine where the script is run. This module provides additional functionality that is crucial for the script to work correctly.
I would like to make my script portable, so that I can put my script and the module in a folder and copy it to another machine and run it directly without the need for manual installations. Is this possible? I have tried searching for a solution online, but I couldn't find anything that specifically addresses my problem.
Upvotes: 5
Views: 2556
Reputation: 27766
Copy the module directory (using the same directory structure as the installed module) into a sub directory where your script is located.
For example, the directory structure could look like this for the Pester module:
When the module is available in PSGallery you can alternatively save the module without installing it first. For example to save the Pester module from PSGallery in a directory structure like above:
md Modules
Save-Module -Name Pester -Path Modules
You basically have two ways to load the module.
Import-Module
, specifying the full path of the module directory, without the version sub directory.$env:PSModulePath
variable. This enables simple import using just the module name and module auto-loading (as if the module were actually installed). This might be preferred if your script is split into multiple files. In this case you only have to modify the root script and any scripts loaded by the root script will automatically use the portable module(s).Example for using Import-Module
:
# Import module from a sub directory relative to the current script
Import-Module $PSScriptRoot\Modules\Pester
# Now using functions from portable Pester module
Describe 'Portable Module Test' {
It 'Should have loaded portable module' {
$portableModuleFilePath = (Get-Item $PSScriptRoot\Modules\Pester\*\Pester.psm1).FullName
(Get-Module Pester).Path | Should -Be $portableModuleFilePath
}
}
Example for using $env:PSModulePath
:
# Insert portable module directory at the front of PSModulePath so our portable
# version of the module will be preferred over any installed version.
# This is only in script scope, the system environment variable won't be modified!
$env:PSModulePath = "$PSScriptRoot\modules;$env:PSModulePath"
# Now using functions from portable Pester module, which PowerShell loads automatically.
Describe 'Portable Module Test' {
It 'Should have loaded portable module' {
$portableModuleFilePath = (Get-Item $PSScriptRoot\Modules\Pester\*\Pester.psm1).FullName
(Get-Module Pester).Path | Should -Be $portableModuleFilePath
}
}
Upvotes: 8