cksgen-ps/cksgen-ps.ps1

118 lines
4.9 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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
}