Public/Get-MSCatalogUpdate.ps1

function Get-MSCatalogUpdate {
    <#
        .SYNOPSIS
        Query catalog.update.micrsosoft.com for available updates.

        .DESCRIPTION
        TBC

        .PARAMETER Search
        Specify a string to search for.

        .PARAMETER AllPages
        By default this command returns the first page of results from catalog.update.micrsosoft.com, which is
        the latest 25 updates matching the search term. If you specify this switch the command will instead
        return all pages of results. This can result in a significant increase in the number of HTTP requests
        to the catalog.update.micrsosoft.com endpoint.

        .PARAMETER Architecture
        Specify the architecture to search for e.g. "64-Bit" or "32-Bit".

        .EXAMPLE
        Get-MSCatalogUpdate -Search "Office 2013"

        .EXAMPLE
        Get-MSCatalogUpdate -Search "Office 2013" -AllPages

        .EXAMPLE
        Get-MSCatalogUpdate -Search "Office 2013" -Architecture "64-Bit"
    #>

    
    [CmdLetBinding()]
    param (
        [Parameter(
            Mandatory = $true,
            Position = 0
        )]
        [String] $Search,

        [Parameter(
            Mandatory = $false,
            Position = 1
        )]
        [Switch] $AllPages,

        [Parameter(
            Mandatory = $false,
            Position = 2
        )]
        [ValidateSet("64-Bit", "32-Bit")]
        [String] $Architecture,

        [Parameter(DontShow)]
        [String] $Method = "Get",

        [Parameter(DontShow)]
        [String] $EventArgument,

        [Parameter(DontShow)]
        [String] $EventTarget,

        [Parameter(DontShow)]
        [String] $EventValidation,

        [Parameter(DontShow)]
        [String] $ViewState,

        [Parameter(DontShow)]
        [String] $ViewStateGenerator
    )

    if ($Method -eq "Post") {
        $ReqBody = @{
            "__EVENTARGUMENT" = $EventArgument
            "__EVENTTARGET" = $EventTarget
            "__EVENTVALIDATION" = $EventValidation
            "__VIEWSTATE" = $ViewState
            "__VIEWSTATEGENERATOR" = $ViewStateGenerator
        }
    }
    $UriSearch = [Uri]::EscapeUriString($Search)
    $Params = @{
        Uri = "https://www.catalog.update.microsoft.com/Search.aspx?q=$UriSearch"
        Method = $Method
        Body = $ReqBody
        ContentType = "application/x-www-form-urlencoded"
        UseBasicParsing = $true
    }
    $Results = Invoke-WebRequest @Params

    $HtmlDoc = [HtmlAgilityPack.HtmlDocument]::new()
    $HtmlDoc.LoadHtml($Results.RawContent.ToString())
    $NextPage = $HtmlDoc.GetElementbyId("ctl00_catalogBody_nextPage")
    $EventArgument = $HtmlDoc.GetElementbyId("__EVENTARGUMENT")[0].Attributes["value"].Value
    $EventValidation = $HtmlDoc.GetElementbyId("__EVENTVALIDATION")[0].Attributes["value"].Value
    $ViewState = $HtmlDoc.GetElementbyId("__VIEWSTATE")[0].Attributes["value"].Value
    $ViewStateGenerator = $HtmlDoc.GetElementbyId("__VIEWSTATEGENERATOR")[0].Attributes["value"].Value
    $Table = $HtmlDoc.GetElementbyId("ctl00_catalogBody_updateMatches")
    $Rows = $Table.SelectNodes("tr")

    foreach ($Row in $Rows[1..($Rows.Count - 1)]) {
        $Cells = $Row.SelectNodes("td")
        if ($Architecture) {
            if ($Cells[1].innerText.Trim() -match $Architecture) {
                [PSCustomObject] @{
                    PSTypeName = "MSCatalogUpdate"
                    Title = $Cells[1].innerText.Trim()
                    Products = $Cells[2].innerText.Trim()
                    Classification = $Cells[3].innerText.Trim()
                    LastUpdated = ([DateTime] $Cells[4].innerText.Trim()).ToString("yyyy/MM/dd")
                    Version = $Cells[5].innerText.Trim()
                    Size = $Cells[6].SelectNodes("span")[0].InnerText
                    SizeInBytes = [Int] $Cells[6].SelectNodes("span")[1].InnerText 
                    Guid = $Cells[7].SelectNodes("input")[0].Id
                }
            }
        } else {
            [PSCustomObject] @{
                PSTypeName = "MSCatalogUpdate"
                Title = $Cells[1].innerText.Trim()
                Products = $Cells[2].innerText.Trim()
                Classification = $Cells[3].innerText.Trim()
                LastUpdated = ([DateTime] $Cells[4].innerText.Trim()).ToString("yyyy/MM/dd")
                Version = $Cells[5].innerText.Trim()
                Size = $Cells[6].SelectNodes("span")[0].InnerText
                SizeInBytes = [Int] $Cells[6].SelectNodes("span")[1].InnerText 
                Guid = $Cells[7].SelectNodes("input")[0].Id
            }
        }
    }

    # If $NextPage is $null then there are more pages to collect.
    if (!$NextPage) {
        $NextParams = @{
            Search = $Search
            EventArgument = $EventArgument
            EventTarget = 'ctl00$catalogBody$nextPageLinkText'
            EventValidation = $EventValidation
            ViewState = $ViewState
            ViewStateGenerator = $ViewStateGenerator
            Method = "Post"
        }
        if ($Architecture) {
            $NextParams.Architecture = $Architecture
        }
        if ($AllPages) {
            $NextParams.AllPages = $true
            Get-MSCatalogUpdate @NextParams
        }
    }
}