Public/Get-PdqLatestVersion.ps1

<#
.SYNOPSIS
Asks a PDQ API what the latest version number is.
 
.NOTES
The API returns multiple fields, not just the version number.
 
.INPUTS
None.
 
.OUTPUTS
System.Management.Automation.PSCustomObject
 
.EXAMPLE
Get-PdqLatestVersion -ReleaseType 'Nightly'
Retrieves the version number for the latest Nightly build.
#>

function Get-PdqLatestVersion {

    [CmdletBinding()]
    param (
        [ValidateSet('Deploy', 'Inventory')]
        # The PDQ application you would like to execute this function against.
        # Deploy and Inventory have been released simultaneously since 18.1.0.0, so you should never need to use this.
        [String]$Product = 'Deploy',
        
        [ValidateSet('Beta', 'Nightly', 'Release')]
        # The build type you would like to check.
        # https://www.pdq.com/build-types/
        [String]$ReleaseType = 'Release',

        # The version number you would like to tell the API that you have installed.
        # Occasionally there are breaking changes that require updating to one version before another.
        # The API is aware of these and will give you the newest version that is safe to update to.
        [String]$InstalledVersion = '999.0.0.0'
    )

    # I used mitmproxy to see how Deploy and Inventory check for updates.
    # It's relatively simple. The only weird part is having to build a block of JSON for the Body.
    $Params = @{
        'Method'      = 'Post'
        'Uri'         = 'https://services.pdq.tools/function/update-info'
        'Body'        = @{
            'InstalledVersion' = $InstalledVersion
            'Product'          = $Product
            'ReleaseType'      = $ReleaseType
        } | ConvertTo-Json
        'ContentType' = 'application/json'
        'ErrorAction' = 'Stop'
    }
    
    $Result = Invoke-RestMethod @Params

    # Make sure the API returned good data.
    $ErrorMessages = switch ( $Result ) {
        { $_.releaseType -ne $ReleaseType } {
            "releaseType did not match the expected value of: $ReleaseType"
        }
        { -not $_.version } {
            'version is null'
        }
        { $_.version -notmatch '\d+\.\d+\.\d+\.\d+' } {
            'version did not match the pattern a.b.c.d'
        }
    }

    # Make the buildDate human readable. https://gitlab.com/ColbyBouma/pdqstuff/-/issues/73
    $Result.buildDate = ([DateTime]$Result.buildDate).ToString('yyyy-MM-dd HH:mm:ss')

    if ( $ErrorMessages ) {

        foreach ( $ErrorMessage in $ErrorMessages ) {

            Write-Error $ErrorMessage

        }

        # Log the API output to Verbose.
        $Result | Out-String | Write-Verbose

    } else {

        $Result

    }

}