3

There aren't any cmdlets in the AZ modules to get key-value pairs from Azure app configuration. Are there any other options besides AZ CLI? Is there a way to interact with service from PowerShell?

joshduffney
  • 389
  • 1
  • 4
  • 16

5 Answers5

6

There is no PowerShell support to get key-values from App Configuration at this point. Calling Azure CLI in PowerShell is the way to go. The Az.AppConfiguration module only supports management operations (eg., creating an App Configuration store, etc).

The request is tracked in GitHub https://github.com/Azure/AppConfiguration/issues/267.

Zhenlan Wang
  • 1,213
  • 8
  • 10
1

Hey I'm a bit late to the party but I was searching for the same thing and I ended up created my own solution because the given answer only covers management tasks and not data retrieval.

check out this repo

It can fetch key values and resolve secrets.

Also it can parse referenced keys in the values.

it uses az cli in the background, so you need that installed first.

michiel Thai
  • 547
  • 5
  • 16
1

Here's my solution using App Configuration connection string for authentication. You're interested in .items property from the returned object. In case of paging, there'll be a next link there as well. For details, see the docs at https://learn.microsoft.com/azure/azure-app-configuration/rest-api-key-value

Keys can contain slash characters, so they need to be URL-encoded using [System.Net.WebUtility]::UrlEncode($Key) when building a $RequestUri.

function Invoke-AppConfigRequest {
    param(
        [Parameter(Mandatory = $true)] [string] $ConnectionString,  # 'Endpoint=...;Id=...;Secret=...'
        [Parameter(Mandatory = $true)] [string] $RequestUri,        # '/kv?api-version=1.0&key=some-url-encoded-key&label=*'
        [Parameter(Mandatory = $false)] [string] $Method = 'GET',   # 'GET', 'POST'
        [Parameter(Mandatory = $false)] [object] $Body = $null      # Accepts [object] to avoid implicit conversion of $null to empty string
    )

    $ConnectionStringValues = $ConnectionString -split ';' | ForEach-Object { $Tokens = $_ -split '=',2; @{ Key = $Tokens[0]; Value = $Tokens[1] } }
    $Endpoint = ($ConnectionStringValues | Where-Object { $_.Key -eq 'Endpoint' }).Value
    $Credential = ($ConnectionStringValues | Where-Object { $_.Key -eq 'Id' }).Value
    $Secret = ($ConnectionStringValues | Where-Object { $_.Key -eq 'Secret' }).Value
    if ([string]::IsNullOrWhitespace($Endpoint) -or [string]::IsNullOrWhitespace($Credential) -or [string]::IsNullOrWhitespace($Secret)) {
        throw "Invalid App Configuration connection string"
    }

    $UtcNow = (Get-Date).ToUniversalTime().ToString('ddd, d MMM yyyy HH:mm:ss \G\M\T')
    $EndpointHost = $Endpoint -replace '^https?://(.*)$','$1'
    $ContentHash = [Convert]::ToBase64String(
        [System.Security.Cryptography.HashAlgorithm]::Create('sha256').ComputeHash(
            [System.Text.Encoding]::UTF8.GetBytes($(if ($Body -ne $null) { "$Body" } else { '' }))
        )
    )
    $StringToSign = "$Method`n$RequestUri`n$UtcNow;$EndpointHost;$ContentHash"

    $HmacSha256 = New-Object System.Security.Cryptography.HMACSHA256
    $HmacSha256.Key = [Convert]::FromBase64String($Secret)
    $Signature = [Convert]::ToBase64String(
        $HmacSha256.ComputeHash(
            [System.Text.Encoding]::UTF8.GetBytes($StringToSign)
        )
    )

    $Headers = @{
        'Host' = $EndpointHost;
        'x-ms-date' =  $UtcNow;
        'x-ms-content-sha256' = $ContentHash;
        'Accept' = 'application/vnd.microsoft.appconfig.kv+json, application/json, application/problem+json';
        'Authorization' = "HMAC-SHA256 Credential=$Credential&SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature=$Signature";
    }

    $Uri = "$Endpoint$RequestUri"
    $Response = Invoke-WebRequest -Method $Method -Uri $Uri -Headers $Headers -Body $Body
    if ($Response.StatusCode -eq 200) {
        [System.Text.Encoding]::UTF8.GetString($Response.Content) | ConvertFrom-Json
    }
}

Example invocation:

function Get-AppConfigKeyValue {
    param(
        [Parameter(Mandatory = $true)] [string] $ConnectionString,
        [Parameter(Mandatory = $true)] [string] $Key,
        [Parameter(Mandatory = $false)] [string] $Label = ''
    )

    $UrlEncodedKey = [System.Net.WebUtility]::UrlEncode($Key)
    $UrlEncodedLabel = [System.Net.WebUtility]::UrlEncode($Label)

    # https://learn.microsoft.com/azure/azure-app-configuration/rest-api-key-value
    $Method = 'GET'
    $ApiVersion = '1.0'
    $RequestUri = '/kv'
    #if (![string]::IsNullOrWhitespace($UrlEncodedKey)) {
    #    $RequestUri += "/$UrlEncodedKey"  # Strict key/label matching, no support for wildcards like *.
    #}
    $RequestUri += "?api-version=$ApiVersion"
    if (![string]::IsNullOrWhitespace($UrlEncodedKey)) {
        $RequestUri += "&key=$UrlEncodedKey"  # Key filter, accepts "*" to match all keys.
    }
    if (![string]::IsNullOrWhitespace($UrlEncodedLabel)) {
        $RequestUri += "&label=$UrlEncodedLabel"  # Label filter, accepts "*" to match all labels.
    } else {
        $RequestUri += "&label=%00"  # Matches KV without a label.
    }

    (Invoke-AppConfigRequest -ConnectionString $ConnectionString -RequestUri $RequestUri).items
}
xorcus
  • 999
  • 1
  • 11
  • 12
0

Azure CLI has a command az appconfig kv list that can be used to list all key-values from App Configuration. More details on the usage and examples can be found here.

Abhilash Arora
  • 277
  • 2
  • 4
  • 2
    It is supported in az cli yes, but the OP was specifically asking about a PowerShell module for App Configuration. – Brandon Olin Jul 14 '20 at 00:16
-4

Take a look at the Az.AppConfiguration module. I can't vouch for the quality of it or how complete it is, but it's out there. The Az module doesn't look like it is included as a dependency.

You can download is from the PowerShell Gallery with:

Install-Module -Name Az.AppConfiguration -Repository PSGallery -Scope CurrentUser
Brandon Olin
  • 322
  • 3
  • 11