Private/New-SasToken.ps1

function New-SasToken {
    <#
    .SYNOPSIS
        Generates a SAS token for an Azure Storage Account via Azure CLI.
    .PARAMETER AccountName
        Name of the storage account.
    .PARAMETER Permissions
        SAS permission string (e.g. 'rl' for read-list, 'rwdlc' for read-write-delete-list-create).
    .PARAMETER ExpiryHours
        Number of hours until the SAS token expires. Default: 24.
    .OUTPUTS
        [string] The SAS token.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'New-SasToken generates a read-only token, no state change')]
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)]
        [string]$AccountName,

        [Parameter(Mandatory)]
        [string]$Permissions,

        [Parameter()]
        [int]$ExpiryHours = 24
    )

    $expiry = (Get-Date).ToUniversalTime().AddHours($ExpiryHours).ToString("yyyy-MM-dd'T'HH:mm:ss'Z'")

    Write-Host "[$(Get-Timestamp)] Generating SAS token for '$AccountName' (permissions=$Permissions, expires in ${ExpiryHours}h)..." -ForegroundColor Cyan

    $sasOutput = az storage account generate-sas `
        --account-name $AccountName `
        --permissions $Permissions `
        --services 'f' `
        --resource-types 'sco' `
        --expiry $expiry `
        -o tsv 2>&1

    if ($LASTEXITCODE -ne 0) {
        throw "Failed to generate SAS for '$AccountName': $sasOutput"
    }

    $sas = ($sasOutput | Where-Object { $_ -isnot [System.Management.Automation.ErrorRecord] }) -join ''
    return $sas
}