比较多个文件夹的文件差异

时间:2013-01-21 21:55:59

标签: powershell powershell-v2.0

我开始比较2个文件夹结构来查找按日期和大小不匹配的文件,但是要求已经更改为4个文件夹而且卡住了。

所以这就是我想要做的: 我们将数百个文件夹\文件上传到4个不同的服务器。文件必须全部匹配。有时文件无法正确复制。所以我需要一个脚本来读取所有四个目录并比较所有文件,以确保它们按大小和日期匹配。 输出应该只是一个简单的列表,显示不匹配的文件。

有什么想法吗? 感谢。

我可以做两个文件夹,但四个文件丢失了。此外,这个输出令人困惑。不确定如何只列出那些不匹配的。

    $path1 = "\\path\folder
    $path2 = "\\path\folder1
    $dif = Compare-Object -ReferenceObject $path1 -DifferenceObject $path2 -Property FullName, Length, LastWriteTime
    $dif | ft -AutoSize 

2 个答案:

答案 0 :(得分:0)

我会用基于哈希的方法来解决它,并且可能使用数据库表来帮助自己。顺便说一下,PSCXGet-Hash命令行开关,它可以帮助你做到这一点。

基本方法

遍历每个服务器所需的文件夹树(您希望 所涉及的服务器出于性能原因,而不是通过网络共享!)并在您找到的每个文件上生成哈希值。将散列和完整路径和服务器名称存储在某处,最好是可从所有四个服务器访问的数据库表 - 它将使处理更加容易。

然后,如果您使用过数据库表,请编写一些简单的查询:

  1. 找到散列少于4个实例的任何散列。
  2. 找到任何文件路径(您可能必须处理路径字符串以使其达到每个服务器的相同根目录),其中存在不同的哈希值(尽管上面可能会介绍这一点)。
  3. 当然,所有这一切都可以在PS内完成。

    为什么这种做事方式可能会有所帮助

    1. 您不必运行四向比较对象。哈希就是你的比较点。
    2. 用于生成哈希的Powershell代码是一个在每个服​​务器上运行的相同功能。
    3. 它缩放。您可以轻松地为100个文件夹执行此操作。
    4. 你最终得到的东西很容易被操纵和“分发”,即。可访问所涉及的服务器 - 数据库表。
    5. <强>下行

      PSCX Get-Hash不是很快。这可以通过PS fire some faster hash generating command, such as this one, md5sums轻松解决。

      如何不使用数据库表
      1.在处理哈希文件夹时,将哈希,文件路径,severnames写入每个服务器上的文件,并在完成后将这些文件带回来。
      2.将文件处理为哈希表,该哈希表在哈希码上键入并计算每个哈希码。 3.您可以使用并行哈希表(在通过结果文件传递的同时构建)将每个哈希代码上的键作为该哈希码的路径/服务器数组。
      4.在哈希表1中查找小于4的哈希码。使用并行哈希表2查找计数小于4的哈希码,以找出文件路径和服务器的内容是

答案 1 :(得分:0)

试试这个:

请记住,PrimaryPath必须是主要位置(内容正确)。此外,与您编写路径的方式一致(如果包含\或不包括)。防爆。对所有路径使用c:\folders\folder1\c:\folders\folder1

Compare.ps1

Param( 
    [parameter(Mandatory=$true)] [alias("p")] [string]$PrimaryPath,
    [parameter(Mandatory=$true)] [alias("c")] [string[]]$ComparePath
    ) 

#Get filelist with relativepath property
function Get-FilesWithRelativePath ($Path) {
    Get-ChildItem $Path -Recurse | ? { !$_.PSIsContainer } | % { 
        Add-Member -InputObject $_ -MemberType NoteProperty -Name RelativePath -Value $_.FullName.Substring($Path.Length)
        $_
    }
}

#If path exists and is folder
if (Test-Path $PrimaryPath -PathType Container) {
    #Get master fileslist
    $Masterfiles = Get-FilesWithRelativePath (Resolve-Path $PrimaryPath).Path

    #Compare folders
    foreach ($Folder in $ComparePath) {
        if (Test-Path $Folder -PathType Container) {
            #Getting filelist and adding relative-path property to files
            $ResolvedFolder = (Resolve-Path $Folder).Path
            $Files = Get-FilesWithRelativePath $ResolvedFolder

            #Compare and output filepath to missing or old file
            Compare-Object -ReferenceObject $Masterfiles -DifferenceObject $Files -Property RelativePath, Length, LastWriteTime | ? { $_.SideIndicator -eq "<=" } | Select @{n="FilePath";e={Join-Path $ResolvedFolder $_.RelativePath}}
        } else { Write-Error "$Folder is not a valid foldername. Foldertype: Compare" }
    }

} else { Write-Error "$PrimaryPath is not a valid foldername. Foldertype: Master" }