Installing PowerShell module persistently for all users

52.7k views Asked by At

I'm installing a PowerShell module via Octopus Deploy onto a number of different servers. For testing purposes, I went with the guidance of Microsoft's documentation for installing PowerShell Modules.

This worked fine, but as the documentation stated, my changes would be visible only for the current session. That is, if I were to do the following:

$modulePath = [Environment]::GetEnvironmentVariable("PSModulePath", [EnvironmentVariableTarget]::Machine)
# More practically, this would be some logic to install only if not present
$modulePath += ";C:\CustomModules"
[Environment]::SetEnvironmentVariable("PSModulePath", $modulePath, [EnvironmentVariableTarget]::Machine)

When running this installer automatically on tentacle servers, future PowerShell sessions do not appear to see the newly installed modules.

How can I install a PowerShell module in a profile agnostic way so that every PowerShell session started can see it?

3

There are 3 answers

2
Ansgar Wiechers On BEST ANSWER

PowerShell can only "see" modules installed in one of the directories listed in $env:PSModulePath. Otherwise you'll have to import the module with its full path.

To make a new module visible to all users you basically have two options:

  1. Install the module to the default system-wide module directory (C:\Windows\system32\WindowsPowerShell\v1.0\Modules).
  2. Modify the system environment so that PSModulePath variable already contains your custom module directory (e.g. via a group policy preference).

The latter will only become effective for PowerShell sessions started after the modification was made, though.

3
Knuckle-Dragger On

This profile applies to all users and all shells.

%windir%\system32\WindowsPowerShell\v1.0\profile.ps1
0
Peter Majeed On

After taking the steps you spelled out in your question (which I think is the general way to go), I found two ways to get the new module source recognized by Powershell:

  • Restart the machine. (Works every time.)
  • Reset the PSModulePath in each open session.

    $env:PSModulePath=[Environment]::GetEnvironmentVariable("PSModulePath", "Machine")
    

    I found this was necessary to run in both normal and elevated prompts to get this to work without restarting in each type of prompt. (See also the conversation @ Topic: PSModulePath.)