@@ -3,7 +3,8 @@ function Get-CIPPAzIdentityToken {
33 . SYNOPSIS
44 Get the Azure Identity token for Managed Identity
55 . DESCRIPTION
6- This function retrieves the Azure Identity token using the Managed Identity endpoint for the specified resource
6+ This function retrieves the Azure Identity token using the Managed Identity endpoint for the specified resource.
7+ Tokens are cached per resource URL until expiration to reduce redundant API calls.
78 . PARAMETER ResourceUrl
89 The Azure resource URL to get a token for. Defaults to 'https://management.azure.com/' for Azure Resource Manager.
910
@@ -12,6 +13,8 @@ function Get-CIPPAzIdentityToken {
1213 - https://vault.azure.net (Azure Key Vault)
1314 - https://api.loganalytics.io (Log Analytics / Application Insights)
1415 - https://storage.azure.com/ (Azure Storage)
16+ . PARAMETER SkipCache
17+ Force a new token to be fetched, bypassing the cache.
1518 . EXAMPLE
1619 Get-CIPPAzIdentityToken
1720 Gets a token for Azure Resource Manager
@@ -25,7 +28,8 @@ function Get-CIPPAzIdentityToken {
2528 [CmdletBinding ()]
2629 param (
2730 [Parameter (Mandatory = $false )]
28- [string ]$ResourceUrl = ' https://management.azure.com/'
31+ [string ]$ResourceUrl = ' https://management.azure.com/' ,
32+ [switch ]$SkipCache
2933 )
3034
3135 $Endpoint = $env: IDENTITY_ENDPOINT
@@ -35,12 +39,40 @@ function Get-CIPPAzIdentityToken {
3539 throw ' Managed Identity environment variables (IDENTITY_ENDPOINT/IDENTITY_HEADER) not found. Is Managed Identity enabled on the Function App?'
3640 }
3741
38- $EncodedResource = [System.Uri ]::EscapeDataString($ResourceUrl )
39- $TokenUri = " $ ( $Endpoint ) ?resource=$EncodedResource &api-version=2019-08-01"
40- $Headers = @ {
41- ' X-IDENTITY-HEADER' = $Secret
42- }
42+ # Build cache key from resource URL
43+ $TokenKey = " ManagedIdentity-$ResourceUrl "
44+
45+ try {
46+ # Check if cached token exists and is still valid
47+ if ($script :ManagedIdentityTokens .$TokenKey -and [int ](Get-Date - UFormat % s - Millisecond 0 ) -lt $script :ManagedIdentityTokens .$TokenKey.expires_on -and $SkipCache -ne $true ) {
48+ return $script :ManagedIdentityTokens .$TokenKey.access_token
49+ }
50+
51+ # Get new token
52+ $EncodedResource = [System.Uri ]::EscapeDataString($ResourceUrl )
53+ $TokenUri = " $ ( $Endpoint ) ?resource=$EncodedResource &api-version=2019-08-01"
54+ $Headers = @ {
55+ ' X-IDENTITY-HEADER' = $Secret
56+ }
57+
58+ $TokenResponse = Invoke-RestMethod - Method Get - Headers $Headers - Uri $TokenUri - ErrorAction Stop
59+
60+ # Calculate expiration time
61+ $ExpiresOn = [int ](Get-Date - UFormat % s - Millisecond 0 ) + $TokenResponse.expires_in
4362
44- $TokenResponse = Invoke-RestMethod - Method Get - Headers $Headers - Uri $TokenUri
45- return $TokenResponse.access_token
63+ # Store in cache (initialize synchronized hash table if needed)
64+ if (-not $script :ManagedIdentityTokens ) {
65+ $script :ManagedIdentityTokens = [HashTable ]::Synchronized(@ {})
66+ }
67+
68+ # Add expires_on to token response for tracking
69+ Add-Member - InputObject $TokenResponse - NotePropertyName ' expires_on' - NotePropertyValue $ExpiresOn - Force
70+
71+ # Cache the token
72+ $script :ManagedIdentityTokens .$TokenKey = $TokenResponse
73+
74+ return $TokenResponse.access_token
75+ } catch {
76+ throw " Failed to get managed identity token for resource '$ResourceUrl ': $ ( $_.Exception.Message ) "
77+ }
4678}
0 commit comments