PSGalleryBatch.psm1
|
function Find-GalleryModuleBatch { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true)] [string]$Name, [Parameter()] [switch]$AllowPrerelease, [Parameter()] [switch]$Install, [Parameter()] [switch]$Update, [Parameter()] [switch]$Silent ) process { # Auto-wildcard for convenience if ($Name -notmatch '\*') { $Name = "*$Name*" } Write-Host "Searching for modules matching '$Name'..." -ForegroundColor Cyan $modules = @() try { # Try to use Find-PSResource (PSResourceGet v3) first as it supports wildcards + prerelease if (Get-Command Find-PSResource -ErrorAction SilentlyContinue) { Write-Verbose "Using Find-PSResource" $modules = @(Find-PSResource -Name $Name -Repository PSGallery -Prerelease:$AllowPrerelease -ErrorAction Stop) } else { Write-Verbose "Using Find-Module (PowerShellGet v2)" if ($AllowPrerelease -and $Name -match '\*') { Write-Warning "PowerShellGet (Find-Module) does not support Wildcards with -AllowPrerelease. SEARCHING STABLE ONLY." $modules = @(Find-Module -Name $Name -Repository PSGallery -ErrorAction Stop) } else { $modules = @(Find-Module -Name $Name -Repository PSGallery -AllowPrerelease:$AllowPrerelease -ErrorAction Stop) } } if ($modules.Count -eq 0) { Write-Warning "No modules found matching '$Name'." return } Write-Host "Found $($modules.Count) modules." -ForegroundColor Green $selected = @() if ($Silent) { Write-Host "Silent mode: Selecting all $($modules.Count) modules." -ForegroundColor Yellow $selected = $modules } else { # Invoke UI selection $selected = Show-ModuleSelection -Modules $modules } if ($selected) { Write-Host "`nProcessing $($selected.Count) selected module(s)..." -ForegroundColor Cyan if ($Install) { $selected | Install-GalleryModuleBatch -AllowPrerelease:$AllowPrerelease } elseif ($Update) { $selected | Update-GalleryModuleBatch -AllowPrerelease:$AllowPrerelease } else { return $selected } } } catch { Write-Warning "Search failed: $_" } } } function Show-ModuleSelection { param( [Parameter(Mandatory = $true)] [array]$Modules ) # Attempt to use Spectre Console if available if (Get-Command Read-SpectreMultiSelection -ErrorAction SilentlyContinue) { $choices = $Modules | ForEach-Object { $desc = if ($_.Description -and $_.Description.Length -gt 60) { $_.Description.Substring(0, 57) + "..." } else { $_.Description } "$($_.Name) ($($_.Version)) - $desc" } $selectedStrings = Read-SpectreMultiSelection -Message "[cyan]Select modules to process (Space to toggle, Enter to confirm)[/]" ` -Choices $choices ` -Color "Green" ` -PageSize 20 if (-not $selectedStrings) { return $null } $results = foreach ($sel in $selectedStrings) { if ($sel -match '^(.+?)\s+\((.+?)\)\s+-') { $mName = $matches[1] $mVer = $matches[2] $Modules | Where-Object { $_.Name -eq $mName -and $_.Version -eq $mVer } | Select-Object -First 1 } } return $results } else { Write-Warning "Spectre Console 'Read-SpectreMultiSelection' not found. Using Out-GridView." return $Modules | Out-GridView -Title "Select Modules" -PassThru } } function Install-GalleryModuleBatch { [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] $InputObject, [Parameter()] [switch]$AllowPrerelease ) begin { $items = @() } process { $items += $InputObject } end { if ($items.Count -eq 0) { return } foreach ($mod in $items) { Write-Host "Installing: " -ForegroundColor Magenta -NoNewline Write-Host "$($mod.Name) ($($mod.Version))" -ForegroundColor White try { if (Get-Command Install-PSResource -ErrorAction SilentlyContinue) { # Removed -Force (not supported), using -TrustRepository Install-PSResource -Name $mod.Name -Version $mod.Version -Prerelease:$AllowPrerelease -TrustRepository -Scope CurrentUser -ErrorAction Stop } else { Install-Module -Name $mod.Name -RequiredVersion $mod.Version -AllowPrerelease:$AllowPrerelease -Scope CurrentUser -Force -AllowClobber -ErrorAction Stop } Write-Host "✓ Successfully installed $($mod.Name)" -ForegroundColor Green } catch { Write-Error "✗ Failed to install $($mod.Name): $_" } } } } function Update-GalleryModuleBatch { [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] $InputObject, [Parameter()] [switch]$AllowPrerelease ) begin { $items = @() } process { $items += $InputObject } end { if ($items.Count -eq 0) { return } foreach ($mod in $items) { Write-Host "Updating: " -ForegroundColor Magenta -NoNewline Write-Host "$($mod.Name)" -ForegroundColor White try { if (Get-Command Update-PSResource -ErrorAction SilentlyContinue) { Update-PSResource -Name $mod.Name -Prerelease:$AllowPrerelease -TrustRepository -ErrorAction Stop } else { Update-Module -Name $mod.Name -AllowPrerelease:$AllowPrerelease -Force -ErrorAction Stop } Write-Host "✓ Successfully updated $($mod.Name)" -ForegroundColor Green } catch { Write-Error "✗ Failed to update $($mod.Name): $_" } } } } |