src/_Connect-CciBlobStore.ps1

function _Connect-CciBlobStore {
<#
.SYNOPSIS
    Establishes an Entra-authenticated context for the tenant distribution store.
.DESCRIPTION
    Machine builders hold `Storage Blob Data Reader` on the tenant store via an
    Entra group and need no Azure DevOps entitlement.
 
    Auth order:
      1. A live Azure CLI session, if present (no prompt).
      2. Device-code sign-in over plain REST (_Get-CciEntraToken).
 
    No Az PowerShell modules are used - see _Get-CciEntraToken for why.
    Returns a context object (Account/Token/TenantId) or $null.
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]$Feed
    )

    $accountProp = $Feed.PSObject.Properties['blobAccount']
    $account = if ($accountProp) { $accountProp.Value }
    if ([string]::IsNullOrWhiteSpace($account)) {
        Write-Verbose "cciget: tenant '$($Feed.name)' has no blobAccount configured."
        return $null
    }
    # Read through PSObject.Properties throughout: the module loads under
    # Set-StrictMode -Version Latest, where touching an absent property throws.
    $tenantProp = $Feed.PSObject.Properties['tenantId']
    $tenantId = if ($tenantProp) { $tenantProp.Value }

    if ($Script:CciGetBlobContext -and $Script:CciGetBlobContext.Account -eq $account) {
        return $Script:CciGetBlobContext
    }

    $token = $null

    # 1. existing Azure CLI session
    if (Get-Command az -ErrorAction SilentlyContinue) {
        try {
            $token = az account get-access-token --resource 'https://storage.azure.com' --query accessToken -o tsv 2>$null
            if ($token) { Write-Verbose 'cciget: storage token from the Azure CLI session.' }
        } catch { }
    }

    # 2. device code over REST
    if (-not $token) {
        if (-not $tenantId) {
            Write-Warning "cciget: tenant '$($Feed.name)' has no tenantId; cannot sign in to the distribution store."
            return $null
        }
        $clientProp = $Feed.PSObject.Properties['clientId']
        $clientId = if ($clientProp -and $clientProp.Value) { $clientProp.Value } else { '04b07795-8ddb-461a-bbee-02f9e1bf7b46' }

        Write-Host 'cciget: signing in to the tenant distribution store...'
        $token = _Get-CciEntraToken -TenantId $tenantId -Scope 'https://storage.azure.com/.default' -ClientId $clientId
        if (-not $token) { return $null }
    }

    $ctx = [pscustomobject]@{
        Account  = $account
        Token    = $token
        TenantId = $tenantId
    }
    $Script:CciGetBlobContext = $ctx
    return $ctx
}