Recursive folder comparison with PowerShell
Tags: devops, powershell
Published: 2019-06-21 14:14:20

---
title: Recursive folder comparison with PowerShell
published: true
tags: DevOps,PowerShell
canonical_url: http://yer.ac/blog/2019/03/25/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.** [WinMerge](http://winmerge.org/?lang=en)can 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
```

Which provides output like:

![](https://i2.wp.com/yer.ac/blog/wp-content/uploads/2019/03/image-11.png?w=840)

**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](http://yer.ac/blog/2019/03/25/recursive-folder-comparison-with-powershell/) appeared first on [yer.ac | Adventures of a developer, and other things.](http://yer.ac/blog).