118 lines
4.9 KiB
PowerShell
118 lines
4.9 KiB
PowerShell
# cksgen-ps – Generate and compare MD5 checksum lists with PowerShell
|
||
#
|
||
# Copyright (c) 2020 Helmut Kaczmarek <code@helmutkaczmarek.de>
|
||
#
|
||
# This program is free software: you can redistribute it and/or modify
|
||
# it under the terms of the GNU General Public License as published by
|
||
# the Free Software Foundation, either version 3 of the License, or
|
||
# (at your option) any later version.
|
||
#
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
# GNU General Public License for more details.
|
||
#
|
||
# You should have received a copy of the GNU General Public License
|
||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
||
# Settings
|
||
$dataFolder = "D:\Photos"
|
||
$scriptFolder = "D:\Photos\Checksums"
|
||
$checksumFolderPath = Join-Path -Path $scriptFolder -ChildPath "Lists"
|
||
$logFolderPath = Join-Path -Path $scriptFolder -ChildPath "Logs"
|
||
$allowedExtensions = "*.jpg", "*.jpeg", "*.dng", "*.cr2"
|
||
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
|
||
|
||
# Create folder for checksum files (will be subfolder of $scriptFolder)
|
||
if (-not (Test-Path -Path $checksumFolderPath -PathType Container)) {
|
||
New-Item -Path $checksumFolderPath -ItemType Directory
|
||
}
|
||
|
||
# Create folder for log files (will be subfolder of $scriptFolder)
|
||
if (-not (Test-Path -Path $logFolderPath -PathType Container)) {
|
||
New-Item -Path $logFolderPath -ItemType Directory
|
||
}
|
||
|
||
# Create the checksum file
|
||
$checksumList = Join-Path -Path $checksumFolderPath -ChildPath ("${timestamp}_checksum.txt")
|
||
|
||
Add-Content -Path $checksumList -Value "MD5 checksums on: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
||
Get-ChildItem -Recurse -File -Path $dataFolder -Include $allowedExtensions | ForEach-Object {
|
||
$file = $_.FullName
|
||
$md5 = Get-FileHash -Algorithm MD5 -Path $file
|
||
$logEntry = "$($md5.Hash) $file"
|
||
Add-Content -Path $checksumList -Value $logEntry
|
||
Write-Host "Processing $file"
|
||
}
|
||
|
||
# Keep the 10 most recent checksum files
|
||
$allChecksumFiles = Get-ChildItem -Path $checksumFolderPath -Filter "*_checksum.txt" | Sort-Object -Property LastWriteTime -Descending
|
||
$oldChecksumFiles = $allChecksumFiles | Select-Object -Skip 10
|
||
|
||
foreach ($oldFile in $oldChecksumFiles) {
|
||
Remove-Item -Path $oldFile.FullName -Force
|
||
}
|
||
|
||
# Determine the last two checksum files
|
||
$allChecksumFiles = Get-ChildItem -Path $checksumFolderPath -Filter "*_checksum.txt" | Sort-Object -Property LastWriteTime -Descending
|
||
|
||
if ($allChecksumFiles.Count -lt 2) {
|
||
Write-Host "INFO: Checksums could not be compared because there is currently only one checksum file."
|
||
$logFile = Join-Path -Path $logFolderPath -ChildPath ("${timestamp}_log.txt")
|
||
Add-Content -Path $logFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): INFO: Checksums could not be compared because there is currently only one checksum file."
|
||
Write-Host "The following log file was created:"
|
||
Write-Host $logFile
|
||
}
|
||
else {
|
||
$latestChecksumFile = $allChecksumFiles[0]
|
||
$previousChecksumFile = $allChecksumFiles[1]
|
||
|
||
# Read the checksums and filenames from the last two checksum files
|
||
$latestChecksums = Get-Content -Path $latestChecksumFile.FullName
|
||
$previousChecksums = Get-Content -Path $previousChecksumFile.FullName
|
||
|
||
# Compare the checksums and create the log file
|
||
$differentFiles = @()
|
||
|
||
for ($i = 0; $i -lt $latestChecksums.Count; $i++) {
|
||
$latestChecksum = $latestChecksums[$i] -split ' ', 2
|
||
$previousChecksum = $previousChecksums[$i] -split ' ', 2
|
||
|
||
$latestHash = $latestChecksum[0]
|
||
$latestFile = $latestChecksum[1]
|
||
|
||
$previousHash = $previousChecksum[0]
|
||
$previousFile = $previousChecksum[1]
|
||
|
||
if ($latestFile -eq $previousFile -and $latestHash -ne $previousHash) {
|
||
$differentFiles += $latestFile
|
||
}
|
||
}
|
||
|
||
# Create the log file
|
||
$logFile = Join-Path -Path $logFolderPath -ChildPath ("${timestamp}_log.txt")
|
||
|
||
Add-Content -Path $logFile -Value "Directory monitoring on: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
||
if ($differentFiles.Count -gt 0) {
|
||
Write-Host "ATTENTION: Different MD5 checksums found!"
|
||
Add-Content -Path $logFile -Value "ATTENTION: The following files have different checksums:"
|
||
foreach ($file in $differentFiles) {
|
||
Add-Content -Path $logFile -Value " $file"
|
||
}
|
||
} else {
|
||
Write-Host "INFO: No different MD5 checksums found."
|
||
Add-Content -Path $logFile -Value "INFO: No different MD5 checksums found."
|
||
}
|
||
|
||
# Keep the 10 most recent log files
|
||
$allLogFiles = Get-ChildItem -Path $logFolderPath -Filter "*_log.txt" | Sort-Object -Property LastWriteTime -Descending
|
||
$oldLogFiles = $allLogFiles | Select-Object -Skip 10
|
||
|
||
foreach ($oldFile in $oldLogFiles) {
|
||
Remove-Item -Path $oldFile.FullName -Force
|
||
}
|
||
|
||
# Display a message with the path to the created log file in the command prompt
|
||
Write-Host "The following log file was created:"
|
||
Write-Host $logFile
|
||
} |