Public/Test-DattoApiConnection.ps1

function Test-DattoApiConnection {
<#
.SYNOPSIS
Tests authentication and access to a selected Datto API surface.
.DESCRIPTION
Performs a minimal GET request and returns a structured result. Select the API surface that the key is expected to access because a valid key may be permission-restricted.
.PARAMETER Surface
BCDR tests /v1/bcdr/device, SaaSProtection tests /v1/saas/domains, and DirectToCloud tests /v1/dtc/assets.
.PARAMETER Path
A custom /v1/ path to test.
.PARAMETER Connection
A connection object, name, or ID.
.PARAMETER ThrowOnFailure
Rethrows the terminating API error instead of returning a failed test result.
.EXAMPLE
Test-DattoApiConnection -Surface BCDR
.EXAMPLE
Test-DattoApiConnection -Path '/v1/saas/domains' -ThrowOnFailure
.OUTPUTS
PSCustomObject
#>

    [CmdletBinding(DefaultParameterSetName = 'Surface')]
    param(
        [Parameter(ParameterSetName = 'Surface')]
        [ValidateSet('BCDR', 'SaaSProtection', 'DirectToCloud')]
        [string]$Surface = 'BCDR',

        [Parameter(Mandatory, ParameterSetName = 'Path')]
        [ValidatePattern('^/v1/')]
        [string]$Path,

        [Parameter()]
        [AllowNull()]
        [object]$Connection,

        [Parameter()]
        [switch]$ThrowOnFailure
    )

    $query = @{}
    if ($PSCmdlet.ParameterSetName -eq 'Surface') {
        switch ($Surface) {
            'BCDR' { $Path = '/v1/bcdr/device'; $query = @{ _page = 1; _perPage = 1 } }
            'SaaSProtection' { $Path = '/v1/saas/domains' }
            'DirectToCloud' { $Path = '/v1/dtc/assets'; $query = @{ _page = 1; _perPage = 1 } }
        }
    }

    $state = Resolve-DattoApiConnectionState -Connection $Connection
    $stopwatch = [Diagnostics.Stopwatch]::StartNew()
    try {
        $response = Invoke-DattoApiHttpRequest -Method GET -Path $Path -Query $query -Connection $state.Id
        $stopwatch.Stop()
        return [pscustomobject][ordered]@{
            Success        = $true
            ConnectionName = $state.Name
            Path           = $Path
            StatusCode     = $response.StatusCode
            LatencyMs      = $stopwatch.ElapsedMilliseconds
            ErrorId        = $null
            Message        = 'Authentication and endpoint access succeeded.'
        }
    }
    catch {
        $stopwatch.Stop()
        if ($ThrowOnFailure) { throw }
        $statusCode = $null
        if ($_.Exception.Data.Contains('StatusCode')) { $statusCode = $_.Exception.Data['StatusCode'] }
        return [pscustomobject][ordered]@{
            Success        = $false
            ConnectionName = $state.Name
            Path           = $Path
            StatusCode     = $statusCode
            LatencyMs      = $stopwatch.ElapsedMilliseconds
            ErrorId        = $_.FullyQualifiedErrorId
            Message        = $_.Exception.Message
        }
    }
}