Use Import-Csv
to read old CSV and new CSV into separate variables, then call Compare-Object
to compare them. Make sure to compare on both Hash
and Path
to detect moved files.
$oldHashes = Import-Csv oldhashes.csv
$newHashes = Import-Csv newhashes.csv
Compare-Object $oldHashes $newHashes -Property Hash, Path | Export-Csv difference.csv
As a performance optimization, you could store the new hashes in a variable, while you are generating them. This way you wouldn't have to read the new hashes from the file back again.
The output file 'difference.csv' will be empty if CSVs are equal.
Otherwise the output file contains all differences. The column SideIndicator
indicates whether a given combination of Hash and Path exists only in the oldhashes.csv
(SideIndicator <=
) or only in the newhashes.csv
(SideIndicator =>
).
Further improvements
The above code outputs duplicate paths, in case a file has been modified. Example output in table format for readability:
Path Hash SideIndicator
---- ---- -------------
C:estar.txt 73FEFFA4B7F6BB68E44CF984C85F6E88 <=
C:estaz.txt D41D8CD98F00B204E9800998ECF8427E =>
C:estfoo.txt 2AF65102DB00B80835E1578278064AD1 =>
C:estfoo.txt 37B51D194A7513E45B56F6524F2D51F2 <=
The file "foo.txt" is listed twice because it exists in old and new state but has modified content. To remove duplicate paths, we can use Group-Object
to group on the Path
property:
# Compare and store differences in variable $diff
$diff = Compare-Object $oldHashes $newHashes -Property Path, Hash | Sort-Object
# Group on path to create only a single output item for each modified file
$groupedDiff = $diff | Group-Object Path | ForEach-Object {
# The pscustomobject is the output of the ForEach-Object script block
[pscustomobject] @{
Path = $_.Name
# If group has only one element, the file exists either in old or in new state.
# Otherwise we have a modified file, which will be indicated by
# special SideIndicator value '<>'.
SideIndicator = if( $_.Count -eq 1 ) { $_.Group.SideIndicator } else { '<>' }
}
}
$groupedDiff | Export-Csv difference.csv
Contents of $groupedDiff
in table format:
Path SideIndicator
---- -------------
C:estar.txt <=
C:estaz.txt =>
C:estfoo.txt <>
Now we get only a single line for "foo.txt", where <>
clearly shows that the file has been modified. I didn't output the hash values because I don't see much use for them in this output format. If you need them, add a property to the [pscustomobject]
and assign $_.Group.Hash
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…