waypoit debuguing
This commit is contained in:
+155
-87
@@ -1,3 +1,13 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Princess Pi's Magical CHECKSUM! - Computes and verifies message digests / file checksums.
|
||||
.DESCRIPTION
|
||||
Computes or verifies checksums using cryptographic hash algorithms (SHA256, SHA512, SHA1, MD5, SHA384).
|
||||
Supports parallel processing, recursive scanning, direct hash matching, and verification file parsing.
|
||||
.NOTES
|
||||
Requires PowerShell 7.0 or higher.
|
||||
#>
|
||||
|
||||
[CmdletBinding(DefaultParameterSetName='Generate')]
|
||||
param(
|
||||
# File(s) or wildcard pattern to compute checksum for
|
||||
@@ -49,6 +59,13 @@ param(
|
||||
[switch]$Help
|
||||
)
|
||||
|
||||
# --- ENVIRONMENT SANITY CHECK ---
|
||||
# Ensure PowerShell 7+ is used since ForEach-Object -Parallel is required.
|
||||
if ($PSVersionTable.PSVersion.Major -lt 7) {
|
||||
Write-Error "checksum: This script requires PowerShell 7 or higher for parallel execution (-Parallel support). Current version is $($PSVersionTable.PSVersion)."
|
||||
exit 1
|
||||
}
|
||||
|
||||
begin {
|
||||
function Show-Help {
|
||||
@'
|
||||
@@ -149,7 +166,7 @@ https://linktr.ee/princesspi3
|
||||
@****#######%**@+*%**#%+++++%##*** #+++++++++++++++++#+++++#****+======*****+
|
||||
#****##%####@**%+*******@@+++@###**% #+++++++++++++*++++++++++****========****#
|
||||
****#####%%*%*%+***@@@%%@*+++@####** *+++++++++++++++++++++#****=======****#
|
||||
%***####%%**+%%*++*@=##@@%@++++%###*** +++++*+++++++++++#+**************#
|
||||
%***####%%**+%%*++*@=##@@%@++++%###*** ++++*+++++++++++#+**************#
|
||||
@%%%@@##%%#++++++++==**@@**+++%*###**% +++++++++++#*+++++#*********####
|
||||
%###%++++++++====**#++++%**##**% @% ++++#+++++++++++++**************#
|
||||
%###%++++++++++++++++++%**%##**%@###@ %++++++++++++++++***=====********
|
||||
@@ -174,7 +191,7 @@ https://linktr.ee/princesspi3
|
||||
@@@@@@@@@@ ++++++++# ******# #++++++# *##@%********% @*@
|
||||
@@+@@@++@@+ ++++++++# ******# #++++++# @## #*********@ #***#
|
||||
@@+@@++@@@++ @@@++++++* @@@%**** #@@++++% +## %#****************%
|
||||
@*@**@+++# @@@@+++++ @@@@@@**# @@@@++++# @# %#****************
|
||||
@*@**@+++# @@@@+++++ @@@@@@**# @@@@@++++# @# %#****************
|
||||
+#+++++# @@@@@@+++% @@@@@@@@# @@@@@@@++ @ %##************%
|
||||
#+++** @@@@@@@@@@ @@@@@@@@@ @@@@@@@@@ %###********%*
|
||||
@@@@@@@@@@+ @@@@@@@@@@ =@@@@@@@@@ %%#####%%
|
||||
@@ -213,31 +230,6 @@ https://linktr.ee/princesspi3
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function Invoke-ParallelHashing {
|
||||
param([array]$Items, [string]$Algorithm);
|
||||
|
||||
$Items | ForEach-Object -Parallel {
|
||||
$item = $_
|
||||
$algo = $using:Algorithm
|
||||
|
||||
$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($algo)).Hash.ToLower();
|
||||
|
||||
$relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue';
|
||||
if (-not $relativePath) { $relativePath = $item.Name; };
|
||||
if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) {
|
||||
$relativePath = $relativePath.Substring(2);
|
||||
};
|
||||
|
||||
[PSCustomObject]@{
|
||||
Item = $item
|
||||
Hash = $hash
|
||||
RelativePath = $relativePath
|
||||
OutputLine = "${hash} ${relativePath}"
|
||||
ItemOutFile = "$($item.FullName).$($algo.ToLower())"
|
||||
}
|
||||
} -ThrottleLimit 16
|
||||
};
|
||||
}
|
||||
|
||||
process {
|
||||
@@ -265,6 +257,15 @@ process {
|
||||
$Algorithm = $Algorithm.ToUpper();
|
||||
};
|
||||
|
||||
# Determine if progress bar should display (-r, -c/-Check, or wildcard input '*')
|
||||
$isWildcardGlobal = $false;
|
||||
if ($FilePath) {
|
||||
foreach ($p in $FilePath) {
|
||||
if ($p -match '\*') { $isWildcardGlobal = $true; }
|
||||
}
|
||||
}
|
||||
$showProgress = $Recursive.IsPresent -or $isWildcardGlobal -or ($PSCmdlet.ParameterSetName -eq 'Verify');
|
||||
|
||||
# --- ITEM GATHERING (Generate & Match Modes) ---
|
||||
if ($PSCmdlet.ParameterSetName -in @('Generate', 'Match')) {
|
||||
if (-not $FilePath -or $FilePath.Count -eq 0) {
|
||||
@@ -273,14 +274,12 @@ process {
|
||||
};
|
||||
|
||||
$allItems = @();
|
||||
$isWildcardGlobal = $false;
|
||||
$skipExtensions = @('.md5', '.sha1', '.sha256', '.sha384', '.sha512');
|
||||
|
||||
foreach ($pathEntry in ($FilePath)) {
|
||||
$isWildcard = ($pathEntry -match '\*');
|
||||
if ($isWildcard) { $isWildcardGlobal = $true; };
|
||||
|
||||
$resolvedItems = @();
|
||||
|
||||
if ($Recursive) {
|
||||
$resolvedItems = Get-ChildItem -Path ($pathEntry) -Recurse -File -ErrorAction 'SilentlyContinue';
|
||||
} else {
|
||||
@@ -323,9 +322,10 @@ process {
|
||||
|
||||
$expectedHash = $Match.Trim().ToLower();
|
||||
$totalFiles = $allItems.Count;
|
||||
$currentIndex = [ref]0;
|
||||
$currentIndex = 0;
|
||||
|
||||
$results = $allItems | ForEach-Object -Parallel {
|
||||
# Stream parallel results and update progress bar in real time
|
||||
$allItems | ForEach-Object -Parallel {
|
||||
$item = $_
|
||||
$algo = $using:Algorithm
|
||||
$exp = $using:expectedHash
|
||||
@@ -339,25 +339,22 @@ process {
|
||||
TargetFile = $targetFile
|
||||
IsMatch = ($actualHash -eq $exp)
|
||||
}
|
||||
} -ThrottleLimit 16;
|
||||
|
||||
$showProgressMatch = $Recursive.IsPresent -or $isWildcardGlobal;
|
||||
|
||||
foreach ($res in $results) {
|
||||
$currentIndex.Value++;
|
||||
if ($showProgressMatch -and $totalFiles -gt 0) {
|
||||
Write-Progress -Activity "Matching Checksums ($Algorithm)" -Status "Processing file $($currentIndex.Value) of $totalFiles" -PercentComplete (($currentIndex.Value / $totalFiles) * 100);
|
||||
} -ThrottleLimit 16 | ForEach-Object {
|
||||
$currentIndex++
|
||||
if ($showProgress -and $totalFiles -gt 0) {
|
||||
Write-Progress -Activity "Matching Checksums ($Algorithm)" -Status "Processing file $currentIndex of $totalFiles" -PercentComplete (($currentIndex / $totalFiles) * 100);
|
||||
}
|
||||
|
||||
if ($res.IsMatch) {
|
||||
Write-Host "$($res.TargetFile): " -NoNewline;
|
||||
if ($_.IsMatch) {
|
||||
Write-Host "$($_.TargetFile): " -NoNewline;
|
||||
Write-Host "OK" -ForegroundColor Green;
|
||||
} else {
|
||||
Write-Host "$($res.TargetFile): " -NoNewline;
|
||||
Write-Host "$($_.TargetFile): " -NoNewline;
|
||||
Write-Host "FAILED" -ForegroundColor Red;
|
||||
}
|
||||
};
|
||||
if ($showProgressMatch) {
|
||||
|
||||
if ($showProgress) {
|
||||
Write-Progress -Activity "Matching Checksums ($Algorithm)" -Completed;
|
||||
}
|
||||
}
|
||||
@@ -428,10 +425,10 @@ process {
|
||||
}
|
||||
|
||||
$totalFiles = $verifyItems.Count;
|
||||
$currentIndex = [ref]0;
|
||||
$currentIndex = 0;
|
||||
|
||||
# Run verification items in parallel
|
||||
$verifyResults = $verifyItems | ForEach-Object -Parallel {
|
||||
# Run verification items in parallel and stream progress live
|
||||
$verifyItems | ForEach-Object -Parallel {
|
||||
$item = $_
|
||||
$algo = $using:fileAlgo
|
||||
|
||||
@@ -459,23 +456,21 @@ process {
|
||||
IsError = $true
|
||||
}
|
||||
}
|
||||
} -ThrottleLimit 16;
|
||||
|
||||
foreach ($res in $verifyResults) {
|
||||
$currentIndex.Value++;
|
||||
} -ThrottleLimit 16 | ForEach-Object {
|
||||
$currentIndex++
|
||||
if ($totalFiles -gt 0) {
|
||||
Write-Progress -Activity "Verifying Checksums ($fileAlgo)" -Status "Processing file $($currentIndex.Value) of $totalFiles" -PercentComplete (($currentIndex.Value / $totalFiles) * 100);
|
||||
Write-Progress -Activity "Verifying Checksums ($fileAlgo)" -Status "Processing file $currentIndex of $totalFiles" -PercentComplete (($currentIndex / $totalFiles) * 100);
|
||||
}
|
||||
|
||||
Write-Host "$($res.DisplayPath): " -NoNewline;
|
||||
if ($res.IsError) {
|
||||
Write-Host "$($res.Status)" -ForegroundColor Red;
|
||||
} elseif ($res.Status -eq "OK") {
|
||||
Write-Host "$($_.DisplayPath): " -NoNewline;
|
||||
if ($_.IsError) {
|
||||
Write-Host "$($_.Status)" -ForegroundColor Red;
|
||||
} elseif ($_.Status -eq "OK") {
|
||||
Write-Host "OK" -ForegroundColor Green;
|
||||
} else {
|
||||
Write-Host "FAILED" -ForegroundColor Red;
|
||||
}
|
||||
}
|
||||
};
|
||||
Write-Progress -Activity "Verifying Checksums ($fileAlgo)" -Completed;
|
||||
};
|
||||
}
|
||||
@@ -488,9 +483,6 @@ process {
|
||||
$wantCustomOut = $PSBoundParameters.ContainsKey('OutFile');
|
||||
$wantAutoOut = $Save.IsPresent;
|
||||
|
||||
# Show progress if wildcard used anywhere in inputs or recursive flag set
|
||||
$showProgressGen = $Recursive.IsPresent -or $isWildcardGlobal;
|
||||
|
||||
if ($wantCustomOut -or $wantAutoOut) {
|
||||
# Recursive wildcard auto-saves per directory
|
||||
if ($Recursive -and $isWildcardGlobal) {
|
||||
@@ -510,17 +502,36 @@ process {
|
||||
$currentIndex = 0;
|
||||
$linesToWrite = @();
|
||||
|
||||
$parallelResults = Invoke-ParallelHashing -Items $filesInDir -Algorithm $Algorithm;
|
||||
foreach ($res in $parallelResults) {
|
||||
$filesInDir | ForEach-Object -Parallel {
|
||||
$item = $_
|
||||
$algo = $using:Algorithm
|
||||
|
||||
$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($algo)).Hash.ToLower();
|
||||
|
||||
$relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue';
|
||||
if (-not $relativePath) { $relativePath = $item.Name; };
|
||||
if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) {
|
||||
$relativePath = $relativePath.Substring(2);
|
||||
};
|
||||
|
||||
[PSCustomObject]@{
|
||||
Item = $item
|
||||
Hash = $hash
|
||||
RelativePath = $relativePath
|
||||
OutputLine = "${hash} ${relativePath}"
|
||||
ItemOutFile = "$($item.FullName).$($algo.ToLower())"
|
||||
}
|
||||
} -ThrottleLimit 16 | ForEach-Object {
|
||||
$currentIndex++;
|
||||
if ($showProgressGen -and $totalFiles -gt 0) {
|
||||
if ($showProgress -and $totalFiles -gt 0) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Status "Directory: $(Split-Path $dirPath -Leaf) [$currentIndex/$totalFiles]" -PercentComplete (($currentIndex / $totalFiles) * 100);
|
||||
}
|
||||
|
||||
$linesToWrite += $res.OutputLine;
|
||||
Write-Output $res.OutputLine;
|
||||
}
|
||||
if ($showProgressGen) {
|
||||
$linesToWrite += $_.OutputLine;
|
||||
Write-Output $_.OutputLine;
|
||||
};
|
||||
|
||||
if ($showProgress) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Completed;
|
||||
}
|
||||
|
||||
@@ -540,17 +551,36 @@ process {
|
||||
$currentIndex = 0;
|
||||
$linesToWrite = @();
|
||||
|
||||
$parallelResults = Invoke-ParallelHashing -Items $allItems -Algorithm $Algorithm;
|
||||
foreach ($res in $parallelResults) {
|
||||
$allItems | ForEach-Object -Parallel {
|
||||
$item = $_
|
||||
$algo = $using:Algorithm
|
||||
|
||||
$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($algo)).Hash.ToLower();
|
||||
|
||||
$relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue';
|
||||
if (-not $relativePath) { $relativePath = $item.Name; };
|
||||
if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) {
|
||||
$relativePath = $relativePath.Substring(2);
|
||||
};
|
||||
|
||||
[PSCustomObject]@{
|
||||
Item = $item
|
||||
Hash = $hash
|
||||
RelativePath = $relativePath
|
||||
OutputLine = "${hash} ${relativePath}"
|
||||
ItemOutFile = "$($item.FullName).$($algo.ToLower())"
|
||||
}
|
||||
} -ThrottleLimit 16 | ForEach-Object {
|
||||
$currentIndex++;
|
||||
if ($showProgressGen -and $totalFiles -gt 0) {
|
||||
if ($showProgress -and $totalFiles -gt 0) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Status "Processing file $currentIndex of $totalFiles" -PercentComplete (($currentIndex / $totalFiles) * 100);
|
||||
}
|
||||
|
||||
$linesToWrite += $res.OutputLine;
|
||||
Write-Output $res.OutputLine;
|
||||
}
|
||||
if ($showProgressGen) {
|
||||
$linesToWrite += $_.OutputLine;
|
||||
Write-Output $_.OutputLine;
|
||||
};
|
||||
|
||||
if ($showProgress) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Completed;
|
||||
}
|
||||
|
||||
@@ -561,17 +591,36 @@ process {
|
||||
$totalFiles = $allItems.Count;
|
||||
$currentIndex = 0;
|
||||
|
||||
$parallelResults = Invoke-ParallelHashing -Items $allItems -Algorithm $Algorithm;
|
||||
foreach ($res in $parallelResults) {
|
||||
$allItems | ForEach-Object -Parallel {
|
||||
$item = $_
|
||||
$algo = $using:Algorithm
|
||||
|
||||
$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($algo)).Hash.ToLower();
|
||||
|
||||
$relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue';
|
||||
if (-not $relativePath) { $relativePath = $item.Name; };
|
||||
if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) {
|
||||
$relativePath = $relativePath.Substring(2);
|
||||
};
|
||||
|
||||
[PSCustomObject]@{
|
||||
Item = $item
|
||||
Hash = $hash
|
||||
RelativePath = $relativePath
|
||||
OutputLine = "${hash} ${relativePath}"
|
||||
ItemOutFile = "$($item.FullName).$($algo.ToLower())"
|
||||
}
|
||||
} -ThrottleLimit 16 | ForEach-Object {
|
||||
$currentIndex++;
|
||||
if ($showProgressGen -and $totalFiles -gt 0) {
|
||||
if ($showProgress -and $totalFiles -gt 0) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Status "Processing file $currentIndex of $totalFiles" -PercentComplete (($currentIndex / $totalFiles) * 100);
|
||||
}
|
||||
|
||||
Write-Output $res.OutputLine;
|
||||
Set-Content -Path ($res.ItemOutFile) -Value $res.OutputLine -Encoding utf8;
|
||||
}
|
||||
if ($showProgressGen) {
|
||||
Write-Output $_.OutputLine;
|
||||
Set-Content -Path ($_.ItemOutFile) -Value $_.OutputLine -Encoding utf8;
|
||||
};
|
||||
|
||||
if ($showProgress) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Completed;
|
||||
}
|
||||
};
|
||||
@@ -582,16 +631,35 @@ process {
|
||||
$totalFiles = $allItems.Count;
|
||||
$currentIndex = 0;
|
||||
|
||||
$parallelResults = Invoke-ParallelHashing -Items $allItems -Algorithm $Algorithm;
|
||||
foreach ($res in $parallelResults) {
|
||||
$allItems | ForEach-Object -Parallel {
|
||||
$item = $_
|
||||
$algo = $using:Algorithm
|
||||
|
||||
$hash = (Get-FileHash -Path ($item.FullName) -Algorithm ($algo)).Hash.ToLower();
|
||||
|
||||
$relativePath = Resolve-Path -Path ($item.FullName) -Relative -ErrorAction 'SilentlyContinue';
|
||||
if (-not $relativePath) { $relativePath = $item.Name; };
|
||||
if ($relativePath.StartsWith(".\") -or $relativePath.StartsWith("./")) {
|
||||
$relativePath = $relativePath.Substring(2);
|
||||
};
|
||||
|
||||
[PSCustomObject]@{
|
||||
Item = $item
|
||||
Hash = $hash
|
||||
RelativePath = $relativePath
|
||||
OutputLine = "${hash} ${relativePath}"
|
||||
ItemOutFile = "$($item.FullName).$($algo.ToLower())"
|
||||
}
|
||||
} -ThrottleLimit 16 | ForEach-Object {
|
||||
$currentIndex++;
|
||||
if ($showProgressGen -and $totalFiles -gt 0) {
|
||||
if ($showProgress -and $totalFiles -gt 0) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Status "Processing file $currentIndex of $totalFiles" -PercentComplete (($currentIndex / $totalFiles) * 100);
|
||||
}
|
||||
|
||||
Write-Output $res.OutputLine;
|
||||
}
|
||||
if ($showProgressGen) {
|
||||
Write-Output $_.OutputLine;
|
||||
};
|
||||
|
||||
if ($showProgress) {
|
||||
Write-Progress -Activity "Computing Checksums ($Algorithm)" -Completed;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user