DEV Community

Rich
Rich

Posted on • Originally published at yer.ac on

3

Recursive folder comparison with PowerShell

The Issue

This post definitely isn’t “new” or revolutionary, but I was quite surprised to find the Compare-object helper in PS, and I’m bound to forget in the future…

As part of some recent roadmap work, we moved over to a new installer technology for some of our tooling. This came with some minor headaches such as validating we have harvested all the correct files. The first iteration of this was a manual check which obviously is prone is human error – aside from being mind numbing!

I didn’t really want to use a third party tool. WinMergecan perform fantastic comparisons, but I wanted something quick and custom. Ideally also not spending longer than 10 minutes creating any code!

The first iteration was to do a recursive loop, pull out all the file names (Note: not the path) into 2 separate text files. The only “nicety” was I wrapped directory names in square brackets to give it some organisation.

The downside of this is that it only really worked for my sample folder with a few items. In production with thousands of files and nested folders this was plain chaos. Also I had to compare these files in a third party tool like WinMerge anyway – taking away the point of doing this!

The final version of my script aimed to only show the difference (avoid noise), ideally show which direction the change occurred using Compare-Object in PowerShell.

The Result

  • Do a recursive loop through the directory structure
  • Output Folder names as [Folder], and recursively dive-down. This is a bit dirty as I didn’t want the full path (harder to compare) but wanted to differentiate when I dug down. YMMV.
  • Output File names, excluding some files I didn’t care about (Like .tmp & .XML files)
  • Do this for folder A and folder B, storing the result to a variable
  • Using Compare-Object on these variables and outputting the result.


function GetFiles($path, [string[]]$excludedFiles)
{
    foreach ($item in Get-ChildItem $path)
    {
        if ($excludedFiles | Where {$item -like $_}) { continue }

        if( (Get-Item $item.FullName) -is [System.IO.DirectoryInfo]){
         $('['+$item.Name+']')
        }else{
          $($item.Name)
        }
        if (Test-Path $item.FullName -PathType Container)
        {
            GetFiles $item.FullName $excludedFiles
        }
    }
} 
$env1 = GetFiles -path "C:\folderA\" -excludedFiles "*.xml",".tmp"
$env2 = GetFiles -path "C:\folderB\" -excludedFiles "*.xml",".tmp"

Compare-Object -DifferenceObject $env1 -ReferenceObject $env2


Enter fullscreen mode Exit fullscreen mode

Which provides output like:

This could definitely be optimized and cleaned up for sure, and YMMV massively.

Overall, a few minutes in PowerShell and I managed to save substantial time – and that was my only real goal!

The post Recursive folder comparison with PowerShell appeared first on yer.ac | Adventures of a developer, and other things..

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay