Created
February 20, 2021 14:43
-
-
Save rupeshtech/2b7c4c4a8ab4103605409426547ac797 to your computer and use it in GitHub Desktop.
Create a Consumption Budget for ResourceGroups in Azure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param ( | |
[string]$ResourceGroupsToExclude | |
) | |
function Login-AzureAutomation([bool] $AzModuleOnly) { | |
try { | |
$RunAsConnection = Get-AutomationConnection -Name "AzureRunAsConnection" | |
Write-Output "Logging in to Azure ($AzureEnvironment)..." | |
if (!$RunAsConnection.ApplicationId) { | |
$ErrorMessage = "Connection 'AzureRunAsConnection' is incompatible type." | |
throw $ErrorMessage | |
} | |
if ($AzModuleOnly) { | |
Connect-AzAccount ` | |
-ServicePrincipal ` | |
-TenantId $RunAsConnection.TenantId ` | |
-ApplicationId $RunAsConnection.ApplicationId ` | |
-CertificateThumbprint $RunAsConnection.CertificateThumbprint ` | |
-Environment $AzureEnvironment | |
Select-AzSubscription -SubscriptionId $RunAsConnection.SubscriptionID | Write-Verbose | |
} else { | |
Add-AzureRmAccount ` | |
-ServicePrincipal ` | |
-TenantId $RunAsConnection.TenantId ` | |
-ApplicationId $RunAsConnection.ApplicationId ` | |
-CertificateThumbprint $RunAsConnection.CertificateThumbprint ` | |
-Environment $AzureEnvironment | |
Select-AzureRmSubscription -SubscriptionId $RunAsConnection.SubscriptionID | Write-Verbose | |
} | |
} catch { | |
if (!$RunAsConnection) { | |
$RunAsConnection | fl | Write-Output | |
Write-Output $_.Exception | |
$ErrorMessage = "Connection 'AzureRunAsConnection' not found." | |
throw $ErrorMessage | |
} | |
throw $_.Exception | |
} | |
} | |
function Get-AzCachedAccessToken() | |
{ | |
$ErrorActionPreference = 'Stop' | |
if(-not (Get-Module Az.Accounts)) { | |
Import-Module Az.Accounts | |
} | |
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile | |
if(-not $azProfile.Accounts.Count) { | |
Write-Error "Ensure you have logged in before calling this function." | |
} | |
$currentAzureContext = Get-AzContext | |
$profileClient = New-Object Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient($azProfile) | |
Write-Debug ("Getting access token for tenant" + $currentAzureContext.Tenant.TenantId) | |
$token = $profileClient.AcquireAccessToken($currentAzureContext.Tenant.TenantId) | |
$token.AccessToken | |
} | |
$AzureEnvironment='AzureCloud' | |
$UseAzModule = $true | |
Login-AzureAutomation $UseAzModule | |
$subscriptionId= (Get-AzContext).Subscription.id | |
$token= Get-AzCachedAccessToken | |
$bearerToken="Bearer $token" | |
$contactEmails= @('xxxxxxxxx') | |
$bodyObject=@{ | |
"properties" = @{ | |
"category"= "Cost" | |
"amount"="100" | |
"timeGrain" = "Monthly" | |
"timePeriod"= @{ | |
"startDate"= "2021-01-01" | |
"endDate"= "2025-01-01" | |
} | |
"notifications"=@{ | |
"NotificationForExceededBudget"= @{ | |
"enabled"= "true" | |
"operator"= "GreaterThan" | |
"threshold"= "90" | |
"contactEmails"=$contactEmails | |
} | |
} | |
} | |
} | |
$headers = @{ | |
'Authorization' = $bearerToken | |
} | |
$body = $bodyObject | convertto-json -Depth 2 | |
$rgs= Get-AzResourceGroup | where { $ResourceGroupsToExclude -notlike "*$($_.ResourceGroupName)*" } | |
foreach ($rg in $rgs) { | |
$resourceGroupName= $rg.ResourceGroupName | |
$budgetName= "$resourceGroupName-cb" | |
$URI="https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Consumption/budgets/$budgetName"+"?api-version=2019-10-01" | |
Invoke-RestMethod -Method Put -ContentType "application/json" -Uri $URI -Headers $headers -Body $body | |
} |
Thanks for this ... I get the following error:
Invoke-RestMethod : {"error":{"code":"400","message":"Notification cannot have all of Contact Emails, Contact Roles
and Contact Groups empty.\r\n (Request ID: 290e6349-3219-46d4-9c82-9861a3d25132)"}}
At line:1 char:17
- ... ateBudget = Invoke-RestMethod -Uri $restUri -Method Put -Headers $aut ...
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
eption - FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
- CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc
I have no Contact Roles or Contact Groups and already have budgets with those fields empty. Any ideas?
thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@rupeshtech thanks for the example, but
| convertto-json -Depth 2
will fail as it's 3 deep.NotificationForExceededBudget
will not be converted to JSON. Maybe the behavior is different in another version, but in PowerShell Core it won't work with the value2
.Also, to get the token, I find that the following is a much cleaner approach: