Private/IWAPG-Hlp-UpdateCheck.ps1
|
function Get-PowerShellGalleryModuleVersion { <# .SYNOPSIS Returns the latest module version from PowerShell Gallery. .PARAMETER ModuleName The module name to query. .PARAMETER TimeoutSeconds Request timeout in seconds. #> [CmdletBinding()] param( [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string] $ModuleName, [Parameter()][int] $TimeoutSeconds = 10, [switch] $Detailed ) try { $lastError = $null if (Get-Command -Name Find-Module -ErrorAction SilentlyContinue) { try { $galleryModule = Find-Module -Name $ModuleName -Repository PSGallery -ErrorAction Stop if ($galleryModule -and $galleryModule.Version) { $latest = [version]$galleryModule.Version return $Detailed ? [PSCustomObject]@{ Latest = $latest; Error = $null } : $latest } } catch { $lastError = $_.Exception.Message # fall back to OData endpoint below } } try { $tls12 = [Net.SecurityProtocolType]::Tls12 [Net.ServicePointManager]::SecurityProtocol = $tls12 -bor [Net.ServicePointManager]::SecurityProtocol } catch { } $url = "https://www.powershellgallery.com/api/v2/FindPackagesById()?id='$ModuleName'" $client = New-Object System.Net.Http.HttpClient $client.Timeout = [TimeSpan]::FromSeconds($TimeoutSeconds) $resp = $client.GetAsync($url).Result if (-not $resp.IsSuccessStatusCode) { $lastError = "HTTP $($resp.StatusCode)" return $Detailed ? [PSCustomObject]@{ Latest = $null; Error = $lastError } : $null } $content = $resp.Content.ReadAsStringAsync().Result if (-not $content) { $lastError = "Empty response" return $Detailed ? [PSCustomObject]@{ Latest = $null; Error = $lastError } : $null } $xml = [xml]$content $versions = @() foreach ($entry in $xml.feed.entry) { $ver = $entry.properties.Version if ($ver) { $versions += [version]$ver } } if ($versions.Count -eq 0) { $lastError = "No versions found" return $Detailed ? [PSCustomObject]@{ Latest = $null; Error = $lastError } : $null } $latest = ($versions | Sort-Object -Descending | Select-Object -First 1) return $Detailed ? [PSCustomObject]@{ Latest = $latest; Error = $null } : $latest } catch { $msg = $_.Exception.Message return $Detailed ? [PSCustomObject]@{ Latest = $null; Error = $msg } : $null } finally { if ($client) { $client.Dispose() } } } |