Search code examples
powershellpowershell-1.0

Comparing two sets of folders and files in Powershell v1.0


I want to generate a report which highlights only the differences between two directories, each on a different remote machine, complete with subdirectories and duplicate file Names.

I need two lists:

  • One which lists the files only in directory A or found on both servers with different LastWriteTime and newest is in directory A
  • One which lists the files only in directory B or found on both servers with different LastWriteTime and newest is in directory B

How do I filter out objects below where two objects from different servers have the same NoteProperty (ProjectDir) but different LastWriteTime?

Background

I have two servers which have a set of folders and files which are developed on in isolation and then occasionally synchronised once engineers are happy with their work. These engineers have been poor in reflecting their work onto the server they didn't work on. I want to generate a report which helps guide my team when choosing what to synchronise.

What I have tried

#Read in files only of project directories
$dirAItems = Get-ChildItem -Recurse -path ' D:\WORKING' | Where-Object {$_.GetType() | where-object -property "Name" -eq "FileInfo"}
$dirBItems = Get-ChildItem -Recurse -path ' E:\WORKING' | Where-Object {$_.GetType() | where-object -property "Name" -eq "FileInfo"}

#Compute relative paths
 $dirAItems| foreach-Object {
    $_ | Add-Member -MemberType NoteProperty -Name 'ProjectDir' -Value ($_.FullName.Replace("D:\WORKING","PROJECT"))
}
 $dirBItems| foreach-Object {
    $_ | Add-Member -MemberType NoteProperty -Name 'ProjectDir' -Value ($_.FullName.Replace("E:\WORKING","PROJECT"))
}

#Get the discrepancies and assign to Server1List or Server2List
Compare-Object -ReferenceObject $dirAItems -DifferenceObject $dirBItems -Property ProjectDir, LastWriteTime

$ServerAItemsOfInterest = Compare-Object -ReferenceObject $dirAItems -DifferenceObject $dirBItems -Property ProjectDir, LastWriteTime | Where-Object -Property SideIndicator -eq "<="

$ServerBItemsOfInterest = Compare-Object -ReferenceObject $dirAItems -DifferenceObject $dirBItems -Property ProjectDir, LastWriteTime | Where-Object -Property SideIndicator -eq "=>"

"Server A Items of Interest:"
$ServerAItemsOfInterest

"
Server B Items of Interest:"
$ServerAItemsOfInterest

Output

Server A Items of Intereset:

ProjectDir                                 LastWriteTime       SideIndicator
----------                                 -------------       -------------
PROJECT\File 2 - A is newest.txt           16/04/2021 14:55:24 <=           
PROJECT\File 3 - B is newest.txt           16/04/2021 12:04:06 <=           
PROJECT\File 4 - A only.txt                16/04/2021 12:06:47 <=           
PROJECT\SubDir1\File 1.2 - A is newest.txt 16/04/2021 15:35:26 <=           
PROJECT\SubDir1\File 1.3 - B is newest.txt 16/04/2021 12:04:06 <=           
PROJECT\SubDir1\File 1.4 - A only.txt      16/04/2021 12:06:47 <=           

Server B Items of Intereset:
PROJECT\File 2 - A is newest.txt           16/04/2021 12:04:06 =>           
PROJECT\File 3 - B is newest.txt           16/04/2021 12:06:31 =>           
PROJECT\SubDir1\File 1.2 - A is newest.txt 16/04/2021 12:06:17 =>           
PROJECT\SubDir1\File 1.3 - B is newest.txt 16/04/2021 14:55:13 => 

I need a way of filtering out objects in $ServerAItemsOfInterest where there is an object in $ServerBItemsOfInterest with the same ProjectDir and LastWriteTime is greater on Server B etc so the output is:

Server A Items of Interest:

ProjectDir                                 LastWriteTime       SideIndicator
----------                                 -------------       -------------
PROJECT\File 2 - A is newest.txt           16/04/2021 14:55:24 <=          
PROJECT\File 4 - A only.txt                16/04/2021 12:06:47 <=           
PROJECT\SubDir1\File 1.2 - A is newest.txt 16/04/2021 15:35:26 <=           
PROJECT\SubDir1\File 1.4 - A only.txt      16/04/2021 12:06:47 <=           

Server B Items of Interest:         
PROJECT\File 3 - B is newest.txt           16/04/2021 12:06:31 =>           
PROJECT\SubDir1\File 1.3 - B is newest.txt 16/04/2021 14:55:13 =>

I have tried filtering Compare-Object results but can't quite find the right conditions:

$ServerAItemsOfInterest = Compare-Object -ReferenceObject $dirAItems -DifferenceObject $dirBItems -Property ProjectDir, LastWriteTime | Where-Object `
{$_.SideIndicator -eq "<=" #-and `
    ($dirBItems.ProjectDir -notcontains $_.ProjectDir -or `
    ($dirBItems.ProjectDir -contains $_.ProjectDir # -and [COMPARE LAST WRITE TIMES SOMEHOW]  ))
}

Solution

  • Not sure about powershell v1, but maybe something like this could work?

    $dirA = Get-ChildItem -Path 'C:\Temp\test1'
    $dirB = Get-ChildItem -Path 'C:\Temp\test2'
    
    $listA = $dirA | ForEach-Object {
        if ($_.Name -notin $dirB.Name) { return $_ }
        $file = $_
        if ($_.LastWriteTime -gt ( $dirB.Where( { $file.Name -eq $_.Name }) ).LastWriteTime) { return $_ }
    }
    
    $listB = $dirB | ForEach-Object {
        if ($_.Name -notin $dirA.Name) { return $_ }
        $file = $_
        if ($_.LastWriteTime -gt ( $dirA.Where( { $file.Name -eq $_.Name }) ).LastWriteTime) { return $_ }
    }