43

I want to write a script that run using azure power shell to automate adding the Web Application configuration

Azure > MyWebApp > Application Settings > App settings

It's look like key = "value"

I write this script

###########################
# MyApp Config Automation #
###########################

#Begin

$subscriptionName="MySubscriptionName"
$webSiteName="MyWebAppName"
$storageAccountName="StorageAccountName"
########################################
$userName = "myaccount@outlook.com"
$securePassword = ConvertTo-SecureString -String "mypass" -AsPlainText -Force
#####################################
$cred = New-Object System.Management.Automation.PSCredential($userName, $securePassword)
#####################################
Add-AzureAccount -Credential $cred 
Select-AzureSubscription -SubscriptionName $subscriptionName -Default
#####################################
Get-AzureWebsite -Name $webSiteName

#End

but i know that the above script is only get my web application, now i need to access MyWebApp > Application Settings > App settings and give the script file/array of my new App settings and the script check if there are any new App Settings key it will add it to App Settings, if there are any existing keys it will override it's value. What is the steps or APIS or can i do that with azure power shell?

Edit: This script can Automate creating new web application and adding App Settings to it:

##############################################
# Creating website and Adding Configs Script #
##############################################

$webSiteName="mywebsite"
$storageAccountName="storageaccount"
$subscriptionName="mysubsc"
$userName = "myaccount"
$securePassword = ConvertTo-SecureString -String "mypass" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($userName, $securePassword)
Add-AzureAccount -Credential $cred 
Select-AzureSubscription -SubscriptionName $subscriptionName -Default

New-AzureWebsite -Name $webSiteName
New-AzureStorageAccount –StorageAccountName $storageAccountName -Location "South Central US"
$ClientId="dfgdf6"
$Password="ffefe"
$StorageAccountKey = Get-AzureStorageKey -StorageAccountName $storageAccountName
$AppSettings = @{"StorageAccountPrimary" = $StorageAccountKey.Primary;"StorageAccountSecondary" = $StorageAccountKey.Secondary;"ida:ClientId"=$ClientId;"ida:Password"=$Password}

Set-AzureWebsite -Name $webSiteName -AppSettings $AppSettings
Marzouk
  • 2,650
  • 3
  • 25
  • 56

4 Answers4

92

Here's an update to it based on the 12/2015 Azure PowerShell commands. The example is for slot-specific settings, if you want global, use Get/Set-AzureRmWebApp and remove the -slot parameter.

$myResourceGroup = 'PartsUnlimitedMRP'
$mySite = 'centpartsunlimited'

$webApp = Get-AzureRMWebAppSlot -ResourceGroupName $myResourceGroup -Name $mySite -Slot production
$appSettingList = $webApp.SiteConfig.AppSettings

$hash = @{}
ForEach ($kvp in $appSettingList) {
    $hash[$kvp.Name] = $kvp.Value
}

$hash['NewKey'] = "NewValue"
$hash['ExistingKey'] = "NewValue"

Set-AzureRMWebAppSlot -ResourceGroupName $myResourceGroup -Name $mySite -AppSettings $hash -Slot production
Dan Piessens
  • 936
  • 7
  • 2
  • 2
    This is the better answer with the release of the 12/2015 Azure PowerShell commands. – Andy Mehalick Mar 20 '16 at 13:58
  • I had to run this code snippet, using both Set-AzureRMWebApp and Set-AzureRMWebAppSlot otherwise, if I only ran Set-AzureRMWebApp, the non-slot specific settings in the staging slot were not updated. Unless I missed something... – MartynJones87 Jun 02 '16 at 14:21
  • Also worth noting that if you run this as a step in an azure pipeline you need ```Enable-AzureRmAlias``` before you can use Set-AzureRMWebAppSlot – Serban Murariu Mar 17 '20 at 14:21
14

Retrieve App Settings

First set these two variables.

$myResourceGroup = 'RESOURCE_GROUP_NAME'
$mySite = 'SITE_NAME'

Then switch to the new Resource Manager mode and sign-in to your account.

Switch-AzureMode AzureResourceManager
Get-AzureAccount

