Reputation: 1
I have a PowerShell script that calls the Microsoft Azure API for cost management.
I first call:
This returns a 202 as expected:
StatusCode : 202
StatusDescription : Accepted
Content : {}
RawContent : HTTP/1.1 202 Accepted
Pragma: no-cache
I then extract the header location and poll until I get a 200
StatusCode : 200
StatusDescription : OK
Content : {"id":"/providers/Microsoft.Billing/enrollmentAccounts/7****5/providers/Microsoft.CostManagement/costDetail sOperationResults/ca4f*******-d8bff1dbf7c2","name":"ca4f85f****-d8bff1...
RawContent : HTTP/1.1 200 OK
Pragma: no-cache
Vary: Accept-Encoding
session-id: ae0a1b9b-2d21********6136a55bcb
x-ms-request-id: d2f**********85-8d7f54a02fb7
x-ms-correlation-request-id: 23b94e5d...
Forms : {}
Headers : {[Pragma, no-cache], [Vary, Accept-Encoding], [session-id, ae0a1b9b-2d21-4088-82f4- 106136a55bcb], [x-ms-request-id, d2f0ab18-e34c-*****4a02fb7]...}
Images : {}
InputFields : {}
Links : {}
ParsedHtml : mshtml.HTMLDocumentClass
RawContentLength : 935
The problem is that I'm expecting a blob location to be returned but it isn't.
Any guidance would be greatly appreciated.
The blob location should be in the Manifest section
i.e ......Manifest.blobs.blobLink
I
I've tried different versions of the API be all return the same.
I'm sure it's something I'm doing wrong.
Upvotes: 0
Views: 176
Reputation: 1
Many thanks for your response. Looking at your code I realised I had a difference. I was using Invoke-Webrequest when I was looking for the blob location when it should have been Invoke-RestMethod. Making this single change returns the required Blob Location details. id : /providers/Microsoft.Billing/enrollmentAccounts/75/providers/Microsoft.CostManagement/costDetailsOperationResults/9bb4efc1-e5f-0afdaec988b8 name : 9bb4efc1-4b4e-49****daec988b8 status : Completed manifest : @{manifestVersion=2022-05-01; dataFormat=Csv; byteCount=46517627; blobCount=1; compressData=False; requestContext=; blobs=System.Object[]} validTill : 2023-12-06T23:39:58.9165023
Many thanks
Upvotes: 0
Reputation: 8167
According to this Official MS Document the Azure Cost management API with scope set to enrollmentAccounts
does not contain any blob location in the request. If you want to retrieve the cost of the blob resource, You need to use:-
'/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}'
where resourceGroupName is the name of your resource group containing your blob.
My sample Powershell script that calls the Cost management API:-
$AppId = "xxxxxx-6d26a31435cb"
$AppSecret = "xxxxhhZ~bY."
$TokenURI = "https://login.microsoftonline.com/xxxxxx95/oauth2/token"
$Resource = "https://management.core.windows.net/"
$BodyRequest = "grant_type=client_credentials&client_id=$AppId&client_secret=$AppSecret&resource=$Resource"
$AccessToken = Invoke-RestMethod -Method Post -Uri $TokenURI -Body $BodyRequest -ContentType 'application/x-www-form-urlencoded'
$RequestURI = "https://management.azure.com/subscriptions/0151c365-f598-44d6-b4fd-e2b6e97cb2a7/resourceGroups/siliconstrg909-rg/providers/Microsoft.CostManagement/query?api-version=2023-03-01"
$Headers = @{
"Authorization" = "Bearer " + $AccessToken.access_token
"Content-Type" = "application/json"
}
# Updated request body structure
$UsageRequestBody = @{
type = "Usage"
timeframe = "MonthToDate"
dataset = @{
granularity = "Daily"
aggregation = @{
totalCost = @{
name = "PreTaxCost"
function = "Sum"
}
}
grouping = @(
@{
type = "Dimension"
name = "ResourceGroup"
}
)
}
}
# Convert the updated payload to JSON
$UsageRequestBodyJson = $UsageRequestBody | ConvertTo-Json
# Make the request using Invoke-RestMethod
$UsageRequest = Invoke-RestMethod -Method Post -Uri $RequestURI -Headers $Headers -Body $UsageRequestBodyJson -ContentType 'application/json'
# Output the response
$UsageRequest.properties.rows
# Check for pagination
while ($UsageRequest.properties.nextLink) {
$NextLink = $UsageRequest.properties.nextLink
$UsageRequest = Invoke-RestMethod -Uri $NextLink -Headers $Headers -Method Get
$UsageRequest.properties.rows
}
Output:-
In your enrollmentAccounts Rest API, Try to add ResourceGroup name in value that contains your blob:-
$AppId = "xxxxxx26a31435cb"
$AppSecret = "xxxxxxxZ~bY."
$TokenURI = "https://login.microsoftonline.com/83xxxxxx92395/oauth2/token"
$Resource = "https://management.core.windows.net/"
$BodyRequest = "grant_type=client_credentials&client_id=$AppId&client_secret=$AppSecret&resource=$Resource"
$AccessToken = Invoke-RestMethod -Method Post -Uri $TokenURI -Body $BodyRequest -ContentType 'application/x-www-form-urlencoded'
$RequestURI = "https://management.azure.com/providers/Microsoft.Billing/enrollmentAccounts/*****5/providers/Microsoft.CostManagement/generateCostDetailsReport?api-version=2023-08-01"
$Headers = @{
"Authorization" = "Bearer " + $AccessToken.access_token
"Content-Type" = "application/json"
}
# Updated request body structure
$UsageRequestBody = @{
type = "Usage"
timeframe = "MonthToDate"
dataset = @{
granularity = "Daily"
filter = @{
and = @(
@{
or = @(
@{
dimensions = @{
name = "ResourceLocation"
operator = "In"
values = @("East US", "West Europe")
}
},
@{
tags = @{
name = "Environment"
operator = "In"
values = @("UAT", "Prod")
}
}
)
},
@{
dimensions = @{
name = "ResourceGroup"
operator = "In"
values = @("YourSampleResourceGroupName") # Replace this with your actual resource group name
}
}
)
}
}
}
# Convert the updated payload to JSON
$UsageRequestBodyJson = $UsageRequestBody | ConvertTo-Json
# Make the request using Invoke-RestMethod
$UsageRequest = Invoke-RestMethod -Method Post -Uri $RequestURI -Headers $Headers -Body $UsageRequestBodyJson -ContentType 'application/json'
# Output the response
$UsageRequest
# Check for pagination
while ($UsageRequest.properties.nextLink) {
$NextLink = $UsageRequest.properties.nextLink
$UsageRequest = Invoke-RestMethod -Uri $NextLink -Headers $Headers -Method Get
$UsageRequest
}
Also, There's a separate Rest API dedicated to Azure Blob Storage, You can try calling the Azure blob Powershell command to retrieve the blob properties like below:-
# Connect to Azure account and set the desired subscription
Connect-AzAccount -TenantId xxxxxxxab9
Set-AzContext -SubscriptionId 'xxxxxxcb2a7'
# Get the storage account context
$ctx = Get-AzStorageAccount -ResourceGroupName "valleyrg87" -Name "siliconstorage678"
# Check if the context is retrieved properly
$ctx
# Get the storage account context
$ctx = Get-AzStorageAccount -ResourceGroupName "valleyrg87" -Name "siliconstorage678"
# Check if the context is retrieved properly
$ctx
# If context is retrieved successfully, proceed to get blob properties
if ($ctx) {
# Get the blob reference
$blob = Get-AzStorageBlob -Blob "hello_world.py" -Container "data" -Context $ctx.Context
# Check if the blob is retrieved successfully
$blob
# If the blob is retrieved successfully, get blob properties
if ($blob) {
$properties = $blob.ICloudBlob.Properties
$properties
} else {
Write-Host "Blob not found or there was an issue retrieving the blob."
}
} else {
Write-Host "Storage account not found"
}
Output:-
Upvotes: 0