Search code examples
powershellenvironment-variablespowershell-5.0

Changing the PSModulePath in Powershell 5


I've used the following to permanently change the PSModulePath:

[Environment]::SetEnvironmentVariable('PSModulePath', "ABC", "Machine")

This works fine when I call the below (it returns "ABC"):

[Environment]::GetEnvironmentVariable('PSModulePath', "Machine")

But in any Powershell Session when I run:

$env:PSModulePath

I get:

C:\Users\myname\Documents\WindowsPowerShell\Modules;ABC

Where is this path coming from, is it PS5 magic? I've checked the "User" target and this is blank. It's as if something is pre-pending the PSModulePath with this default path?


Solution

  • The environment drive Env: contains the environment variables specific to the current user's session (source). It is equivalent to the Process scope. So

    [Environment]::GetEnvironmentVariable('PSModulePath', 'Process')
    

    should be equivalent to

    $env:PSModulePath
    

    The Process scope contains the environment variables of a particular process. It gets constructed like this (source):

    This list of variables is inherited from the parent process and is constructed from the variables in the Machine and User scopes.

    As you checked both, the Machine and the User scope, and did not find the path, it has to come from the parent process, which is PowerShell itself. And this is indeed the case as can be read here:

    The CurrentUser module path is prefixed only if User scope $env:PSModulePath doesn't exist. Otherwise, the User scope $env:PSModulePath is used as defined.

    As you confirmed in your question,

    [Environment]::GetEnvironmentVariable('PSModulePath', 'User')
    

    is empty and thus $env:PSModulePath has been prefixed by the CurrentUser module path, which is $HOME\Documents\PowerShell\Modules or $HOME\Documents\WindowsPowerShell\Modules depending on your Windows version.

    You can read more about environment variables in my answer here.