Check for PowerShell module updates

Last year, I wrote a blog post about updating your modules to the latest version, including removing the older versions here. This blog post will show you how to check for updated modules.

Why is updating your modules important?

Things change a lot in IT, and your PowerShell modules are regularly updated with new features and options or just to kill a few bugs. 🙂 In the Microsoft 365/Entra/Graph modules, things change significantly in how you connect or what cmdlets can do.

How does the script work?

It gathers a list of all the installed PowerShell modules on your system (Installed from a repository using Install-Module) and checks if a newer version is available. It retrieves the information of 63 updates at a time until all modules are checked for more recent versions. (Limit of PSGallery searching using Find-Module). If so, it will add it to a list and display it at the end of the script.

You can use the -NameFilter parameter to only search for specific modules. (It will show a warning if you filter for something that doesn’t exist.) For example, the command below will only search for all Graph modules:

PS C:\Scripts> .\Find-ModuleUpdates.ps1 -NameFilter *Graph*

Note: This could take a while if you have many modules installed!

Running the script

In the example below, I run the Find-ModuleUpdates.ps1 from c:\scripts, and it will show the available updates afterward while showing a progress bar while checking. If there are no updates, it will also mention that.

PS C:\Scripts> .\Find-ModuleUpdates.ps1

It will show the output on the screen, which will look like this:

In this example, there were 7 updates. After running the Update-Modules script (Which updates everything to the latest version and uninstalls previous versions), the output will look like this:

The script

Below are the contents of the script. Save it to your system and run it to check for updated versions of your modules.

# Parameter for filtering modules for specific pattern, e.g. *Graph*
param (
    [Parameter(Mandatory = $false)][string]$NameFilter = '*'
)

#Retrieve all installed modules
Write-Host ("Retrieving installed PowerShell modules") -ForegroundColor Green
[array]$InstalledModules = Get-InstalledModule -Name $NameFilter -ErrorAction SilentlyContinue

#Retrieve current versions of modules (63 at a time because of PSGallery limit) if $InstalledModules is greater than 0
if ($InstalledModules.Count -eq 1) {
    $onlineversions = $null
    Write-Host ("Checking online versions for installed module {0}" -f $name) -ForegroundColor Green
    $currentversions = Find-Module -Name $CurrentModules.name
    $onlineversions = $onlineversions + $currentversions
}

if ($InstalledModules.Count -gt 1) {
    $startnumber = 0
    $endnumber = 62
    $onlineversions = $null
    while ($InstalledModules.Count -gt $onlineversions.Count) {
        Write-Host ("Checking online versions for installed modules [{0}..{1}/{2}]" -f $startnumber, $endnumber, $InstalledModules.Count) -ForegroundColor Green
        $currentversions = Find-Module -Name $InstalledModules.name[$startnumber..$endnumber]
        $startnumber = $startnumber + 63
        $endnumber = $endnumber + 63
        $onlineversions = $onlineversions + $currentversions
    }
}
if (-not $onlineversions) {
    Write-Warning ("No modules were found to check for updates, please check your NameFilter. Exiting...")
    return
}

#Loop through all modules and check for newer versions and add those to $total
$number = 1
Write-Host ("Checking for updated versions") -ForegroundColor Green
$total = foreach ($module in $InstalledModules) {
    Write-Progress ("[{0}/{1} Checking module {2}" -f $number, $InstalledModules.count, $module.name)
    try {
        $PsgalleryModule = $onlineversions | Where-Object name -eq $module.Name
        if ([version]$module.version -lt [version]$PsgalleryModule.version) {
            [PSCustomObject]@{
                Repository          = $module.Repository
                'Module name'       = $module.Name
                'Installed version' = $module.Version
                'Latest version'    = $PsgalleryModule.version
                'Published on'      = $PsgalleryModule.PublishedDate
            }
        }
    }
    catch {
        Write-Warning ("Could not find module {0}" -f $module.Name)
    }
    $number++
}

#Output $total to display updates for installed modules if any
if ($total.Count -gt 0) {
    Write-Host ("Found {0} updated modules" -f $total.Count) -ForegroundColor Green
    $total | Format-Table -AutoSize
}
else {
    Write-Host ("No updated modules were found")
}

Download the script(s) from GitHub here.

8 thoughts on “Check for PowerShell module updates

  1. Get-InstalledModule does work quite well in various versions of PowerShell and the various platforms for PowerShell 7. However, Get-InstalledModule will only return modules that you installed and exclude native modules. As a result, if you have not installed/updated modules, such as Pester, PowerShellGet, or PSReadLine, this script will not list them as having an update when a newer version exists. All of these mentioned have newer versions than the version natively.

    I’m still looking for a good method that works in PowerShell version 5.1 and 7.x, including the multiple platforms 7.x supports, that will identify native modules that have newer versions. I don’t think it is a simple problem to solve.

    • That is the issue indeed, I could check for errors during updating to determine if the module was not installed by install-module. If so, use install-module on it but then it still reports that it was not installed by install-module but the newer 2.3.3 (I tried it on PSReadline) and that didn’t work…

      I think we have to wait on the new PSResourceGet, I hope that will fix it

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.