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

Maximize Value from Microsoft Defender

In this ebook, you’ll learn why Red Canary’s platform and expertise bring you the highest possible value from your Microsoft Defender for Endpoint investment, deployment, or migration.

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

External Sharing and Guest User Access in Microsoft 365 and Teams

This eBook will dive into policy considerations you need to make when creating and managing guest user access to your Teams network, as well as the different layers of guest access and the common challenges that accompany a more complicated Microsoft 365 infrastructure.

You will learn:

  • Who should be allowed to be invited as a guest?
  • What type of guests should be able to access files in SharePoint and OneDrive?
  • How should guests be offboarded?
  • How should you determine who has access to sensitive information in your environment?

Sponsored by:

Live Webinar: Active Directory Security: What Needs Immediate Priority!Live on Tuesday, October 12th at 1 PM ET

Attacks on Active Directory are at an all-time high. Companies that are not taking heed are being punished, both monetarily and with loss of production.

In this webinar, you will learn:

  • How to prioritize vulnerability management
  • What attackers are leveraging to breach organizations
  • Where Active Directory security needs immediate attention
  • Overall strategy to secure your environment and keep it secured

Sponsored by: