PowerShell / PowerShellGallery

221 stars 61 forks source link

PowerShellGallery API throttled? #129

Closed o-l-a-v closed 4 months ago

o-l-a-v commented 3 years ago

I have this script for updating PowerShell modules, and removing outdated ones.

In it I have following function for getting latest published version of a module from PowerShellGallery

Prerequirement

$null = New-Variable -Scope 'Script' -Option 'ReadOnly' -Force -Name 'Random' -Value ([System.Random]::New())

Function

function Get-ModulePublishedVersion {
    <#
        .SYNAPSIS
            Fetches latest version number of a given module from PowerShellGallery.

        .PARAMETER ModuleName
            String, name of the module you want to check.
    #>            
    [CmdletBinding(SupportsPaging=$false)]
    [OutputType([System.Version])]    
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string] $ModuleName
    )

    Begin {}

    Process {                                
        # Access the main module page, and add a random number to trick proxies
        $Url = [string]('https://www.powershellgallery.com/packages/{0}/?dummy={1}' -f ($ModuleName,$Script:Random.Next(9999)))
        Write-Debug -Message ('URL for module "{0}" = "{1}".' -f ($ModuleName,$Url))

        # Create Request Url
        $Request = [System.Net.WebRequest]::Create($Url)

        # Do not allow to redirect. The result is a "MovedPermanently"
        $Request.'AllowAutoRedirect' = $false
        $Request.'Proxy' = $null

        # Try to get published version number
        Try {
            # Send the request
            $Response = $Request.GetResponse()

            # Get back the URL of the true destination page, and split off the version
            $Version = [System.Version]$($Response.GetResponseHeader('Location').Split('/')[-1])
        }
        Catch {
            # Write warning if it failed & return blank version number.
            Write-Warning -Message ($_.'Exception'.'Message')
            $Version = [System.Version]('0.0.0.0')
        }
        Finally {
            # Make sure to clean up connection
            $Response.Close()
            $Response.Dispose()
        }

        # Return Version
        return $Version
    }

    End {}
}

Earlier this function was wicked fast, now it takes several seconds to complete for each of my installed 300+ modules.

BanterBoy commented 3 years ago

Not sure if this is what you are looking for but I have always used the following in order to update my modules

Get-Module -ListAvailable | Update-Module -WhatIf*

*obviously running without whatif will actually update the module.

This will only work with Modules that have been installed from the Gallery.

Hope that helps.

o-l-a-v commented 3 years ago

@BanterBoy

I only want the version number of the latest released module returned, so that I can handle install with my own logic. Else you get loads of deprecated/ old versions left + no way of controlling what modules not to update etc.

But Update-Module -WhatIf gave me some new info on how to retrieve version info, will check that out, thanks.

VERBOSE: Checking for updates for module 'Az.Accounts'.
VERBOSE: Repository details, Name = 'PSGallery', Location = 'https://www.powershellgallery.com/api/v2'; IsTrusted = 'False'; IsRegistered = 'True'.
VERBOSE: Using the provider 'PowerShellGet' for searching packages.
VERBOSE: Using the specified source names : 'PSGallery'.
VERBOSE: Getting the provider object for the PackageManagement Provider 'NuGet'.
VERBOSE: The specified Location is 'https://www.powershellgallery.com/api/v2' and PackageManagementProvider is 'NuGet'.
VERBOSE: Searching repository 'https://www.powershellgallery.com/api/v2/FindPackagesById()?id='Az.Accounts'' for ''.
VERBOSE: Total package yield:'1' for the specified package 'Az.Accounts'.
VERBOSE: Skipping installed module Az.Accounts 1.9.4.