To set up a budget with warning in Azure, the Az.Billing PowerShell Module offers the cmdlets New-AzConsumptionBudget. Unfortunately, the PowerShell commands don’t seem to be implemented correctly in version 2.0.0 at the Az Module 8.3.0 or newer (currently 9.0.1):

New-AzConsumptionBudget -Amount 5 -Name "Budget1" -Category Cost -StartDate 2022-10-01 -TimeGrain Monthly -EndDate 2022-12-31 -ContactEmail "thomas@zuehlke.cloud" -NotificationKey Key1 -NotificationThreshold 0.8 -NotificationEnabled
New-AzConsumptionBudget: Operation returned an invalid status code 'BadRequest'

The call produces the unhelpful BadRequest error message. Get-Error can be used to check more details about the last error:

Get-Error
...
        Content      : {"error":{"code":"400","message":"Cost Management supports only Enterprise Agreement, Web direct and Microsoft Customer Agreement offer types. Subscription ... is not associated with a valid offer type.
...

The error message does not appear to be correct because it is possible to define a budget for the subscription without any problems. The list budgets command also fails with an error message:

Get-AzConsumptionBudget
Get-AzConsumptionBudget: Operation returned an invalid status code 'UnprocessableEntity'

In this case, the request doesn’t seem to be implemented correctly:

Get-Error
...
        Content      : {"error":{"code":"422","message":"This operation is not supported in the version specified in the request. Please use version 2019-10-01-preview or later. }}
...

As an alternative, the budget can also be defined directly via REST:

$body = @{
  "properties"= @{
    "category" = "Cost"
    "amount"= 5
    "timeGrain" = "Monthly"
    "timePeriod"= @{
      "startDate" = "2022-10-01T00:00:00Z"
      "endDate" = "2022-12-31T00:00:00Z"
    }
    "notifications" = @{
      "Forecasted_GreaterThan_80_Percent" = @{
        "enabled" = $true
        "operator" = "GreaterThan"
        "threshold" = 80
        "locale" = "de-de"
        "contactEmails" = @("thomas@zuehlke.cloud")
        "thresholdType" = "Forecasted"
      }
    }
  }
}
$token=(Get-AzAccessToken).token
Invoke-RestMethod `
  -Method Put `
  -Headers @{"Authorization"="Bearer $token"} `
  -ContentType "application/json; charset=utf-8" `
  -Body (ConvertTo-Json $body -Depth 10) `
  -Uri "https://management.azure.com/subscriptions/<SubscriptionId>/providers/Microsoft.Consumption/budgets/Budget1?api-version=2021-10-01"