PowerShell Problem Solver: Cleaning Up Old DSC Resources


Desired State Configuration (DSC) is a fascinating technology that can dramatically alter an IT pro’s job description. This is a big topic, but today I want to focus on one small piece, and one that I have found a little annoying. One of the elements that makes DSC work is a DSC Resource. A resource is a configuration element that is defined generally through PowerShell script and packaged as a PowerShell module. In the beginning we only had a small number of resources and everything was essentially version 1.0. Now there are many, many resources, often in varying stages of maturity as reflected by version number.



Sponsored Content

Passwords Haven’t Disappeared Yet

123456. Qwerty. Iloveyou. No, these are not exercises for people who are brand new to typing. Shockingly, they are among the most common passwords that end users choose in 2021. Research has found that the average business user must manually type out, or copy/paste, the credentials to 154 websites per month. We repeatedly got one question that surprised us: “Why would I ever trust a third party with control of my network?

You can find and install many of these resources from the PowerShell Gallery.

Finding DSC Resources

The challenge is you can download new versions and end up with multiple versions locally. For example, look at a single DSC Resource I have installed.

Multiple versions installed

When I go to use the resource in a DSC Configuration I am presented with a related error condition.

Configuration Error

If I hover over the red squiggle, I’ll get a message about multiple resource versions detected. The solution is simple enough. I merely have to explicitly state which resource module to import.

Configuration WebConfig {


Import-DscResource -ModuleName PSDesiredStateConfiguration,

Node $Computername {
  xWebSite My {
    Name = 'MyWebSite'
    Ensure = 'Present'
    PhysicalPath = 'C:\Web\MyWebSite'
    EnabledProtocols = 'http'
  #additional configuration


This is probably for the best because I can guarantee exactly which version to use. This is also a good practice if I’m creating configurations I plan to share. But if I always keep my resources up-to-date with the latest version, I can save myself a little time. So what I need is a tool to prune my installed DSC Resources, always keeping the most current version and uninstalling everything else. There is one big caveat here: some DSC Resources take dependencies on other resources and often a specific version. PowerShell doesn’t like it if you try to uninstall a dependent resource. In addition, your configurations might need to be updated to work with newer versions.  But if you are good, or merely want to see how you can find and remove older DSC resources, then you can use this PowerShell function.
#requires -version 5.0

Function Remove-DSCResourceModule {

#Remove all but newest DSC Resource module


[Parameter(Position=0,HelpMessage="Enter the module name of a DSC resource.")]

if ($Name) {
    Write-Verbose "Getting module $Name"
    $clean = Get-Module -Name $Name -ListAvailable | Group Name | where Count -gt 1
else {
    Write-Verbose "Getting all DSC resource modules"
    $clean = Get-DSCResource | 
    Select @{Name="Name";Expression={$_.ModuleName}},Version -Unique | 
    Group Name | 
    where Count -gt 1

if ($clean.Group) {
    Write-Verbose "Processing module group"

    foreach ($mod in $clean) {
        Write-Host "Cleaning up $($mod.name)" -ForegroundColor Cyan
        #sort modules from Group by version, skipping the first one which should
        #be the newest. Uninstall the rest
        $mod.group | Sort Version -Descending | Select -Skip 1 |
        Foreach { 
            There appears to be an issue in passing -WhatIf to
            Uninstall-Module so I'll insert my own code
          if ($PSCmdlet.ShouldProcess($_.name)) {           
                Write-Host "Removing version $($_.version)" -ForegroundColor Cyan    
                Uninstall-Module -Name $_.Name -RequiredVersion $_.Version              
          } #should process

    } #foreach

else {
    Write-Warning "No modules found to remove"


The function gets all DSC Resources and groups them by module name and then selects those with more than result. It then sorts each group by version number and uninstalls all but the most recent. I can cleanup a single resource:

Clean up a single resource

Or all of them.

Clean up all

I’ll go ahead and re-run the command without -WhatIf to clean up. I have flagged the removal process with a high impact so that you will be prompted to remove. And if a dependency is detected the module won’t be uninstalled.

Removing older resources

If, for some reason, I find I need a specific resource version, I can download it again from the PowerShell Gallery, so there shouldn’t be that much risk in periodically cleaning up. Still, this is significant process so please, please, test and and plan accordingly.

Related Topics:


Don't have a login but want to join the conversation? Sign up for a Petri Account

Comments (0)

Leave a Reply