Then retrieve the app settings. (Note that a back tick (`) means a new line.)

(Invoke-AzureResourceAction -ResourceGroupName $myResourceGroup `
 -ResourceType Microsoft.Web/sites/Config -Name $mySite/appsettings `
 -Action list -ApiVersion 2015-08-01 -Force).Properties

Add/Update App Settings

To update settings, first put them into a variable.

$props = (Invoke-AzureResourceAction -ResourceGroupName $myResourceGroup `
 -ResourceType Microsoft.Web/sites/Config -Name $mySite/appsettings `
 -Action list -ApiVersion 2015-08-01 -Force).Properties

To use Set-AzureWebsite convert the variable to a hash table.

 $hash = @{}
 $props | Get-Member -MemberType NoteProperty | % { $hash[$_.Name] = $props.($_.Name) }

Now add/update values in the hash table.

$hash.NewKey = "NewValue"
$hash.ExistingKey = "NewValue"

Then switch back to Service Management mode and commit the settings.

Switch-AzureMode AzureServiceManagement
Set-AzureWebsite -Name $mySite -AppSettings $hash

Complete Code Listing

$myResourceGroup = 'RESOURCE_GROUP_NAME'
$mySite = 'SITE_NAME'

Switch-AzureMode AzureResourceManager
Get-AzureAccount

(Invoke-AzureResourceAction -ResourceGroupName $myResourceGroup `
 -ResourceType Microsoft.Web/sites/Config -Name $mySite/appsettings `
 -Action list -ApiVersion 2015-08-01 -Force).Properties

$props = (Invoke-AzureResourceAction -ResourceGroupName $myResourceGroup `
 -ResourceType Microsoft.Web/sites/Config -Name $mySite/appsettings `
 -Action list -ApiVersion 2015-08-01 -Force).Properties

 $hash = @{}
 $props | Get-Member -MemberType NoteProperty | % { $hash[$_.Name] = $props.($_.Name) }

$hash.NewKey = "NewValue"
$hash.ExistingKey = "NewValue"

Switch-AzureMode AzureServiceManagement
Set-AzureWebsite -Name $mySite -AppSettings $hash

Notes

The AzureServiceManagement and AzureResourceManager are not meant for use in the same session. For now the latter does not seem to permit updating the app settings via Set-AzureResource. The above is a workaround. Another way is to use the Azure CLI instead of PowerShell.

Shaun Luttin
  • 133,272
  • 81
  • 405
  • 467
12

These answers are showing their age as both the original Azure PowerShell and AzureRM are deprecated. To do this using the Az PowerShell module it would look like this:

Example

Connect-AzAccount
$site = Get-AzWebApp -Name foo-com-dev-as
$oldSettings = ($site.SiteConfig.AppSettings | % { $h = @{} } { $h[$_.Name] = $_.Value } { $h })

$newSettings = @{ StorageAccountPrimary = $StorageAccountKey.Primary
                  StorageAccountSecondary = $StorageAccountKey.Secondary
                  "ida:ClientId" = $ClientId
                  "ida:Password" = $Password }

Set-AzWebApp -ResourceGroupName foo-com-dev-rg -Name foo-com-dev-as -AppSettings ($oldSettings + $newSettings)

Explanation

  1. Connection-AzAccount - connects to the Azure account, you may need to perform a subsequent step if you need to select a subscription
  2. $site = Get-AzWebApp... - retrieves the site to be modified
  3. $oldSettings... - gets all of the existing settings and puts them into a HashTable
    1. $site.SiteConfig.AppSettings | % - Pipes (passes) each setting via a shorthand alias of ForEach-Object
    2. { $h = @{} } - creates a HashTable via the -Begin positional parameter
    3. { $h[$_.Name] = $_Value } - adds a named value to the HashTable for each value in $site.SiteConfig.AppSettings via the -Process positional parameter
    4. { $h } - returns the newly populated HashTable via the -End positional parameter to the variable to the left
  4. $newSettings = @{... - creates a HashTable of the settings to add
  5. Set-AzWebApp... - combines the two HashTables and replaces the existing AppSettings with the combined set. Note that this assumes that you have no duplicates between the old and new settings. If that situation applies to you, you'll need dedupe in a way that makes sense for you i.e., overwrite/no overwrite.
Robb Vandaveer
  • 1,481
  • 20
  • 25
1

2023 Update

Here's a utility function that is similar to @robb-vandaveer's but will overwrite new settings with old if the keys overlap. You can get the reverse behavior by just swapping the order of the foreach statements.

Note, it assumes you are already connected to Azure

function Update-WebAppSettings {
    Param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$ResourceGroupName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$AppName,
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [hashtable]$AdditionalAppSettings
    )

    #common parameters to target the app in the resource group
    $WebAppSelection = @{
        ResourceGroupName = $ResourceGroupName
        Name              = $AppName
    }

    # hashtable where we will build up the complete merged set of app settings
    $NewAppSettings = @{}

    # get the old settings
    $CurrentAppSettingList = $(Get-AzWebApp @WebAppSelection).SiteConfig.AppSettings

    # they are in list format, so iterate through and add 
    # them to the hashtable we are building
    foreach ($Setting in $CurrentAppSettingList) {
        $NewAppSettings[$Setting.Name] = $Setting.Value
    }

    # iterate through the new settings hashtable and add them to the one we are building
    # NB: if new settings have the same keys as old settings it will overwrite them (this 
    # is different behavior than if you merge the two hashtables with the '+' operator)
    foreach ($Key in $AdditionalAppSettings.Keys) {
        $NewAppSettings[$Key] = $AdditionalAppSettings[$Key]
    }

    $WebAppSettings = @{
        AppSettings       = $NewAppSettings
    }

    Set-AzWebApp @WebAppSelection @WebAppSettings
}

At the call site just do:

$AdditionalAppSettings = @{
    someSetting = "someValue"
    someOtherSetting = "someOtherValue"
}
Update-WebAppSettings -ResourceGroupName my-resource-group -AppName myWebServicesApp -AdditionalAppSettings @AdditionalAppSettings
sam256
  • 1,291
  • 5
  • 29