问题
Have a comparison script that compares based on MD5 hash. Noticed that it's doing odd things.
$Source= "D:\Folder1"
$Destination = "D:\folder2"
get-childitem $Source -Recurse | foreach {
#Calculate hash using Algorithm MD5 reference http://www.tomsitpro.com/articles/powershell-file-hash-check,2-880.html
Write-Host "Copying $($_.fullname) to $Destination" -ForegroundColor Yellow
$OriginalHash = Get-FileHash -Path $_.FullName -Algorithm MD5
#Now copy what's different
$replacedfile = $_ | Copy-Item -Destination $Destination -Force -PassThru
#Check the hash sum of the file copied
$copyHash = Get-FileHash -Path $replacedfile.FullName -Algorithm MD5
#compare them up
if ($OriginalHash.hash -ne $copyHash.hash) {
Write-Warning "$($_.Fullname) and $($replacedfile.fullname) Files don't match!"
}
else {
Write-Host "$($_.Fullname) and $($replacedfile.fullname) Files Match" -ForegroundColor Green
}
} #Win!
The script works fine, until it finds a difference in a sub folder. It then for some reason i can't seem to find, it copies the different item to BOTH the top level and the sub level.....I am being really dumb and I can't see the issue, need a second pair of eyes.
Example
File Test.Txt is in Source\SubFolder
Script runs and puts Test.Txt in Destination\Subfolder AND Destination.....
Any ideas?
回答1:
The line $replacedfile = $_ |
is a fault, here $_ contains only the name without the subdir, and is copied to $Destination.
Replace the line:
$replacedfile = $_ | Copy-Item -Destination $Destination -Force -PassThru
with:
$replacedfile = $_.Fullname -replace [RegEx]::escape($Source),$Destination
This replaces the differing base part leaving the curent source sub dir intact.
The [RegEx]::escape($Source) is necessary because the source string contains
backslashes which would be interpreted as an escape char by the replace function.
EDIT Complete script to avoid ambiguities:
$Source= "D:\Folder1"
$Destination = "D:\folder2"
get-childitem $Source -Recurse | foreach {
#Calculate hash using Algorithm MD5 reference http://www.tomsitpro.com/articles/powershell-file-hash-check,2-880.html
$SrcFile = $_.FullName
$SrcHash = Get-FileHash -Path $SrcFile -Algorithm MD5
$DestFile = $_.Fullname -replace [RegEx]::escape($Source),$Destination
Write-Host "Copying $SrcFile to $DestFile" -ForegroundColor Yellow
if (Test-Path $DestFile) {
#Check the hash sum of the file copied
$DestHash = Get-FileHash -Path $DestFile -Algorithm MD5
#compare them up
if ($SrcHash.hash -ne $DestHash.hash) {
Write-Warning "$SrcFile and $DestFile Files don't match!"
Copy-Item $SrcFile -Destination $DestFile -Force
} else {
Write-Host "$SrcFile and $DestFile Files Match" -ForegroundColor Green
}
} else {
Copy-Item $SrcFile -Destination $DestFile -Force
}
}
来源:https://stackoverflow.com/questions/41876703/compare-directories-and-sub-directories-and-replace-files-based-on-md5-hash