---
title: Get function configuration from deployed Function App
date: 2020-12-02 21:30:00 +0200 +0200
draft: false
author: John Roos
----

When you deploy an Azure Function app you also deploy the configuration for each function within the app. What if you would like to inspect the configuration of a function within a function app? If the function is using a timerTrigger, you might want to be able to look at that schedule for example. That would be easy to do using the Azure Portal, but what if you need to do it using PowerShell? In this post I will show you how to do just that.

Find the configuration

When viewing the function app in the Azure Portal, you have the option to open Kudu. Kudu can be reached by clicking on Advanced tools under Development tools in the menu. On the start page for Kudu you will find a link to list all Functions.

Kudu

Click the link and you should see something like this:

[
    {
        "name": "myfunction",
        "function_app_id": null,
        "script_root_path_href": "https://myfunctionapp.scm.azurewebsites.net/api/vfs/site/wwwroot/myfunction/",
        "script_href": "https://myfunctionapp.scm.azurewebsites.net/api/vfs/site/wwwroot/myfunction/myfunction.ps1",
        "config_href": "https://myfunctionapp.scm.azurewebsites.net/api/vfs/site/wwwroot/myfunction/function.json",
        "secrets_file_href": "https://myfunctionapp.scm.azurewebsites.net/api/vfs/data/functions/secrets/myfunction.json",
        "href": "https://myfunctionapp.scm.azurewebsites.net/api/functions/myfunction",
        "config": {
            "scriptFile": "myfunction.ps1",
            "bindings": [
                 {
                    "name": "Timer",
                    "type": "timerTrigger",
                    "direction": "in",
                    "schedule": "0 1 * * * *"
                }
            ]
        },
        "files": null,
        "test_data": ""
    }
]

In the JSON we can see that we have the bindings among other things. Now we just need to invoke this endpoint and get the information we need, right?

Get the credentials

Unfortunately, its not that straightforward. The Kudu API is not reachable with the same account as the account you normally use when scripting in Azure. Kudu requires you to use the same account which is used when publishing the app. These credentials are created automatically in the background and, in most cases, you don’t have to think about it.

So the first thing we need to do is to get the publishing credentials. These credentials can be found using the Azure Resource Explorer, but to save time, here is the command that is needed:

$resourceActionParameters = @{
    ResourceGroupName = 'myresourcegroup'
    ResourceType      = 'Microsoft.Web/sites/config'
    ResourceName      = 'myfunctionapp/publishingcredentials'
    Action            = 'list'
    ApiVersion        = '2020-06-01'
}
$KuduCredentials = Invoke-AzResourceAction @resourceActionParameters -Force

Make sure you are connected to Azure before running this command. The command will return a result where we have the username and password in the property called properties:

id         : /subscriptions/d5d4f110-b7dc-4e21-a1a0-67c5098a91e5/resourceGroups/myresourcegroup/providers/Microsoft.Web/sites/myfunctionapp/publishingcredentials/$myfunctionapp
name       : myfunctionapp
type       : Microsoft.Web/sites/publishingcredentials
location   : North Europe
properties : @{
    name=;
    publishingUserName=$myfunctionapp;
    publishingPassword=zjlDtWlputfTzjxsVvn8ilsQCHylGXWiTTEdd6bZvtYqjsnojjrWjSh3eMzQ;
    publishingPasswordHash=;
    publishingPasswordHashSalt=;
    metadata=;
    isDeleted=False;
    scmUri=https://$myfunctionapp:zjlDtWlputfTzjxsVvn8ilsQCHylGXWiTTEdd6bZvtYqjsnojjrWjSh3eMzQ@myfunctionapp.scm.azurewebsites.net
}

Create the authorization header

The Kudu API requires you to use basic authentication. This is fairly straight forward. First we need to put the username and password into a string, separated by a colon. Then we need to convert the string to an array of bytes. Finally, we convert the byte array to a base64 string. Add the result to the authorization header.

$Username = $KuduCredentials.Properties.PublishingUserName
$Password = $KuduCredentials.Properties.PublishingPassword

$stringKuduCredentials = "$Username:$Password"
$BytesKuduCredentials  = [Text.Encoding]::ASCII.GetBytes($stringKuduCredentials)
$Base64KuduCredentials = [Convert]::ToBase64String($BytesKuduCredentials)

$Headers = @{
    Authorization = "Basic $Base64KuduCredentials"
}

Invoke and inspect

Now invoke the endpoint using the header.

Invoke-RestMethod -Method 'Get' -Uri "https://myfunctionappname.scm.azurewebsites.net/api/functions" -Headers $Headers

This will return one object per function inside your function app. Each object should look similar to this:

name                  : myfunction
function_app_id       :
script_root_path_href : https://fa-functionlab2.scm.azurewebsites.net/api/vfs/site/wwwroot/myfunction/
script_href           : https://fa-functionlab2.scm.azurewebsites.net/api/vfs/site/wwwroot/myfunction/run.ps1
config_href           : https://fa-functionlab2.scm.azurewebsites.net/api/vfs/site/wwwroot/myfunction/function.json 
secrets_file_href     : https://fa-functionlab2.scm.azurewebsites.net/api/vfs/data/functions/secrets/myfunction.json
href                  : https://fa-functionlab2.scm.azurewebsites.net/api/functions/myfunction
config                : @{bindings=System.Object[]}
files                 :
test_data             :

If we inspect the config property you will find a bindings property, which contains the following:

name  type         direction schedule
----  ----         --------- --------
Timer timerTrigger in        0 */5 * * * *

There we have it! An easy way to get the configuration for each function inside a function app.

Summary

To get the configuration of a function inside a Function App you need to use the Kudu API. The trick to use the Kudu API is to find the publishing credentials. Below you can find this whole solution as a Cmdlet.

function Get-AzureFunctionAppFunction {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$ResourceGroupName,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$FunctionName
    )
    Process {
        $resourceActionParameters = @{
            ResourceGroupName = $ResourceGroupName
            ResourceType      = 'Microsoft.Web/sites/config'
            ResourceName      = "$FunctionName/publishingcredentials"
            Action            = 'list'
            ApiVersion        = '2020-06-01'
        }
        $KuduCredentials       = Invoke-AzResourceAction @resourceActionParameters -Force

        $Username = $KuduCredentials.Properties.PublishingUserName
        $Password = $KuduCredentials.Properties.PublishingPassword

        $stringKuduCredentials = "$Username:$Password"
        $BytesKuduCredentials  = [Text.Encoding]::ASCII.GetBytes($stringKuduCredentials)
        $Base64KuduCredentials = [Convert]::ToBase64String($BytesKuduCredentials)

        $Headers = @{
            Authorization = "Basic $Base64KuduCredentials"
        }

        Invoke-RestMethod -Method 'Get' -Uri "https://$FunctionName.scm.azurewebsites.net/api/functions" -Headers $Headers
    }
}

I hope you find this post useful. For me this opened up a whole range of possibilities which I might write about in the future.