cksgen-ps/cksgen-ps.ps1

118 lines
4.9 KiB
PowerShell
Raw Normal View History

2020-10-30 10:47:08 +01:00
# 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
}