-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Expand file tree
/
Copy pathUpdate-CIPPAzFunctionAppSetting.ps1
More file actions
99 lines (90 loc) · 4.36 KB
/
Copy pathUpdate-CIPPAzFunctionAppSetting.ps1
File metadata and controls
99 lines (90 loc) · 4.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
function Update-CIPPAzFunctionAppSetting {
<#
.SYNOPSIS
Updates Azure Function App application settings via ARM REST using managed identity.
.PARAMETER Name
Function App name.
.PARAMETER ResourceGroupName
Resource group name.
.PARAMETER AppSetting
Hashtable of settings to set (key/value). Values should be strings.
.PARAMETER RemoveKeys
Optional array of setting keys to remove from the Function App configuration. Removals are applied after merging updates and before PUT.
.PARAMETER AccessToken
Optional bearer token to override Managed Identity. If provided, this token is used for Authorization.
.EXAMPLE
Update-CIPPAzFunctionAppSetting -Name myfunc -ResourceGroupName rg1 -AppSetting @{ WEBSITE_TIME_ZONE = 'UTC' }
.EXAMPLE
Update-CIPPAzFunctionAppSetting -Name myfunc -ResourceGroupName rg1 -AppSetting @{ WEBSITE_TIME_ZONE = 'UTC' } -RemoveKeys @('OLD_KEY','LEGACY_SETTING')
#>
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory = $true)]
[string]$Name,
[Parameter(Mandatory = $true)]
[string]$ResourceGroupName,
[Parameter(Mandatory = $true)]
[hashtable]$AppSetting,
[Parameter(Mandatory = $false)]
[string[]]$RemoveKeys,
[Parameter(Mandatory = $false)]
[string]$AccessToken
)
# Build ARM URIs
$subscriptionId = Get-CIPPAzFunctionAppSubId
$apiVersion = '2024-11-01'
$updateUri = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Web/sites/$Name/config/appsettings?api-version=$apiVersion"
# Fetch current settings to avoid overwriting unrelated keys
$current = $null
try {
# Prefer the dedicated getter to handle ARM quirks
$GetSettings = @{
Name = $Name
ResourceGroupName = $ResourceGroupName
}
if ($AccessToken) { $GetSettings.AccessToken = $AccessToken }
$current = Get-CIPPAzFunctionAppSetting @GetSettings
} catch { $current = $null }
$currentProps = @{}
if ($current -and $current.properties) {
# Handle PSCustomObject properties (JSON deserialization result)
if ($current.properties -is [hashtable]) {
foreach ($ck in $current.properties.Keys) { $currentProps[$ck] = [string]$current.properties[$ck] }
} else {
# PSCustomObject - enumerate using PSObject.Properties
foreach ($prop in $current.properties.PSObject.Properties) {
$currentProps[$prop.Name] = [string]$prop.Value
}
}
} else {
# Could not retrieve current settings - backfill from EnvVarBackup to avoid overwriting required properties with empty values
Write-Warning "Could not retrieve current Function App settings for $Name - attempting to backfill from environment variable backup."
$EnvBackupTable = Get-CIPPTable -tablename 'EnvVarBackups'
$BackupEntity = Get-CIPPAzDataTableEntity @EnvBackupTable -Filter "PartitionKey eq 'EnvVarBackup' and RowKey eq '$Name'"
if ($BackupEntity -and $BackupEntity.Values) {
($BackupEntity.Values | ConvertFrom-Json).PSObject.Properties | ForEach-Object {
if ($_.Value) { $currentProps[$_.Name] = [string]$_.Value }
}
Write-Information "Backfilled $($currentProps.Count) properties from environment variable backup for $Name"
} else {
throw "Failed to retrieve current settings for Function App $Name and no backup found - aborting update to avoid potential misconfiguration."
}
}
# Merge requested settings
foreach ($k in $AppSetting.Keys) { $currentProps[$k] = [string]$AppSetting[$k] }
# Apply removals if specified
if ($RemoveKeys -and $RemoveKeys.Count -gt 0) {
foreach ($rk in $RemoveKeys) {
if ($currentProps.ContainsKey($rk)) {
[void]$currentProps.Remove($rk)
}
}
}
$body = @{ properties = $currentProps }
if ($PSCmdlet.ShouldProcess($Name, 'Update Function App settings')) {
$restParams = @{ Uri = $updateUri; Method = 'PUT'; Body = $body; ContentType = 'application/json' }
if ($AccessToken) { $restParams.AccessToken = $AccessToken }
$resp = New-CIPPAzRestRequest @restParams
return $resp
}
}