The Problem

One of the benefits of dbatools being a community supported project, is frequent updates. One of the downsides is frequent updates. By default, after you install or update the dbatools module, the new version is there right next to the old version. After a while you have quite a collection of old versions sitting in your module directory.

 
     
        
Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\dbatools\'

    Directory:  C:\Program Files\WindowsPowerShell\Modules\dbatools

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d-----        10/6/2020  10:40 AM        1   1.0.123
d-----       11/17/2020  11:11 AM        1   1.0.131
d-----        12/8/2020   7:53 AM        1   1.0.135
d-----        5/27/2021   9:11 AM        1   1.0.153
d-----         6/9/2021   8:59 AM        1   1.0.155
d-----        6/11/2021   9:37 AM        1   1.0.156

 
    
As you can see we have started to get cluttered. PowerShell will do it’s best to find the newest version installed when it imports it for use. So to both have a clean module directory and to make sure we are importing the version we want used, we need to get rid of all the old versions.

Where the problem is stored.

To see the directories that PowerShell checks for modules run the following:

 
     
        
#Windows path separator = ;
$env:PSModulePath.split(';')
C:\Users\JeffH\Documents\WindowsPowerShell\Modules
C:\Program Files\WindowsPowerShell\Modules
C:\windows\system32\WindowsPowerShell\v1.0\Modules
C:\Program Files\Microsoft SQL Server\130\Tools\PowerShell\Modules\
C:\Program Files (x86)\Microsoft SQL Server\130\Tools\PowerShell\Modules\
C:\Program Files\Microsoft Monitoring Agent\Agent\PowerShell\
#Linux path separator = :
$env:PSModulePath.split(':')
/home/jeff/.local/share/powershell/Modules
/usr/local/share/powershell/Modules
/snap/powershell/160/opt/powershell/Modules
#MacOS path separator = :
$env:PSModulePath.split(':')
/Users/jeffhill/.local/share/powershell/Modules
/usr/local/share/powershell/Modules
/usr/local/microsoft/powershell/7/Modules
 
    

The Solution.

Get the latest version.

If we run Get-InstalledModule we can see the latest version that PowerShell finds on the system.

 
     
        

Get-InstalledModule -Name dbatools
Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.0.156    dbatools                            PSGallery            The community module that enables SQL Server Pro...
 
    

Get all installed versions.

Now we run it again with the -AllVersions switch.

 
     
        
Get-InstalledModule -Name dbatools -AllVersions

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.0.123    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.131    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.135    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.153    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.155    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.156    dbatools                            PSGallery            The community module that enables SQL Server Pro...
 
    

Save to variables and test.

Next we’ll assign them to variables.

 
     
        
$Latest = Get-InstalledModule -Name dbatools 
$All = Get-InstalledModule -Name dbatools -AllVersions
 
    
Then we test to make sure we get the results we want.

Give me all the versions installed where the version number is not equal to the latest version.

 
     
        
$All | Where-Object {$_.Version -ne $Latest.Version}

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.0.123    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.131    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.135    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.153    dbatools                            PSGallery            The community module that enables SQL Server Pro...
1.0.155    dbatools                            PSGallery            The community module that enables SQL Server Pro...
 
    
We see here that we got back everything except the latest version, version 1.0.156.

Putting it all together we pipe the results of our previous command to UnInstall-Module

UnInstall.

 
     
        
$All | Where-Object {$_.Version -ne $Latest.Version} | UnInstall-Module
 
    
That’s it. Simple once you’ve seen it. If one of the versions is loaded in a session somewhere, you’ll get an error about it being in use.

Update (Jul 6, 2021)

**UPDATE** (Jul 6, 2021) I discovered that dbatools comes with a script to aid in getting rid of old modules. It’s called cleanup.ps1 and it’s located in (Get-InstalledModule -Name dbatools).InstalledLocation. The explanation and code are here. The big difference I saw was that it will try to kill all PowerShell sessions to ensure no modules are in use. It also will do a Find-Module so see if you’re running the lastest and greatest.

Just goes to show there and lots of different ways to do things and you may not need to reinvent the wheel.