代码之家  ›  专栏  ›  技术社区  ›  Jeremiah Williams

目录之间的PowerShell ForEach哈希比较

  •  1
  • Jeremiah Williams  · 技术社区  · 6 年前

    我正在编写一个脚本来比较两个目录。我希望脚本在输出中显示两个主要内容——哪些文件存在于一个目录中,而不是另一个目录中,以及哪些文件出现在两个目录中,但存在差异。匹配的文件不需要显示。

    我之前得到了一些关于如何实现这一点的建议,但由于我对PS还是相当陌生,所以在执行它时遇到了困难。我想做的是:

    1. 我有路径#1。对于该路径中的每个文件,我想测试它们是否存在于路径#2上。
    2. 如果文件存在于两个路径中,请对它们进行哈希比较。如果存在差异,请将文件添加到列表A中。
    3. 如果文件出现在路径1中,而不是路径2中,请将其放在列表B中。
    4. 这一点并不重要,但是否也可以找到路径2中存在但路径1中不存在的文件?出于工作目的,这可能无关紧要,但以防万一还是不错的。
    5. 获取输出并对其进行格式化,以便它可以显示如下内容:“以下文件存在于路径1中,而不是路径2中”,以及“以下文件存在于两个路径中,但存在差异”

    基本上,我不只是希望文件的信息转储成为输出,人们最终不得不对其进行拼图。正如我所说,我认为我收到的关于如何做的建议将是好的,我只是很难让它发挥作用。

    以下是我目前掌握的代码:

    $Source = @(Get-ChildItem -Recurse -Path \\SERVER\D$\PSTest)
    foreach ($file in $Source){
    If ($Target = Test-Path @(Get-ChildItem -Recurse -Path \\SERVER\D$\PSTest)) 
    { 
        $HashResult = (Compare-Object -ReferenceObject $file -DifferenceObject 
    $Target -Property hash -PassThru).Path
        } 
    else { 
        $Missing += $file
        }
    }
    
    
    Write-Host 'These files have differences.' -ForegroundColor Green
    $HashResult
    Write-Host 'These files are missing from the target path.' -ForegroundColor 
    Green
    $Missing
    

    当我运行它时,我不会得到任何结果(除了文本输出)。这件事我哪里做错了?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Forty3    6 年前

    对文件名及其在源/目标文件夹不同深度的唯一性进行了一些假设:

    $SourceDir = "C:\\temptest";
    $DestDir = "D:\\temptest";
    $SourceFiles = @(Get-ChildItem -Recurse -Path $SourceDir);
    $DestFiles = @(Get-ChildItem -Recurse -Path $DestDir);
    
    $SourceFileNames = $SourceFiles | % { $_.Name };
    $DestFileNames = $DestFiles | % { $_.Name };
    
    $MissingFromDestination = @();
    $MissingFromSource = @();
    $DifferentFiles = @();
    
    foreach($f in $SourceFiles) {
        if (!$DestFileNames.Contains($f.Name)) {
            $MissingFromDestination += $f;
        } else {
            $t = $DestFiles | Where { $_.Name -eq $f.Name };
            if ((Get-FileHash $f.FullName).hash -ne (Get-FileHash $t.FullName).hash) {
                $DifferentFiles += $f;
            }
        }
    }
    
    foreach($f in $DestFiles) {
        if (!$SourceFileNames.Contains($f.Name)) {
            $MissingFromSource += $f;
        }
    }
    
    "
    Missing from Destination: "
    $MissingFromDestination | % { $_.FullName };
    
    "
    Missing from Source: "
    $MissingFromSource | % { $_.FullName };
    
    "
    Source is Different: "
    $DifferentFiles | % { $_.FullName };
    

    这种方法有点幼稚,因为它实际上只检查文件名,而忽略子文件夹树结构。但是,希望它能给你足够的跳跃点。