将目录与子文件夹进行比较

时间:2015-02-20 13:55:27

标签: powershell compare directory

我在这方面遇到了困难,但我正在尝试对两台服务器进行比较,并将它们从一台服务器与另一台服务器进行比较。甚至在子文件夹中。到目前为止,我已经得到它来比较文件夹名称和文件,但无法让它进入文件夹并比较内容。这是我尝试过的一些事情。

$A = Get-ChildItem -Recurse -path $Path
$B = Get-ChildItem -Recurse -path $PAth1
Compare-Object -ReferenceObject $A -DifferenceObject $B -PassThru

这是我开始使用它并且效果最好,但仍然没有进入子文件夹。我还尝试使用带有数组的foreach语句将内容存储在数组中并比较数组,但这似乎根本不起作用。

$FileDirectoryA = "Path"
$FileDirectoryC = "path"
$A = foreach($folderA in Get-ChildItem $fileDirectoryA)
{
    $FolderA
}
$B = foreach($FileA in Get-ChildItem $ArrayA)
{
    $FileA
}
$C = foreach($folderC in Get-ChildItem $fileDirectoryC)
{
    $FolderC
}
$D = foreach($FileC in Get-ChildItem $ArrayC)
{
    $FileC
}

Compare-Object $B $D

当我尝试做一个

Compare-Object $Path $Path2 

所有文件夹上的错误都说拒绝权限对我来说没有多大意义。

谢谢, 安德鲁

4 个答案:

答案 0 :(得分:1)

如果指定要比较的属性,它应该有效:

$a = ls c:\temp\ -rec
$b = icm -computername $servername -scriptblock{ls c:\temp\ -rec}
compare $a $b -Property fullname

更可靠的方法可能是使用robocopy robocopy.exe \\serverA\Folder1 \\serverB\Folder2 /e /l /log:c:\temp\dif.txt

答案 1 :(得分:1)

我认为这个powershell脚本https://github.com/oflisback/dirdiff解决了您的问题,它会扫描两个目录并报告差异:

PS C:\> dirdiff.ps1 C:\dir1 C:\dir2
One identical file:
        .\identical.txt
One file only present in C:\dir1:
        .\newdir1.txt
2 files only present in C:\dir2:
        .\newdir2.txt
        .\newdir\newfilesdir2.txt
One file present in both directories and has different content:
        .\modified.bin

该脚本基于此gist,因此归功于cchamberlein

答案 2 :(得分:0)

我认为这应该给你一个合理的比较。如果您愿意,可以在返回值上使用正则表达式来重建原始文件路径。

$Dir1="C:\Test"
$Dir2="C:\Test2"
$A=(Get-ChildItem $Dir1 -Recurse).VersionInfo.Filename -replace [regex]::Escape($Dir1),""
$B=(Get-ChildItem $Dir2 -Recurse).VersionInfo.Filename -replace [regex]::Escape($Dir2),""
Compare-Object $A $B

这在像...这样的输出中重新出现。

InputObject                                                        SideIndicator                                                     
-----------                                                        -------------                                                     
\New folder\temp.txt                                               =>                                                                
\temp.txt                                                          <=                                                                
\New folder\New folder\temp.txt                                    <=           

<强>更新

我认为应该做你想要的一切。您需要更改$Dir1$Dir2值。它可能过于复杂,但似乎确实有效。

$Dir1="C:\Test"
$Dir2="C:\Test2"
$Items1=Get-ChildItem $Dir1 -Recurse
$Items2=Get-ChildItem $Dir2 -Recurse
$A=$Items1.VersionInfo.Filename -replace [regex]::Escape($Dir1),""
$B=$Items2.VersionInfo.Filename -replace [regex]::Escape($Dir2),""
$Exist_Diff=Compare-Object $A $B

$Exist_Diff | %{
    $Current_Item=$_.InputObject
    if($_.SideIdicator -eq "<="){
        Write-Host "No file equivilent to $Dir1$Current_Item found in $Dir2"
        }else{
        Write-Host "No file equivilent to $Dir2$Current_Item found in $Dir1"
        }
    }

$Items1 | %{
    if ($Exist_Diff.InputObject -notcontains ($_.VersionInfo.Filename -replace [regex]::Escape($Dir1),""))
        {
        $MatchingFile=[string]$_.VersionInfo.Filename -replace [regex]::Escape($Dir1),$Dir2      
        try{if(Test-Path $MatchingFile)
            {
            if((Get-Item $MatchingFile).length -gt $_.Length)
                {
                Write-host $_.fullname "is larger than" $MatchingFile
                }
            }}catch{}
        }
    }
$Items2 | %{
    if ($Exist_Diff.InputObject -notcontains ($_.VersionInfo.Filename -replace [regex]::Escape($Dir1),""))
        {
        $MatchingFile=[string]$_.VersionInfo.Filename -replace [regex]::Escape($Dir2),$Dir1      
        try{if(Test-Path $MatchingFile)
            {
            if((Get-Item $MatchingFile).length -gt $_.Length)
                {
                Write-host $_.fullname  "is larger than" $MatchingFile
                }
            }}catch{}
        }
    }

答案 3 :(得分:0)

Get-ChildItem $Source -Recurse | ForEach-Object{

   $Dest = Join-Path $Destination $_.FullName.Substring($Source.Length)

   $bool = Test-Path $Dest

   if(!$bool){
       #Write of some thing here to indicate difference
   }

}