diff --git a/Windows-Scripts/checksum.ps1 b/Windows-Scripts/checksum.ps1 index 39ff4b1..2a5bdca 100644 --- a/Windows-Scripts/checksum.ps1 +++ b/Windows-Scripts/checksum.ps1 @@ -93,19 +93,19 @@ PARAMETERS EXAMPLES 1. Compute SHA256 for a single file and auto-save as 'myfile.iso.sha256': - .\checksum.ps1 myfile.iso -o + .\checksum.ps1 myfile.iso -o 2. Compute SHA512 recursively and auto-save as 'checksums.sha512' in each folder: - .\checksum.ps1 * -r -o -a SHA512 + .\checksum.ps1 * -r -o -a SHA512 3. Compute SHA256 checksums and save to a specific custom file: - .\checksum.ps1 * -f my_hashes.txt + .\checksum.ps1 * -f my_hashes.txt 4. Verify checksums against a verification file: - .\checksum.ps1 -c checksums.sha256 + .\checksum.ps1 -c checksums.sha256 5. Compare file directly against an expected hash string: - .\checksum.ps1 myfile.bin -m 406653a68bd3538975656831f33f031b + .\checksum.ps1 myfile.bin -m 406653a68bd3538975656831f33f031b '@ }; @@ -127,39 +127,39 @@ EXAMPLES } process { - $helpInPath =$false; + $helpInPath = $false; if ($FilePath) { foreach ($p in ($FilePath)) { - if ($p -match '^(?i)[-/]{1,2}(h\vert{}help\vert{}\?)$') { - $helpInPath =$true; + if ($p -match '^(?i)[-/]{1,2}(h|help|\?)$') { + $helpInPath = $true; break; } }; }; - if ($Help.IsPresent -or$helpInPath) { + if ($Help.IsPresent -or $helpInPath) { Show-Help; return; }; if (-not [string]::IsNullOrWhiteSpace($Algorithm)) { - $Algorithm =$Algorithm.ToUpper(); + $Algorithm = $Algorithm.ToUpper(); }; # --- ITEM GATHERING (Generate & Match Modes) --- if ($PSCmdlet.ParameterSetName -in @('Generate', 'Match')) { - if (-not $FilePath -or$FilePath.Count -eq 0) { + if (-not $FilePath -or $FilePath.Count -eq 0) { Write-Error "checksum: Missing file path parameter. Use -Help for usage."; return; }; $allItems = @(); - $isWildcardGlobal =$false; + $isWildcardGlobal = $false; $skipExtensions = @('.md5', '.sha1', '.sha256', '.sha384', '.sha512'); foreach ($pathEntry in ($FilePath)) { $isWildcard = ($pathEntry -match '\*'); - if ($isWildcard) { $isWildcardGlobal =$true; }; + if ($isWildcard) { $isWildcardGlobal = $true; }; $resolvedItems = @(); if ($Recursive) { @@ -173,7 +173,7 @@ process { }; if (-not $resolvedItems) { - Write-Error "checksum: $($pathEntry)`: No such file or directory"; + Write-Error "checksum: $($pathEntry): No such file or directory"; continue; }; @@ -232,18 +232,18 @@ process { }; if (-not $checkFiles -or $checkFiles.Count -eq 0) { - Write-Error "checksum: $($Check)`: No such file or directory"; + Write-Error "checksum: $($Check): No such file or directory"; return; }; foreach ($cf in ($checkFiles)) { $lines = Get-Content -Path ($cf.FullName); - $baseDir =$cf.DirectoryName; + $baseDir = $cf.DirectoryName; - $fileAlgo =$Algorithm; + $fileAlgo = $Algorithm; if ([string]::IsNullOrWhiteSpace($fileAlgo)) { foreach ($line in ($lines)) { - if ([string]::IsNullOrWhiteSpace($line) -or$line.StartsWith("#")) { continue; }; + if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith("#")) { continue; }; if ($line -match '^([a-fA-F0-9]+)\s+') { $fileAlgo = Get-AlgorithmFromHashLength -HashString ($Matches[1]); @@ -254,33 +254,35 @@ process { break; } }; - if ([string]::IsNullOrWhiteSpace($fileAlgo)) {$fileAlgo = 'SHA256'; }; + if ([string]::IsNullOrWhiteSpace($fileAlgo)) { $fileAlgo = 'SHA256'; }; }; foreach ($line in ($lines)) { - if ([string]::IsNullOrWhiteSpace($line) -or$line.StartsWith("#")) { continue; }; + if ([string]::IsNullOrWhiteSpace($line) -or $line.StartsWith("#")) { continue; }; - $expectedHash =$null; - $targetFile =$null; + $expectedHash = $null; + $targetFile = $null; if ($line -match '^([a-fA-F0-9]+)\s+[* ]?(.*)$') { - $expectedHash =$Matches[1].ToLower(); - $targetFile =$Matches[2].Trim().TrimStart('*'); + $expectedHash = $Matches[1].ToLower(); + $targetFile = $Matches[2].Trim().TrimStart('*'); } - elseif ($line -match '^([a-fA-F0-9]{128}\vert{}[a-fA-F0-9]{96}\vert{}[a-fA-F0-9]{64}\vert{}[a-fA-F0-9]{40}\vert{}[a-fA-F0-9]{32})[* ]?(.*)$') { - $expectedHash =$Matches[1].ToLower(); - $targetFile =$Matches[2].Trim().TrimStart('*'); + elseif ($line -match '^([a-fA-F0-9]{128}|[a-fA-F0-9]{96}|[a-fA-F0-9]{64}|[a-fA-F0-9]{40}|[a-fA-F0-9]{32})[* ]?(.*)$') { + $expectedHash = $Matches[1].ToLower(); + $targetFile = $Matches[2].Trim().TrimStart('*'); }; - if ($expectedHash -and $targetFile) {$targetFullPath = Join-Path -Path ($baseDir) -ChildPath ($targetFile); + if ($expectedHash -and $targetFile) { + $targetFullPath = Join-Path -Path ($baseDir) -ChildPath ($targetFile); - if (Test-Path -Path ($targetFullPath) -PathType 'Leaf') {$actualHash = (Get-FileHash -Path ($targetFullPath) -Algorithm ($fileAlgo)).Hash.ToLower(); + if (Test-Path -Path ($targetFullPath) -PathType 'Leaf') { + $actualHash = (Get-FileHash -Path ($targetFullPath) -Algorithm ($fileAlgo)).Hash.ToLower(); $displayPath = Resolve-Path -Path ($targetFullPath) -Relative -ErrorAction 'SilentlyContinue'; - if (-not $displayPath) { $displayPath =$targetFile; }; - if ($displayPath.StartsWith(".\") -or $displayPath.StartsWith("./")) { $displayPath =$displayPath.Substring(2); }; + if (-not $displayPath) { $displayPath = $targetFile; }; + if ($displayPath.StartsWith(".\") -or $displayPath.StartsWith("./")) { $displayPath = $displayPath.Substring(2); }; - if ($actualHash -eq$expectedHash) { + if ($actualHash -eq $expectedHash) { Write-Host "${displayPath}: " -NoNewline; Write-Host "OK" -ForegroundColor Green; } else { @@ -288,9 +290,10 @@ process { Write-Host "FAILED" -ForegroundColor Red; }; } else { - $displayPath =$targetFile; - if ($baseDir -ne (Get-Location).Path) {$displayPath = Join-Path -Path (Resolve-Path -Path ($baseDir) -Relative -ErrorAction 'SilentlyContinue') -ChildPath ($targetFile); - if ($displayPath.StartsWith(".\") -or $displayPath.StartsWith("./")) { $displayPath =$displayPath.Substring(2); }; + $displayPath = $targetFile; + if ($baseDir -ne (Get-Location).Path) { + $displayPath = Join-Path -Path (Resolve-Path -Path ($baseDir) -Relative -ErrorAction 'SilentlyContinue') -ChildPath ($targetFile); + if ($displayPath.StartsWith(".\") -or $displayPath.StartsWith("./")) { $displayPath = $displayPath.Substring(2); }; }; Write-Host "${displayPath}: " -NoNewline; Write-Host "FAILED open or read" -ForegroundColor Red; @@ -301,94 +304,100 @@ process { } # --- GENERATION MODE --- else { - if ([string]::IsNullOrWhiteSpace($Algorithm)) {$Algorithm = 'SHA256'; + if ([string]::IsNullOrWhiteSpace($Algorithm)) { + $Algorithm = 'SHA256'; }; - $wantCustomOut =$PSBoundParameters.ContainsKey('OutFile'); - $wantAutoOut =$AutoOut.IsPresent; + $wantCustomOut = $PSBoundParameters.ContainsKey('OutFile'); + $wantAutoOut = $AutoOut.IsPresent; - if ($wantCustomOut -or$wantAutoOut) { + if ($wantCustomOut -or $wantAutoOut) { # Recursive wildcard auto-saves per directory - if ($Recursive -and$isWildcardGlobal) { - $groupedItems =$allItems | Group-Object DirectoryName; + if ($Recursive -and $isWildcardGlobal) { + $groupedItems = $allItems | Group-Object DirectoryName; foreach ($group in ($groupedItems)) { - $dirPath =$group.Name; - $filesInDir =$group.Group; + $dirPath = $group.Name; + $filesInDir = $group.Group; - if ($wantCustomOut) {$currentOutFile = Join-Path -Path ($dirPath) -ChildPath ($OutFile); + if ($wantCustomOut) { + $currentOutFile = Join-Path -Path ($dirPath) -ChildPath ($OutFile); } else { $currentOutFile = Join-Path -Path ($dirPath) -ChildPath "checksums.$($Algorithm.ToLower())"; }; $linesToWrite = @(); - foreach ($item in ($filesInDir)) {$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); - $relativePath =$item.Name; + foreach ($item in ($filesInDir)) { + $hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); + $relativePath = $item.Name; - $outputLine = "${hash}${relativePath}"; - $linesToWrite +=$outputLine; + $outputLine = "${hash} ${relativePath}"; + $linesToWrite += $outputLine; Write-Output $outputLine; }; - Set-Content -Path ($currentOutFile) -Value$linesToWrite -Encoding utf8; + Set-Content -Path ($currentOutFile) -Value $linesToWrite -Encoding utf8; }; } else { # Custom file OR Auto file with a wildcard - if ($wantCustomOut -or ($wantAutoOut -and$isWildcardGlobal)) { + if ($wantCustomOut -or ($wantAutoOut -and $isWildcardGlobal)) { if ($wantCustomOut) { - $singleOutFile =$OutFile; + $singleOutFile = $OutFile; } else { $singleOutFile = "checksums.$($Algorithm.ToLower())"; }; $linesToWrite = @(); - foreach ($item in ($allItems)) {$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); + foreach ($item in ($allItems)) { + $hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); $relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue'; - if (-not $relativePath) { $relativePath =$item.Name; }; + if (-not $relativePath) { $relativePath = $item.Name; }; if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) { - $relativePath =$relativePath.Substring(2); + $relativePath = $relativePath.Substring(2); }; - $outputLine = "${hash}${relativePath}"; - $linesToWrite +=$outputLine; + $outputLine = "${hash} ${relativePath}"; + $linesToWrite += $outputLine; Write-Output $outputLine; }; - Set-Content -Path ($singleOutFile) -Value$linesToWrite -Encoding utf8; + Set-Content -Path ($singleOutFile) -Value $linesToWrite -Encoding utf8; } # Auto file for explicit individual files (No wildcard) else { - foreach ($item in ($allItems)) {$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); + foreach ($item in ($allItems)) { + $hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); $relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue'; - if (-not $relativePath) { $relativePath =$item.Name; }; + if (-not $relativePath) { $relativePath = $item.Name; }; if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) { - $relativePath =$relativePath.Substring(2); + $relativePath = $relativePath.Substring(2); }; - $outputLine = "${hash}${relativePath}"; + $outputLine = "${hash} ${relativePath}"; Write-Output $outputLine; # Save directly next to the original file: . $itemOutFile = "$($item.FullName).$($Algorithm.ToLower())"; - Set-Content -Path ($itemOutFile) -Value$outputLine -Encoding utf8; + Set-Content -Path ($itemOutFile) -Value $outputLine -Encoding utf8; }; }; }; } # Standard console output (No save flags passed) else { - foreach ($item in ($allItems)) {$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); + foreach ($item in ($allItems)) { + $hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($Algorithm)).Hash.ToLower(); $relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue'; - if (-not $relativePath) { $relativePath =$item.Name; }; + if (-not $relativePath) { $relativePath = $item.Name; }; if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) { - $relativePath =$relativePath.Substring(2); + $relativePath = $relativePath.Substring(2); }; - $outputLine = "${hash}${relativePath}"; + $outputLine = "${hash} ${relativePath}"; Write-Output $outputLine; }; };