Public/New-AzTableAPIContext.ps1

function New-AzTableAPIContext {
    <#
    .SYNOPSIS
        Creates an Azure Table Storage connection context used by all other module commands.

    .DESCRIPTION
        Supports three authentication methods:
        - SharedKey : Storage account name + account access key (HMAC-SHA256).
        - AccessToken : Bearer token obtained externally (e.g. via Get-AzAccessToken or the Azure CLI).
        - SasToken : Shared Access Signature appended to every request URL.

        Optionally provide a custom -Endpoint for Azurite or sovereign clouds.

    .PARAMETER StorageAccountName
        Name of the Azure Storage account.

    .PARAMETER StorageAccountKey
        Base64-encoded storage account access key (SharedKey authentication).

    .PARAMETER AccessToken
        Bearer access token for Azure Storage (scope: https://storage.azure.com/).
        Obtain it externally, for example:
          $token = (Get-AzAccessToken -ResourceUrl 'https://storage.azure.com/').Token
          $token = (az account get-access-token --resource https://storage.azure.com/ | ConvertFrom-Json).accessToken

    .PARAMETER SasToken
        Shared Access Signature token. May start with '?' or without.

    .PARAMETER Endpoint
        Override the default table storage endpoint (e.g. for Azurite).
        Defaults to https://<StorageAccountName>.table.core.windows.net.

    .OUTPUTS
        [PSCustomObject] context object consumed by all AzTableAPI commands.

    .EXAMPLE
        $ctx = New-AzTableAPIContext -StorageAccountName 'myaccount' -StorageAccountKey 'base64key=='

    .EXAMPLE
        $token = (Get-AzAccessToken -ResourceUrl 'https://storage.azure.com/').Token
        $ctx = New-AzTableAPIContext -StorageAccountName 'myaccount' -AccessToken $token

    .EXAMPLE
        $ctx = New-AzTableAPIContext -StorageAccountName 'myaccount' -SasToken '?sv=2020-08-04&...'

    .EXAMPLE
        # Azurite local emulator
        $ctx = New-AzTableAPIContext -StorageAccountName 'devstoreaccount1' `
               -StorageAccountKey 'Eby8vdM02xNOcqFlqUwJPLlmEtlCD...' `
               -Endpoint 'http://127.0.0.1:10002/devstoreaccount1'
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'New-AzTableAPIContext creates a local context object with no external side effects.')]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '',
        Justification = 'The key is supplied as plain text by the caller; SecureString reduces exposure in memory dumps and serialization.')]
    [CmdletBinding()]
    [OutputType([PSCustomObject])]
    param (
        [Parameter(Mandatory, ParameterSetName = 'SharedKey')]
        [Parameter(Mandatory, ParameterSetName = 'AccessToken')]
        [Parameter(Mandatory, ParameterSetName = 'SasToken')]
        [ValidateNotNullOrEmpty()]
        [string]$StorageAccountName,

        [Parameter(Mandatory, ParameterSetName = 'SharedKey')]
        [ValidateNotNullOrEmpty()]
        [string]$StorageAccountKey,

        [Parameter(Mandatory, ParameterSetName = 'AccessToken')]
        [ValidateNotNullOrEmpty()]
        [string]$AccessToken,

        [Parameter(Mandatory, ParameterSetName = 'SasToken')]
        [ValidateNotNullOrEmpty()]
        [string]$SasToken,

        [Parameter(ParameterSetName = 'SharedKey')]
        [Parameter(ParameterSetName = 'AccessToken')]
        [Parameter(ParameterSetName = 'SasToken')]
        [string]$Endpoint
    )

    if ([string]::IsNullOrWhiteSpace($Endpoint)) {
        $Endpoint = "https://$StorageAccountName.table.core.windows.net"
    }

    $context = [PSCustomObject]@{
        StorageAccountName = $StorageAccountName
        Endpoint           = $Endpoint.TrimEnd('/')
        AuthType           = $PSCmdlet.ParameterSetName
    }

    switch ($PSCmdlet.ParameterSetName) {
        'SharedKey' {
            $secureKey = ConvertTo-SecureString -String $StorageAccountKey -AsPlainText -Force
            $context | Add-Member -NotePropertyName StorageAccountKey -NotePropertyValue $secureKey
        }
        'AccessToken' {
            $context | Add-Member -NotePropertyName AccessToken -NotePropertyValue $AccessToken
        }
        'SasToken' {
            $normalizedSas = if ($SasToken.StartsWith('?')) { $SasToken } else { "?$SasToken" }
            $context | Add-Member -NotePropertyName SasToken -NotePropertyValue $normalizedSas
        }
    }

    return $context
}