Monday Morning Module Maintenance Monoliners

Page content

Or: Andy Authors An Amazing Alliteration

Do enough work with PowerShell and you’ll build up a decent collection of modules installed from the gallery into either your computer or your user profile (or maybe both!). Here are two one-liners to help keep things up to date and tidy.

Note: I’m calling these one-liners but I’ve inserted line breaks for readability here. These do count as one-liners as each one is a single, unbroken PowerShell pipeline.

Keeping Modules Up to Date

Some modules update pretty frequently (I’m looking at you, dbatools) and it pays to keep on top of things so that you’ve got all the bug fixes and new features. But PowerShell doesn’t have (to my knowledge) a way to update all the modules that can be updated via Update-Module in one go. Luckily, we can write a one-liner to take care of it for us.

Here’s what it’s doing:

  1. Fetch all modules available to me
  2. Filter the list down to just modules installed from a PowerShellGet repository
  3. Get a list of unique module names
  4. Run Update-Module on each one

There’s a Catch

This approach makes a pretty strong assumption - it assumes that you’re working with administrative privileges. I can’t speak for you, but I don’t normally run an elevated PowerShell session. This means that attempting to update every module is going to result in a sea of red as my non-elevated session can’t install the updates.

I’ve also picked up a habit of installing modules to the CurrentUser scope unless they need to be made available to all users (most commonly in an automation scenario). In fact, depending upon which version of PowerShell you’re running, the default Install-Module scope might be CurrentUser anyway.

How do we handle this? By adding a condition in the Where-Object to restrict the modules being updated to only those installed in my user profile.

Cleaning Up

Keeping those modules up to date is great, but frequently-updated modules will leave a lot of old copies of themselves around over time. Sure, they don’t take up that much room, but it’s clutter.

Let’s clean up those old versions! Another one-liner to find and remove them.

  1. Fetch all modules available to me
  2. Filter the list down to just modules installed from a PowerShellGet repository and in the CurrentUser scope
  3. Get a list of unique module names
  4. For each module name found
    1. Get the list of all installed versions
    2. Sort by version number descending
    3. Drop the first item (the latest version)
    4. Remove the rest of the module versions

Put It in Your Profile

Of course, we don’t want to type these out all the time. For convenience, create a small function to wrap each and put them in your $PSProfile so they’re always at your fingertips.

A Concluding Wish

This process could be made a bit simpler if Get-Module -ListAvailable had a -Scope parameter to limit the search to the CurrentUser, just like Install-Module limits the scope for the installation. Maybe it’s worth filing a feature request in the issue tracker?