0

I have a script which will compare two very similar directories to see which has newer, updated files. The two paths have the same files but the path names are locations that are slightly different. The two folders have about the same amount of files, maybe two or three less than the other.

$path1 = "E:\docs\training\files"
$path2 = "D:\docs\training - Copy\files"
$outdatedFiles = @()

foreach($file in $Folder1)
{
    foreach($file2 in $Folder2)
    {
        if($file2.BaseName -match $file.BaseName)
        {
            if($file.LastWriteTime -gt $file2.LastWriteTime)
            {
                $Result = "" | Select OutDatedFile,LastWriteTime
                $Result.OutDatedFile = $file2.FullName
                $Result.LastWriteTime = $file2.LastWriteTime
                $outdatedFiles += $Result
            }
        }
    }
}

In the $outdatedFiles array, I get files that are not newer than their counterpart in the other directory. I think it might be due to my comparison in the if statement, I tried -match, -contains, and -ccontains to see if any of these would give me what I wanted. Neither worked. It might be that the foreach doesn't work due to the slightly different amount of files in each folder. Any suggestions?

EDIT

I tried building a hash but this did not find all the updated files:

$outdatedFiles = @()
foreach($file in $Folder1)
{
    foreach($file2 in $Folder2)
    {
        if($file2.Name -like $file.Name)
        {
            #compare hash here
            $Hash2 = Get-FileHash $file2.FullName -Algorithm SHA256
            $Hash1 = Get-FileHash $file.FullName -Algorithm SHA256
            if($Hash2.Hash -ne $Hash1.Hash)
            {
                $Result = "" | Select OutDatedFile,LastWriteTime
                $Result.OutDatedFile = $file2.FullName
                $Result.LastWriteTime = $file2.LastWriteTime
                $outdatedFiles += $Result
            }
        }
    }
}

EDIT

This was my solution

$Differences1 = @()
foreach($file in $Folder1)
{
    foreach($file2 in $Folder2)
    {
        <#Trim path then compare#>
        #File1
        $file1part1 = ($file.FullName).Split("\")[-2]
        $file1part2 = ($file.FullName).Split("\")[-1]
        $newPath1 = $file1part1 + "\" + $file1part2
        #File2
        $file2part1 = ($file2.FullName).Split("\")[-2]
        $file2part2 = ($file2.FullName).Split("\")[-1]
        $newPath2 = $file2part1 + "\" + $file2part2
        if($newPath1 -like $newPath2)
        {
            $Differences1 += Compare-Object (gci $file2.FullName) -DifferenceObject (gci $file.FullName) -Property LastWriteTime -PassThru | Select Name,FullName,LastWriteTime | Sort-Object -Property Name
        }
    }
}
if($Differences1 -ne $null)
{
    $Differences1 | Out-File $textFile -Append
}
else
{
    "No folders have different modified dates" | Out-File $textFile -Append
}
techguy1029
  • 743
  • 10
  • 29
  • 1
    walk each directory and build a hash/crc/SHA256 for each file. then compare hashes and the ones that are extra/different from each side are the files of interest. see `Get-FileHash` – Kory Gill Sep 17 '19 at 21:15
  • 1
    `$outdatedFiles = Compare-Object (gci $path1) -DifferenceObject (gci $path2) -Property LastWriteTime -PassThru | Select * | Out-GridView` might be a simpler solution. – Rich Moss Sep 17 '19 at 23:50
  • 1
    Use `.Name` instead of `.BaseName` if there are similarly named files with different extensions, like program.exe and program.config. – Rich Moss Sep 17 '19 at 23:58
  • 1
    [Here's another SO question](https://stackoverflow.com/questions/6526441/comparing-folders-and-content-with-powershell) that's not exactly a duplicate, but might help if you go down the `Compare-Object` route. – Rich Moss Sep 18 '19 at 00:13
  • @RichMoss I figured out my original problem. I have multiple files that have similar paths and the exact same file name and extension. The script is comparing these instead of their counterpart in the other directory. How do I avoid this? – techguy1029 Sep 18 '19 at 18:00
  • When you say 'similar paths' do you mean they are both in some subfolder of the source/`$path1` folder (shouldn't be compared), or they are in the same relative path but across source/`$path1` and destination/`$path2` folders (should be compared). You can use `Resolve-Path -Relative ` to normalize the paths between the source and destination folders. However it would be complicated to do so, because you have to change the current directory to get a relative path. – Rich Moss Sep 18 '19 at 20:53
  • @RichMoss Yes, it was complicated but I think I got it – techguy1029 Sep 18 '19 at 23:00

1 Answers1

1

In the end, the solution was more complex than I wanted, or maybe I just made it that way. The problem was I had multiple files with the same name and similar paths, as in the subfolder was named the same. I had to trim the path to be able to get a better comparison:

$Differences1 = @()
foreach($file in $Folder1)
{
    foreach($file2 in $Folder2)
    {
        <#Trim path then compare#>
        #File1
        $file1part1 = ($file.FullName).Split("\")[-2]
        $file1part2 = ($file.FullName).Split("\")[-1]
        $newPath1 = $file1part1 + "\" + $file1part2
        #File2
        $file2part1 = ($file2.FullName).Split("\")[-2]
        $file2part2 = ($file2.FullName).Split("\")[-1]
        $newPath2 = $file2part1 + "\" + $file2part2
        if($newPath1 -like $newPath2)
        {
            $Differences1 += Compare-Object (gci $file2.FullName) -DifferenceObject (gci $file.FullName) -Property LastWriteTime -PassThru | Select Name,FullName,LastWriteTime | Sort-Object -Property Name
        }
    }
}
if($Differences1 -ne $null)
{
    $Differences1 | Out-File $textFile -Append
}
else
{
    "No folders have different modified dates" | Out-File $textFile -Append
}
techguy1029
  • 743
  • 10
  • 29