Private/Get-Sha256FromUrlWithCache.ps1
|
function Get-Sha256FromUrlWithCache { <# .SYNOPSIS Downloads a file from a URL, calculates its SHA256 hash, and caches the result for 24 hours. .DESCRIPTION Downloads the file at the specified URL to a temporary location, calculates its SHA256 hash, and caches the hash in a JSON file in the user's TEMP directory. If a cached hash exists and is less than 24 hours old, the cached value is returned. .PARAMETER Url The URL of the file to download and hash. .EXAMPLE Get-Sha256FromUrlWithCache -Url 'https://example.com/file.zip' .OUTPUTS System.String. The lowercase SHA256 hash of the file. #> param([string]$Url) $url = $Url.Trim() $cachePath = Join-Path $env:TEMP 'ChocoForge-HashCache.json' $cache = @{} if (Test-Path $cachePath) { try { $rawCache = Get-Content $cachePath -Raw | ConvertFrom-Json if ($rawCache -is [System.Collections.IDictionary]) { foreach ($k in $rawCache.PSObject.Properties.Name) { $cache[$k] = $rawCache.$k } } elseif ($rawCache -is [PSCustomObject]) { foreach ($k in $rawCache.PSObject.Properties.Name) { $cache[$k] = $rawCache.$k } } else { $cache = @{} } } catch { Write-VerboseMark 'Failed to read or parse cache file. Starting with empty cache.' $cache = @{} } } $now = Get-Date $cacheKey = $url $cachedEntry = $null if ($cache.Keys -contains $cacheKey) { $cachedEntry = $cache[$cacheKey] $cacheTime = Get-Date $cachedEntry.timestamp if ($now - $cacheTime -lt ([TimeSpan]::FromHours(24))) { Write-VerboseMark "Using cached SHA256 for $url." return $cachedEntry.sha256 } else { Write-VerboseMark "Cache expired for $url. Recomputing hash." } } $tempDir = Join-Path $env:TEMP ([System.Guid]::NewGuid().ToString()) New-Item -ItemType Directory -Path $tempDir | Out-Null $fileName = Split-Path $url -Leaf $filePath = Join-Path $tempDir $fileName Write-VerboseMark "Downloading $url to $filePath ..." Invoke-WebRequest -Uri $url -OutFile $filePath -UseBasicParsing -Verbose:$false Write-VerboseMark "Calculating SHA256 for $filePath ..." $sha256 = (Get-FileHash -Path $filePath -Algorithm SHA256).Hash.ToLower() Remove-Item -Path $tempDir -Recurse -Force $cache[$cacheKey] = @{ sha256 = $sha256; timestamp = $now.ToString('o') } try { $cache | ConvertTo-Json -Depth 5 | Set-Content -Path $cachePath -Force Write-VerboseMark "Wrote SHA256 to cache for $url." } catch { Write-VerboseMark 'Failed to write cache file.' } Write-VerboseMark "Returning calculated SHA256 for $url." return $sha256 } |