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

Powershell 比较多个文件夹的文件差异,powershell,powershell-2.0,Powershell,Powershell 2.0,我开始比较2个文件夹结构,以查找日期和大小不匹配的文件,但要求已更改为4个文件夹,我被卡住了 下面是我想做的: 我们将数百个文件夹\文件上传到4个不同的服务器。这些文件必须全部匹配。有时文件无法正确复制。所以我需要一个脚本来读取所有四个目录并比较所有文件,以确保它们按大小和日期匹配。 输出应该只是一个简单的列表,显示不匹配的文件 $path1 = "\\path\folder $path2 = "\\path\folder1 $dif = Compare-Object -

我开始比较2个文件夹结构,以查找日期和大小不匹配的文件,但要求已更改为4个文件夹,我被卡住了

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

    $path1 = "\\path\folder
    $path2 = "\\path\folder1
    $dif = Compare-Object -ReferenceObject $path1 -DifferenceObject $path2 -Property FullName, Length, LastWriteTime
    $dif | ft -AutoSize 
有什么想法吗? 谢谢

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

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

我会用一种基于散列的方法来解决这个问题,并且可能会在某个地方使用一个数据库表来帮助您自己。顺便说一句,有
gethash
commandlet可以帮助您实现这一点

基本方法

遍历每台服务器所需的文件夹树(出于性能原因,而不是通过网络共享,您希望在所涉及的服务器上执行此操作),并对找到的每个文件生成哈希。将散列、完整路径和服务器名存储在某个位置,最好是可以从所有四台服务器访问的数据库表——这将使处理变得更加容易

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

  • 查找哈希实例少于4个的任何哈希
  • 查找具有不同哈希值的任何文件路径(可能必须处理路径字符串才能使其到达每个服务器的相同相对根目录)(尽管上面的1.1可能会介绍这一点)
  • 当然,所有这些都可以在PS内部完成

    为什么这样做可能会有帮助

  • 您不必运行四向比较对象。散列作为比较点
  • 生成哈希的Powershell代码是在每台服务器上运行的一个相同函数
  • 它的规模。您可以轻松地对100个文件夹执行此操作
  • 您最终得到了一些易于操作和“分布式”的东西,即可以访问所涉及的服务器——数据库表
  • 下跌趋势

    PSCX获取哈希不是很快。这可以通过PS fire轻松解决

    如何不使用数据库表
    1.在处理散列文件夹时,将散列、文件路径和服务器名称写入每台服务器上的文件,并在完成后将这些文件带回。
    2.将文件处理到一个哈希表中,该哈希表对哈希代码进行键控,并对每个哈希代码进行计数。 3.您可以拥有一个并行哈希表(与2同时构建。当您传递结果文件时),该表将每个哈希代码上的键指向该哈希代码的路径/服务器阵列。
    4.在哈希表1中查找计数小于4的哈希代码。使用并行哈希表2查找计数小于4的哈希代码,以找出文件路径和服务器是什么。

    尝试以下操作:

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

    比较1.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" }
    
    Param(
    [parameter(Mandatory=$true)][alias(“p”)][string]$PrimaryPath,
    [参数(必需=$true)][别名(“c”)][字符串[]]$ComparePath
    ) 
    #获取具有relativepath属性的文件列表
    函数Get FilesWithRelativePath($Path){
    获取ChildItem$Path-Recurse |?{!$\u.PSIsContainer}|%{
    添加成员-InputObject$\成员类型NoteProperty-Name RelativePath-Value$\ InputObject.FullName.Substring($Path.Length)
    $_
    }
    }
    #如果路径存在并且是文件夹
    if(测试路径$PrimaryPath-路径类型容器){
    #获取主文件列表
    $Masterfiles=Get FilesWithRelativePath(解析路径$PrimaryPath).Path
    #比较文件夹
    foreach($ComparePath中的文件夹){
    if(测试路径$文件夹-路径类型容器){
    #获取文件列表并向文件添加相对路径属性
    $ResolvedFolder=(解析路径$Folder)。路径
    $Files=使用相对路径$ResolvedFolder获取文件
    #将文件路径与丢失的文件或旧文件进行比较并输出
    
    比较对象-引用对象$Masterfiles-差异对象$Files-属性RelativePath、Length、LastWriteTime |?{$\ SideIndicator-eq“您是否有一个“主”位置?例如您从中复制文件的位置,并且所有内容都是正确的?这将简化它,如果需要,我可以使用一个作为主位置,以便“在服务器上运行”"我可以使用invoke命令吗?或者这对性能没有帮助吗?您可以使用invoke。只是不要在另一台计算机上的文件夹网络共享上运行它。这会导致性能下降。只要所有代码都在远程计算机上运行,并且不向e起爆机(除该作业已完成外)。如果将其作为四个独立的远程作业启动,则它们可以并行运行。当它们全部完成后,您的脚本知道您可以检查数据库表中的结果。是的,这可能会起作用。我正在尝试从命令行传递文件夹,但似乎只能看到一个文件夹。以下是我的代码:
    Param([parameter(Mandatory=$true)][alias(“p”)]$PrimaryPath,[parameter(Mandatory=$true)][alias(“c”)]$ComparePath)$master=Get ChildItem$PrimaryPath-Recurse$paths=@($ComparePath)$paths |%{Compare Object-ReferenceObject$master-DifferenceObject(Get ChildItem$|-Recurse)-属性名称、长度、LastWriteTime-PassThru |其中{$\ SideIndicator-eq“=>”}从命令行?cmd或powershell中选择全名}
    ?是否意味着它只检查一个文件夹?如果是,如何调用脚本