#Requires -Version 5.1 [CmdletBinding(SupportsShouldProcess)] param([ValidateSet('Tor','Zen','Helium','Mullvad','VeraCrypt')][string[]]$App = @()) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $catalog = Get-Content -LiteralPath (Join-Path $PSScriptRoot 'config/apps.json') -Raw | ConvertFrom-Json if ($App.Count -eq 0) { $catalog | Format-Table Name,Id,Role -Wrap; return } foreach ($name in @($App | Select-Object -Unique)) { $package = $catalog | Where-Object Name -EQ $name Write-Output "$($package.Name): $($package.Role)" Write-Output "Official site: $($package.Website)" if ($PSCmdlet.ShouldProcess($package.Id, 'Install from exact WinGet community-source package; retain installer prompts')) { $winget = Get-Command winget.exe -ErrorAction Stop # No bypassed hash checks, remote PowerShell execution, automatic source/license acceptance or forced restart. & $winget.Source install --id $package.Id --exact --source winget --interactive if ($LASTEXITCODE -ne 0) { throw "WinGet returned $LASTEXITCODE for $name. Installation was not confirmed; inspect its output." } } }