- 24 Dec 2025
- 6 Minutes to read
- Print
- DarkLight
- PDF
Create cost management groups with the API for the first time
- Updated on 24 Dec 2025
- 6 Minutes to read
- Print
- DarkLight
- PDF
This sample will show you how you can create some cost management groups in Turbo360 via the API to help setup Turbo360.
The use case here is you would like to setup a number of groups to help simplify up your first time setup.
In this sample we will be taking advantage of the bulk tag setting feature to allow my group to be configured to focus on cost related to a specific set of tags within the chosen subscriptions.
Scope of Demo
This script will only support 1st time setup for groups
We will be introducing a sample/feature at the end of Jan 2026 to show how you can round trip the cost management groups
Workflow
The user will have a Turbo360 account and is the account owner to create an API Key
The Turbo360 account is configured and has cost data being imported
The user will use the scripts below to create groups for the first time use
The user will then use Turbo360 to maintain groups ongoing
Script to Create my Groups
The below documentation describes the parameters and script to do a first time setup.
Parameters
Parameter | What is this value | Where do I get this value |
|---|---|---|
ParentId | This is a guid for the parent node on the Turbo360 tree view that you want to be the parent for the node you are creating | You can see this in the url in the browser when you click on the desired parent node tree. |
GroupName | This is the name for your new tree view node | |
ClientId | This is the client id for the service principal that you would like your tree view node to use for accessing subscriptions | This should be the client id that you have configured in the Service Principals section of cost analyzer |
SubscriptionIds | This is an array of the subscription id’s that you would like this tree node to look at | You can get these from Azure or you can get them from the cost imports section of Turbo360 Cost Analyzer where you will see the cost import status for each subscription |
FilterTagKey | This is the tag name that you are wanting to use to filter your costs. For example “cost-tracker-code” | You will know this from your Azure setup |
FilterTagValues | This is the array of values for your chosen filter tag. For example:
| You will know this from your Azure setup |
ApiKey | This is the API key from your Turbo360 account | You get this from the Turbo360 user interface |
ApiHostName | This is the host name for Turbo360. If you are using the SaaS platform this will be portal.turbo360.com or alternatively if you are using private hosted turbo360 it will be the host name for your web app. | You can get this from the browser url when you are using Turbo360 |
Script
In this script I can set up 1 cost management group. I can supply more calls to CreateCostGroups.ps1 to create more groups.
$ApiHostName = "portal.turbo360.com"
$apiKey = "[Your Key Here]"
.\CreateGroups.ps1 `
-GroupName "Dev Team Group 2" `
-ParentId "[The parent group id]" `
-ClientId "{Azure Client ID Guid}" `
-SubscriptionIds @("{Azure Subscription Guid 1}", "{Azure Subscription Guid 2}") `
-FilterTagKey "{Tag Name}" `
-FilterValues @("{Tag Value 1}", "{Tag Value 2}") `
-ApiKey $apiKey `
-ApiHostName $ApiHostName `
-Description "Development team subscriptions"Base Script to Create Cost Management Groups via the API
This is the base reusable script which you can use to setup some cost management groups for the first time.
<#
.SYNOPSIS
Create Cost Analyzer Groups in Turbo360
.DESCRIPTION
Creates a new Cost Analyzer group with the specified configuration. This script is designed for
one-time group creation and does not save or manage group configurations on disk.
.PARAMETER GroupName
The name of the group to create
.PARAMETER ParentId
The parent group ID under which to create the group
.PARAMETER ClientId
The service principal client ID to use for all subscriptions
.PARAMETER SubscriptionIds
Array of subscription IDs to include in the group
.PARAMETER FilterTagKey
The tag key to filter on (optional)
.PARAMETER FilterValues
Array of tag values to filter on (optional)
.PARAMETER Description
Description for the group (default: "Group created via PowerShell script")
.PARAMETER ApiKey
The API key for authenticating with Turbo360
.PARAMETER ApiHostName
The API host name (default: portal.turbo360.com). Use custom host for private hosting customers.
.PARAMETER LogRequests
Whether to log create requests to files (default: $false)
.EXAMPLE
.\CreateGroups.ps1 -GroupName "Production Group" -ParentId "414d81d1-e4cc-443c-94a4-21069cd78a6c" -ClientId "0f4b620d-4c52-4dfa-8d17-f831badae1ca" -SubscriptionIds @("sub1","sub2") -ApiKey "your-api-key"
.EXAMPLE
.\CreateGroups.ps1 -GroupName "Dev Group" -ParentId "414d81d1-e4cc-443c-94a4-21069cd78a6c" -ClientId "0f4b620d-4c52-4dfa-8d17-f831badae1ca" -SubscriptionIds @("sub1") -FilterTagKey "environment" -FilterValues @("dev") -ApiKey "your-api-key"
.EXAMPLE
.\CreateGroups.ps1 -GroupName "Private Group" -ParentId "414d81d1-e4cc-443c-94a4-21069cd78a6c" -ClientId "0f4b620d-4c52-4dfa-8d17-f831badae1ca" -SubscriptionIds @("sub1") -ApiKey "your-api-key" -ApiHostName "custom.domain.com"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[string]$GroupName,
[Parameter(Mandatory=$true)]
[string]$ParentId,
[Parameter(Mandatory=$true)]
[string]$ClientId,
[Parameter(Mandatory=$true)]
[string[]]$SubscriptionIds,
[Parameter(Mandatory=$true)]
[string]$ApiKey,
[Parameter(Mandatory=$false)]
[string]$ApiHostName = "portal.turbo360.com",
[Parameter(Mandatory=$false)]
[string]$FilterTagKey,
[Parameter(Mandatory=$false)]
[string[]]$FilterValues = @(),
[Parameter(Mandatory=$false)]
[string]$Description = "Group created via PowerShell script",
[Parameter(Mandatory=$false)]
[bool]$LogRequests = $false
)
# Configuration
$BaseUrl = "https://$ApiHostName/CostAnalyzer/Group"
Write-Host "Creating Cost Analyzer Group: $GroupName" -ForegroundColor Cyan
Write-Host ""
# Function to build service principals from configuration
function Get-ServicePrincipals {
Write-Host "Building service principals from configuration..." -ForegroundColor Cyan
# Map subscription IDs to the format needed for bulkScopeSelection
$MappedSPs = $SubscriptionIds | ForEach-Object {
@{
subscriptionId = $_
clientId = $ClientId
}
}
Write-Host "✓ Built $($MappedSPs.Count) service principal(s) with client ID: $ClientId" -ForegroundColor Green
return $MappedSPs
}
# Template for new group
$GroupTemplate = @{
parentId = $ParentId
name = $GroupName
description = $Description
bulkScopeSelection = @{
servicePrincipals = @()
filters = @()
}
selectedServicePrincipals = @()
}
# Add service principals to the template
$ServicePrincipals = Get-ServicePrincipals
if ($ServicePrincipals.Count -gt 0) {
$GroupTemplate.bulkScopeSelection.servicePrincipals = $ServicePrincipals
Write-Host "✓ Added $($ServicePrincipals.Count) service principal(s) to group template" -ForegroundColor Green
}
# Add filters to the template
if ($FilterTagKey -and $FilterValues.Count -gt 0) {
$Filter = @{
filterType = 0
filterValues = $FilterValues
tagKey = $FilterTagKey
}
$GroupTemplate.bulkScopeSelection.filters = @($Filter)
Write-Host "✓ Added filter with tag '$FilterTagKey' and $($FilterValues.Count) value(s)" -ForegroundColor Green
}
# Create API endpoint
$CreateUrl = "$BaseUrl/Create"
# Convert template to JSON
$Body = $GroupTemplate | ConvertTo-Json -Depth 10
# Optional: Log the request to a file
if ($LogRequests) {
$LogFolder = Join-Path $PSScriptRoot "logs"
if (-not (Test-Path $LogFolder)) {
New-Item -ItemType Directory -Path $LogFolder | Out-Null
}
$Timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$LogFileName = "create_request_$Timestamp.json"
$LogFilePath = Join-Path $LogFolder $LogFileName
$Body | Set-Content $LogFilePath
Write-Host "✓ Request logged to: $LogFilePath" -ForegroundColor Cyan
}
Write-Host ""
Write-Host "Sending create request to API..." -ForegroundColor Cyan
# Make POST request
try {
$Headers = @{
"accept" = "*/*"
"APIKey" = $ApiKey
"Content-Type" = "application/json"
}
$Response = Invoke-RestMethod -Uri $CreateUrl -Method Post -Headers $Headers -Body $Body
Write-Host "✓ Group created successfully!" -ForegroundColor Green
if ($Response.id) {
Write-Host "Group ID: $($Response.id)" -ForegroundColor Cyan
}
Write-Host ""
Write-Host "Operation completed successfully." -ForegroundColor Green
}
catch {
Write-Host "✗ Error creating group: $($_.Exception.Message)" -ForegroundColor Red
if ($_.ErrorDetails.Message) {
Write-Host "Details: $($_.ErrorDetails.Message)" -ForegroundColor Red
}
exit 1
}