src/_Connect-CciBlobStore.ps1

function _Connect-CciBlobStore {
<#
.SYNOPSIS
    Establishes an Entra (Azure RBAC) storage 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 mirrors the
    feed path: reuse a live Az session if there is one, otherwise device code.
 
    Az.Accounts/Az.Storage are installed on demand (CurrentUser, unpinned).
    Returns a storage context, or $null if it cannot be established.
#>

    [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
    }

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

    foreach ($mod in 'Az.Accounts', 'Az.Storage') {
        if (-not (Get-Module -ListAvailable -Name $mod)) {
            Write-Host "cciget: installing $mod (required for the tenant distribution store)..."
            try { Install-Module $mod -Scope CurrentUser -Force -AllowClobber -ErrorAction Stop }
            catch { Write-Warning "cciget: could not install ${mod}: $_"; return $null }
        }
    }
    Import-Module Az.Accounts -Verbose:$false -ErrorAction Stop
    Import-Module Az.Storage  -Verbose:$false -ErrorAction Stop

    if (-not (Get-AzContext)) {
        Write-Host "cciget: signing in to the tenant distribution store (device code follows)..."
        $connectParams = @{ UseDeviceAuthentication = $true; ErrorAction = 'Stop' }
        $tenantProp = $Feed.PSObject.Properties['tenantId']
        if ($tenantProp -and $tenantProp.Value) { $connectParams.Tenant = $tenantProp.Value }
        try { $null = Connect-AzAccount @connectParams }
        catch { Write-Warning "cciget: Azure sign-in failed: $_"; return $null }
    }
    else {
        Write-Verbose "cciget: reusing Az session $((Get-AzContext).Account.Id)."
    }

    try {
        $ctx = New-AzStorageContext -StorageAccountName $account -UseConnectedAccount -ErrorAction Stop
    } catch {
        Write-Warning "cciget: could not create a storage context for '$account': $_"
        return $null
    }
    $Script:CciGetBlobContext = $ctx
    $Script:CciGetBlobAccount = $account
    return $ctx
}