BountyHunter.psm1
# BountyHunter.psm1 # — Load registry from JSON $moduleJson = Join-Path $PSScriptRoot 'modules.json' if (Test-Path $moduleJson) { try { $Global:BountyModuleIndex = Get-Content $moduleJson -Raw | ConvertFrom-Json } catch { Write-Warning "Failed to parse modules.json: $_" $Global:BountyModuleIndex = @() } } else { Write-Warning "modules.json not found at $moduleJson" $Global:BountyModuleIndex = @() } # ------------------------ # 1. Discovery # ------------------------ function Get-BountyModules { [CmdletBinding()] param( [string]$Tag ) $list = $Global:BountyModuleIndex if ($Tag) { $list = $list | Where-Object { $_.Tags -contains $Tag } } $list | Select-Object Name, Description, @{n='Tags';e={($_.Tags -join ', ')}} } function Get-BountyStatus { [CmdletBinding()] param() $results = @() $total = $Global:BountyModuleIndex.Count $i = 1 foreach ($mod in $Global:BountyModuleIndex) { Write-Host "🔍 [$i/$total] Checking module: $($mod.Name)" -ForegroundColor Cyan # Local install info $inst = Get-Module -ListAvailable -Name $mod.Name | Sort-Object Version -Descending | Select-Object -First 1 $instVer = if ($inst) { [version]$inst.Version } else { $null } $status = if ($inst) { '✅ Installed' } else { '❌ Missing' } # Remote gallery info try { $remote = Find-Module -Name $mod.Name -ErrorAction Stop $remoteVer = [version]$remote.Version } catch { $remoteVer = $null } $outdated = if ($instVer -and $remoteVer) { $remoteVer -gt $instVer } else { $false } $results += [PSCustomObject]@{ Name = $mod.Name Status = $status InstalledVersion = if ($instVer) { $instVer.ToString() } else { '<none>' } LatestVersion = if ($remoteVer) { $remoteVer.ToString() } else { '<unknown>' } Outdated = if ($outdated) { '⚠️ Yes' } else { '😊 No' } } $i++ } Write-Host "`n📊 Done! Here's your module status report:`n" -ForegroundColor Green $results | Format-Table -AutoSize } function Install-BountyModules { [CmdletBinding()] param( [switch]$Force ) foreach ($mod in $Global:BountyModuleIndex) { $installed = Get-Module -ListAvailable -Name $mod.Name | Sort-Object Version -Descending | Select-Object -First 1 if (-not $installed -or $Force) { try { Write-Host "📦 Installing $($mod.Name)..." -ForegroundColor Cyan Install-Module -Name $mod.Name -Force:$Force -Scope CurrentUser -ErrorAction Stop Write-Host "✅ Installed $($mod.Name)" -ForegroundColor Green } catch { Write-Warning "❌ Failed to install $($mod.Name): $_" } } else { Write-Host "✔️ Already installed: $($mod.Name)" -ForegroundColor Yellow } } } function Update-BountyModules { [CmdletBinding()] param() foreach ($mod in $Global:BountyModuleIndex) { try { $installed = Get-Module -ListAvailable -Name $mod.Name | Sort-Object Version -Descending | Select-Object -First 1 $remote = Find-Module -Name $mod.Name -ErrorAction Stop if ($installed -and [version]$remote.Version -gt [version]$installed.Version) { Write-Host "⬆️ Updating $($mod.Name) from $($installed.Version) to $($remote.Version)..." -ForegroundColor Cyan Install-Module -Name $mod.Name -Force -Scope CurrentUser -ErrorAction Stop Write-Host "✅ Updated $($mod.Name)" -ForegroundColor Green } elseif (-not $installed) { Write-Host "📦 Not installed: $($mod.Name), installing now..." -ForegroundColor Cyan Install-Module -Name $mod.Name -Force -Scope CurrentUser -ErrorAction Stop Write-Host "✅ Installed $($mod.Name)" -ForegroundColor Green } else { Write-Host "✔️ $($mod.Name) is up to date" -ForegroundColor Yellow } } catch { Write-Warning "❌ Failed to update $($mod.Name): $_" } } } |