I’m trying to access a specific field in a JSON object created by Azure Advisor using PowerShell. I have the following object:
@{id=/subscriptions/xxxx/providers/Microsoft.Advisor/recommendations/xxxx;
category=Cost;
impact=High;
impactedArea=Microsoft.Subscriptions/subscriptions;
description=Consider virtual machine reserved instance to save over your on-demand costs;
recommendationText=Consider virtual machine reserved instance to save over your on-demand costs;
recommendationTypeId=xxx; instanceName=xxxx;
additionalInfo=;
tags=;
ResourceId=/subscriptions/xxxx/providers/Microsoft.Advisor/recommendations/xxxx}
In this, I want to access a field ‘savingsCurrency’ to compare in an if-statement. The field is nested in ‘additionalInfo’, which in turn is in the ‘advisorRecommendation’ object.
I have the following code now:
Write-Output "advisorrecommendation: $advisorRecommendation"
if (-not([string]::IsNullOrEmpty($advisorRecommendation.additionalInfo)))
{
$additionalInfo = $advisorRecommendation.additionalInfo | ConvertTo-Json
Write-Output "additionalInfo: $additionalInfo"
if (-not([string]::IsNullOrEmpty($additionalInfo.savingsCurrency)))
{
$savingsCurrency = $additionalInfo.savingsCurrency | ConvertTo-Json
Write-Output "Currency: $savingsCurrency"
}
}
else
{
$additionalInfo = $null
}
This code gives me the following outputs:
advisorrecommendation:
@{id=/subscriptions/xxxx/providers/Microsoft.Advisor/recommendations/xxx; category=Cost; impact=High; impactedArea=Microsoft.Subscriptions/subscriptions; description=Consider virtual machine reserved instance to save over your on-demand costs; recommendationText=Consider virtual machine reserved instance to save over your on-demand costs; recommendationTypeId=xxxx; instanceName=xxxx; additionalInfo=; tags=; ResourceId=/subscriptions/xxxx/providers/Microsoft.Advisor/recommendations/xxxx}
additionalInfo: {
"annualSavingsAmount": "697",
"reservedResourceType": "virtualmachines",
"targetResourceCount": "4",
"savingsCurrency": "USD",
"savingsAmount": "58",
"lookbackPeriod": "30",
"displaySKU": "Standard_B2s",
"displayQty": "4",
"location": "westeurope",
"region": "westeurope",
"vmSize": "Standard_B2s",
"subId": "xxxx",
"scope": "Single",
"term": "P1Y",
"qty": "4",
"sku": "Standard_B2s"
}
The ‘savingsCurrency’ field never passes the null/empty check, even though I can clearly see that the field in ‘additionalInfo’ is not empty or null. What is going wrong here? If I try the print without the preceeding existence check, it simply prints the additionalInfo object with .savingsCurrency appended like this:
savingsCurrency: {
"annualSavingsAmount": "697",
"reservedResourceType": "virtualmachines",
"targetResourceCount": "4",
"savingsCurrency": "USD",
"savingsAmount": "58",
"lookbackPeriod": "30",
"displaySKU": "Standard_B2s",
"displayQty": "4",
"location": "westeurope",
"region": "westeurope",
"vmSize": "Standard_B2s",
"subId": "xxxx",
"scope": "Single",
"term": "P1Y",
"qty": "4",
"sku": "Standard_B2s"
}.savingsCurrency
2
Answers
$advisorRecommendation.additionalInfo
is an object with nested properties:but
$additionalInfo
is a string because you’ve converted the object to json before assigning it:As a result,
$savingsCurrency = $additionalInfo.savingsCurrency
is trying to read thesavingsCurrency
property of a string, and strings don’t have that property so you get$null
.What you want to do instead is keep a reference to the
$advisorRecommendation.additionalInfo
object instead and only convert it to json for the purpose of writing it to the console:You should now see
Currency: USD
in your output.Note that
$additionalInfo.savingsCurrency
is already a string so you don’t need to useConvertTo-Json
to display the value unless you specifically want it to be formatted as a json string (i.e."USD"
with surrounding quotes and any special characters likeescaped, instead of the literal string value
USD
)You can check not null and if condition like below:
To access any json filed you need to first convert it from json like below :
To access any field you can use dot operator: