Public/Get-StoreLinks.ps1

function Get-StoreLinks {
    <#
    .SYNOPSIS
        Queries the store.rg-adguard.net API for Windows Store package download links.
    .DESCRIPTION
        Retrieves package metadata (download URLs, SHA1 hashes, sizes) for a given
        Windows Store app. Supports querying by URL, ProductId, PackageFamilyName,
        or CategoryID across one or all release channels.
 
        When -Channel is 'All', each channel (Retail, RP, WIS, WIF) is queried and
        results are deduplicated by URL.
    .PARAMETER Type
        The query type. One of: URL, ProductId, PackageFamilyName, CategoryID.
        Defaults to ProductId.
    .PARAMETER Data
        The query value. For example, a Microsoft Store URL or a product ID like '9NBLGGH4NNS1'.
    .PARAMETER Channel
        The release channel to query. Use 'All' to query Retail, RP, WIS, and WIF
        and combine deduplicated results. Defaults to Retail.
    .OUTPUTS
        WinStoreRip.PackageInfo - Objects with Name, URL, ExpireTime, SHA1, Size, Channel properties.
    .EXAMPLE
        Get-StoreLinks -Data '9NBLGGH4NNS1'
        Queries the Retail channel for the given product ID.
    .EXAMPLE
        Get-StoreLinks -Type URL -Data 'https://apps.microsoft.com/detail/9nblggh4nns1' -Channel All
        Queries all channels and returns deduplicated results.
    .EXAMPLE
        Get-StoreLinks -Type PackageFamilyName -Data 'Microsoft.WindowsTerminal_8wekyb3d8bbwe' -Channel RP
        Queries the Release Preview channel for Windows Terminal packages.
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param(
        [Parameter()]
        [ValidateSet('URL', 'ProductId', 'PackageFamilyName', 'CategoryID')]
        [string]$Type = 'ProductId',

        [Parameter(Mandatory, Position = 0)]
        [ValidateNotNullOrEmpty()]
        [string]$Data,

        [Parameter()]
        [ValidateSet('Retail', 'RP', 'WIS', 'WIF', 'All')]
        [string]$Channel = 'Retail'
    )

    $channels = if ($Channel -eq 'All') {
        @('Retail', 'RP', 'WIS', 'WIF')
    } else {
        @($Channel)
    }

    $seenUrls = @{}
    $results = [System.Collections.Generic.List[PSCustomObject]]::new()

    foreach ($ch in $channels) {
        Write-Verbose "Querying channel: $ch"
        try {
            $html = Invoke-StoreAPI -Type $Type -Data $Data -Channel $ch
        } catch {
            Write-Warning "Failed to query channel ${ch}: $_"
            continue
        }

        $packages = ConvertFrom-StoreHtml -Html $html -Channel $ch
        if (-not $packages) { continue }

        foreach ($pkg in $packages) {
            if (-not $seenUrls.ContainsKey($pkg.URL)) {
                $seenUrls[$pkg.URL] = $true
                $results.Add($pkg)
            } else {
                Write-Verbose "Skipping duplicate: $($pkg.Name) (already seen from another channel)"
            }
        }
    }

    Write-Verbose "Returning $($results.Count) unique package(s)."
    $results
}