The PowerShell module path is the list of folders in $env:PSModulePath that PowerShell searches when it looks for a module. To see each folder on its own line, run this:
$env:PSModulePath -split ';'
Here’s the problem I see most often. Someone on the help desk copies a module into a folder, types one of its commands, and PowerShell says the command isn’t recognized. The folder just isn’t on the module path.
In this tutorial, I’ll show you how the PowerShell module path works, which folders PowerShell 7 and Windows PowerShell 5.1 use, how to add your own folder, and two traps: OneDrive and starting 5.1 from 7.
I tested this on a Windows 11 PC in PowerShell 7.6 and Windows PowerShell 5.1. The output shows my user name as alice.
What is PSModulePath and how does module autoloading use it?
$env:PSModulePath is an environment variable that holds a list of folders separated by semicolons. PowerShell searches each folder, and the subfolders under it, for module files (.psd1 or .psm1).
That list drives module autoloading. The first time you run a command from an installed module, PowerShell imports the module for you, but only when it sits in one of these folders. You can ask where a command came from:
$cmd = Get-Command -Name Compress-Archive
"Module: $($cmd.Module.Name) $($cmd.Module.Version)"
"Found in: $($cmd.Module.ModuleBase)"
Output:
Module: Microsoft.PowerShell.Archive 1.2.6
Found in: C:\program files\windowsapps\microsoft.powershell_7.6.7.0_x64__8wekyb3d8bbwe\Modules\Microsoft.PowerShell.Archive
That’s PowerShell 7. Windows PowerShell 5.1 found an older copy of the same module in System32:
Module: Microsoft.PowerShell.Archive 1.0.1.0
Found in: C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive
A module outside these folders still works, but you have to load it by path. That’s normal while you create a PowerShell module and test it before you install it.
Default PowerShell module path folders in PowerShell 7 and 5.1
PowerShell builds $env:PSModulePath every time it starts, and each version builds it differently. Here’s the PowerShell 7 list from my PC:
$env:PSModulePath -split ';'
Output:
C:\Users\alice\OneDrive\Documents\PowerShell\Modules
C:\Program Files\PowerShell\Modules
c:\program files\windowsapps\microsoft.powershell_7.6.7.0_x64__8wekyb3d8bbwe\Modules
C:\Program Files\WindowsPowerShell\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
Windows PowerShell 5.1 printed only three folders:
C:\Users\alice\OneDrive\Documents\WindowsPowerShell\Modules
C:\Program Files\WindowsPowerShell\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules
PowerShell 7 puts its own three folders first and then adds the two Windows PowerShell folders, so it can load many 5.1 modules too. Windows PowerShell 5.1 never sees the PowerShell 7 folders.
| Scope | PowerShell 7 | Windows PowerShell 5.1 |
|---|---|---|
| Current user | $HOME\Documents\PowerShell\Modules | $HOME\Documents\WindowsPowerShell\Modules |
| All users | $env:ProgramFiles\PowerShell\Modules | $env:ProgramFiles\WindowsPowerShell\Modules |
| Built-in ($PSHOME) | $PSHOME\Modules | C:\Windows\System32\WindowsPowerShell\v1.0\Modules |
My PowerShell 7 came from the Microsoft Store, so $PSHOME points into a WindowsApps folder. The MSI installer uses C:\Program Files\PowerShell\7 instead.
The folders don’t all have to exist. This loop runs Test-Path in PowerShell on each entry:
$env:PSModulePath -split ';' | ForEach-Object {
[pscustomobject]@{ Exists = Test-Path -Path $_; Folder = $_ }
} | Format-Table -AutoSize
Output:
Exists Folder
------ ------
True C:\Users\alice\OneDrive\Documents\PowerShell\Modules
False C:\Program Files\PowerShell\Modules
True c:\program files\windowsapps\microsoft.powershell_7.6.7.0_x64__8wekyb3d8bbwe\