Modules/businessdev.ALbuild.Core/Private/Get-ALbuildLicenseCacheEntry.ps1

function Get-ALbuildLicenseCacheEntry {
    <#
    .SYNOPSIS
        Reads the persisted last-verified license entry for a tenant (used for the offline grace
        window). Returns $null when there is no cache or it cannot be read - cache problems must
        never break a license check.
 
    .PARAMETER TenantId
        Azure DevOps organization / collection id the cache is keyed by.
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param([Parameter(Mandatory)] [string] $TenantId)

    try {
        $file = Join-Path (Join-Path (Get-ALbuildConfig -Name 'BaseFolder') 'license-cache') ("$TenantId.json")
        if (-not (Test-Path -LiteralPath $file)) { return $null }
        $raw = Get-Content -LiteralPath $file -Raw -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop

        $verifiedAt = [datetime]::MinValue
        if (-not [datetime]::TryParse([string]$raw.VerifiedAt, [ref] $verifiedAt)) { return $null }
        $expiresOn = $null
        $expProp = $raw.PSObject.Properties['ExpiresOn']
        if ($expProp -and $expProp.Value) {
            $parsedExp = [datetime]::MinValue
            if ([datetime]::TryParse([string]$expProp.Value, [ref] $parsedExp)) { $expiresOn = $parsedExp }
        }

        return [PSCustomObject]@{
            Status     = [string]$raw.Status
            IsTrial    = [bool]$raw.IsTrial
            ExpiresOn  = $expiresOn
            VerifiedAt = $verifiedAt
        }
    }
    catch {
        Write-Verbose "Could not read the license cache for tenant '$TenantId': $($_.Exception.Message)"
        return $null
    }
}