Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

PowerShell Modules in a Cross-Version World

Posted on January 14, 2021January 14, 2021

The other day I was helping a friend sort out some module-related questions. While helping him, I realized his questions and problems were not unique. Now that many of us are running Windows PowerShell 7 side-by-side, what are the implications when it comes to using PowerShell modules? What are the potential "gotchas"? And what can you do to reduce the likelihood of problems?

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

PowerShellGet

Both Windows PowerShell and PowerShell rely on module commands like Find-Module and Install-Module. However, if you need to support modules cross-version, you might need to satisfy a critical requirement. By the way, use Windows PowerShell to run all of these commands unless otherwise directed.

Open Windows PowerShell and run

Get-Module powershellget -ListAvailable

If the only version you see is 1.0.0.1, you need to update the module. The PowerShellGet module is where you get the module commands and in a cross-version world, you need a later version of the module.

However, you can't simply run

Update-Module PowerShellGet

If you do, you'll get an error. The 1.0.0.1 version is a system module that came with your version of Windows 10. It was not installed in the traditional sense. But no problem. You can still install it.

Install-Module PowerShellGet -Force -Repository PSGallery

I'm being very concise in the command to install the Microsoft version. Let's verify.

Remove-Module PowerShellGet -ErrorAction Ignore
Import-Module PowerShellGet
Get-Module PowerShellGet

You should see at least version 2.2.5. If so you are ready to continue. By the way, now that you've used Install-Module, if there is a later version update, you can use Update-Module to install it. Don't worry about the original system version. PowerShell will automatically use the latest version of the module by default.

PSModulePath

The next part of the puzzle is an environmental variable called %PSModulePath%. This variable contains all of the locations that PowerShell and Windows PowerShell looks for modules. This is what makes module autoloading possible. This is where it gets interesting.

Here's my variable on a clean Windows 10 installation.

Windows PowerShell module locations

I split the path on the ";" delimiter to make it easier to read. There are 3 default locations. Once for the current user, one for all users and one for system modules. For the most part, we'll ignore anything in the system path. When you install a new module it will go in either the user and all users path. More on that in a bit.

Here is the same thing in PowerShell 7.1.

Another way to think of the system path is that is under $PSHome. Look closely. PowerShell 7 also knows about the Windows PowerShell system and all users locations! This means that PowerShell can "see" modules installed by Windows PowerShell. However, Windows PowerShell cannot "see" anything installed by PowerShell.

Install-Module

Now that this hopefully clear, let's install some modules. In PowerShell, I'll install a module that I know only works in PowerShell 7.x.

install-module Bluebirdps -Scope AllUsers -force

Notice the -Scope parameter. By default, installed modules are per user. But in this case I wanted to install the module for All Users. This means the account used to install the module needs admin rights to C:\Program Files. This is why the default is to the user's location -- to avoid the need of admin credentials. While I'm at it, I'll install another module in PowerShell 7.

Install-Module PSReleaseTools -force

In Windows PowerShell, I'll install a module for all users and one using the default scope.

Install-Module PSScriptTools -Scope AllUsers -force
Install-Module WTToolbox -force

Get-InstalledModule

The next question should be, "How can I see what modules are available?". One command you can use, and one that I had not been aware of, is Get-InstalledModule. Here's what I get in PowerShell.

Installed PowerShell modules

You can see by the location that one module is for the user and one is for all users. Notice there are no modules from Windows PowerShell.

Here's the same thing from the Windows PowerShell side.

Nothing from PowerShell 7 shows up. But there is one important item I want to point out. Earlier I installed the WTToolBox module without specifying a scope. The default is the user scope yet look at the location. Here's what happened. I was running Windows PowerShell as Administrator, i.e. in an elevated session. In this context, the "user" is the same as "all users". In some ways that is a good thing because any Windows PowerShell modules installed for all users can be used in PowerShell 7.x, assuming compatibility.

Key TakeAway #1: Get-InstalledModule only shows modules installed per PowerShell version.

Key TakeAway #2: Installing a module as an elevated user always installs the module for all users.

Get-Module

So how can you "see" what modules are available? Use Get-Module. By default, the module only shows the currently loaded modules. The key parameter you need to remember is -ListAvailable.

listing an available module

Get-Module searches the PSModulePath locations which is why this works in PowerShell 7. To "see" everything run:

Get-Module -listavailable

Here's a little code snippet to inventory available modules.

$p = $env:PSModulePath -split ";"
 $m = Get-Module -ListAvailable
 foreach ($loc in $p) {
     [pscustomobject]@{
         Location = $loc
         Modules = ($m | where {$_.path -match $loc.replace("\","\\") } ).count
     }   
 }

This is a composite of results from both versions of PowerShell.

module inventory

Key TakeAway #3: If you need to use a module in both Windows PowerShell and PowerShell 7.x, install it for all users in Windows PowerShell.

Summary

I hope this walk-through cleared up any mystery or confusion. Before you go let me mention a few things. First, just because PowerShell can "see" a Windows PowerShell module, there is no guarantee it will work. Don't let this deter you. The vast majority of Windows PowerShell modules work just fine in PowerShell. Those that don't most likely fail due to a .NET dependency that isn't supported in .NET Core, which is what PowerShell is running under.

Second, your PSModulePath variable might be different. Depending on the applications or programs you install, you might have additional locations. On my primary desktop, I have SQL Server Express installed so my variable includes C:\Program Files (x86)\Microsoft SQL Server\150\Tools\PowerShell\Modules\.

Technically, you could modify the environmental variable or adjust locations with a profile script. You might do this if you want to include a custom location. But I would advise against updating the variable so that Windows PowerShell can "see" PowerShell module locations. I'm working under the assumption that if a module is installed in PowerShell it requires PowerShell. For example, I installed the BluebirdPS module in PowerShell. If I modified things so that I could import it into Windows PowerShell, it will most likely fail. If you need modules to work cross-version, install them in Windows PowerShell for all users.

I encourage you to update PowerShellGet and then take a few minutes reading help and examples for the module commands.


Behind the PowerShell Pipeline

Share this:

  • Share on X (Opens in new window) X
  • Share on Facebook (Opens in new window) Facebook
  • Share on Mastodon (Opens in new window) Mastodon
  • Share on LinkedIn (Opens in new window) LinkedIn
  • Share on Reddit (Opens in new window) Reddit
  • Print (Opens in new window) Print
  • Email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

1 thought on “PowerShell Modules in a Cross-Version World”

  1. Mateusz says:
    January 17, 2021 at 8:56 am

    Great explained. I learned this topic when I wrote PSModuleManager. Your post showed me I understand it well. Thanks!

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2026 The Lonely Administrator | Powered by SuperbThemes!
%d