admin管理员组文章数量:1123858
I'm working on getting this kql query to work but unable to get the joins to work and it appears that you can't use "let" in Azure resource graph. I am able to pull a seperate query that give the category along with the amount of unhealthy resources and then I can get a query that give the max score and how much it can increase by but can't seem to get everything in a single query. I used copilot for this code but unfortunately ARGE does not allow to use the "let" code.
// Summarize control data
let controlsAssessmentsData =
securityresources
| where type == "microsoft.security/securescores/securescorecontrols"
| extend secureScoreName = extract("/providers/Microsoft.Security/secureScores/([^/]*)/", 1, id)
| where secureScoreName == "ascScore"
| extend environment = tostring(properties.environment)
| extend scope = extract("(.*)/providers/Microsoft.Security/secureScores/", 1, id)
| where environment in ("AWS", "Azure", "AzureDevOps", "DockerHub", "GCP", "GitHub", "GitLab", "JFrog")
| extend controlDisplayName = tostring(properties.displayName)
| extend controlName = name
| extend assessmentKeys = extract_all("\"id\":\".*?/assessmentMetadata/([^\"]*)\"", tostring(properties.definition.properties.assessmentDefinitions))
| extend notApplicableResourceCount = toint(properties.notApplicableResourceCount)
| extend unhealthyResourceCount = toint(properties.unhealthyResourceCount)
| extend healthyResourceCount = toint(properties.healthyResourceCount)
| extend controlMaxScore = toint(properties.score.max)
| extend currentScore = todouble(properties.score.current)
| join kind=leftouter (
securityresources
| where type == "microsoft.security/securescores"
| where name == "ascScore"
| extend environment = tostring(properties.environment)
| extend scopeMaxScore = toint(properties.score.max)
| extend scopeWeight = toint(properties.weight)
| parse id with scope "/providers/Microsoft.Security/secureScores" *
| where environment in ("AWS", "Azure", "AzureDevOps", "DockerHub", "GCP", "GitHub", "GitLab", "JFrog")
| project scope, scopeWeight, scopeMaxScore, joinOn = 1
) on scope
| extend potentialScoreIncrease = controlMaxScore - currentScore
| project subscriptionId, resourceGroup, controlDisplayName, controlName, maxScore = controlMaxScore, currentScore, potentialScoreIncrease, status = properties.status.code, unhealthyResourceCount, healthyResourceCount, assessmentKeys, controlData = pack_all()
| summarize assessmentKeys = any(assessmentKeys),
controlDisplayName = any(controlDisplayName),
notApplicableResourceCount = sum(notApplicableResourceCount),
unhealthyResourceCount = sum(unhealthyResourceCount),
healthyResourceCount = sum(healthyResourceCount),
controlMaxScore = max(controlMaxScore),
sumParentScopeWeight = max(sumParentScopeWeight),
impactRatio = sum(iff(scopeMaxScore == 0, todouble(0), scopeWeight / scopeMaxScore)),
controlAggregatedCurrentScoreSum = sum(iff(scopeMaxScore == 0, todouble(0), scopeWeight * currentScore / scopeMaxScore)) by controlName
| extend controlAggregatedMaxScoreSum = impactRatio * controlMaxScore
| extend controlAggregatedCurrentScore = iff(controlAggregatedMaxScoreSum == 0, todouble(0), controlAggregatedCurrentScoreSum / controlAggregatedMaxScoreSum) * controlMaxScore
| extend potentialScoreIncrease = iff(sumParentScopeWeight == 0, todouble(0), (controlAggregatedMaxScoreSum - controlAggregatedCurrentScoreSum) / sumParentScopeWeight) * 100
| project controlsAssessmentsData = pack_all(), controlMaxScore
| extend assessmentKeys = controlsAssessmentsData.assessmentKeys
| extend controlData = pack(
"controlDisplayName", controlsAssessmentsData.controlDisplayName,
"controlName", controlsAssessmentsData.controlName,
"assessmentKeys", controlsAssessmentsData.assessmentKeys,
"notApplicableResourceCount", controlsAssessmentsData.notApplicableResourceCount,
"unhealthyResourceCount", controlsAssessmentsData.unhealthyResourceCount,
"healthyResourceCount", controlsAssessmentsData.healthyResourceCount,
"totalResourceCount", toint(controlsAssessmentsData.notApplicableResourceCount) + toint(controlsAssessmentsData.unhealthyResourceCount) + toint(controlsAssessmentsData.healthyResourceCount),
"maxScore", controlsAssessmentsData.controlMaxScore,
"currentScore", controlsAssessmentsData.controlAggregatedCurrentScore,
"potentialScoreIncrease", controlsAssessmentsData.potentialScoreIncrease);
// Combine with security assessments
securityresources
| where type == 'microsoft.security/assessments'
| join kind=leftouter (resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscription=name)
on subscriptionId
| extend resourceId = tolower(tostring(properties.resourceDetails.ResourceId))
| join kind=leftouter (resources | project resourceId=tolower(id), rtags=tags.SystemID, resourceName=name) on resourceId
| join kind=leftouter (controlsAssessmentsData | project controlData, controlName) on controlName
| project
subscription,
resourceGroup,
resourceName,
resourceType=tostring(properties.resourceDetails.ResourceType),
SystemID=rtags,
recommendationSeverity=properties.metadata.severity,
recommendationStatus =properties.status.code,
recommendationName=properties.displayName,
description=properties.metadata.description,
remediationDescription=properties.metadata.remediationDescription,
portalLink=properties.links.azurePortal,
resourceId,
controlData,
unhealthyResourceCount,
healthyResourceCount,
controlMaxScore,
currentScore
Hoping to get the categories along with the individual unhealthy resources. Please advise, Serge
If I could get this query to show all the tags per resource, I could alter the csv to present what I need in a pivot table
securityresources
| where type == 'microsoft.security/assessments'
//above section will provide all information regarding on resources with status on recommendation.
| join kind=leftouter (resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscription=name)
on subscriptionId
//above section will pull all the subscriptions along with the subID and create a column called subscription that will hold the actual name and not the ID
| extend resourceId = tolower(tostring(properties.resourceDetails.ResourceId))
| extend resourceTag = tags
//above will create a column all resourceId that will be mae of the resource ID from the assessments table
| join kind=leftouter (resources | project resourceId=tolower(id), tags, resourceName=name) on resourceId
//above join pulls from the resources table and collects tags based on resource and resource ID and then does a join wiht assessments.
| project
subscription,
resourceGroup,
resourceName,
resourceType=tostring(properties.resourceDetails.ResourceType),
tags,
recommendationSeverity=properties.metadata.severity,
recommendationStatus =properties.status.code,
recommendationName=properties.displayName,
description=properties.metadata.description,
remediationDescription=properties.metadata.remediationDescription,
portalLink=properties.links.azurePortal,
resourceId
Appreciate any assistance...This query is for Azure Resource Graph.
I'm working on getting this kql query to work but unable to get the joins to work and it appears that you can't use "let" in Azure resource graph. I am able to pull a seperate query that give the category along with the amount of unhealthy resources and then I can get a query that give the max score and how much it can increase by but can't seem to get everything in a single query. I used copilot for this code but unfortunately ARGE does not allow to use the "let" code.
// Summarize control data
let controlsAssessmentsData =
securityresources
| where type == "microsoft.security/securescores/securescorecontrols"
| extend secureScoreName = extract("/providers/Microsoft.Security/secureScores/([^/]*)/", 1, id)
| where secureScoreName == "ascScore"
| extend environment = tostring(properties.environment)
| extend scope = extract("(.*)/providers/Microsoft.Security/secureScores/", 1, id)
| where environment in ("AWS", "Azure", "AzureDevOps", "DockerHub", "GCP", "GitHub", "GitLab", "JFrog")
| extend controlDisplayName = tostring(properties.displayName)
| extend controlName = name
| extend assessmentKeys = extract_all("\"id\":\".*?/assessmentMetadata/([^\"]*)\"", tostring(properties.definition.properties.assessmentDefinitions))
| extend notApplicableResourceCount = toint(properties.notApplicableResourceCount)
| extend unhealthyResourceCount = toint(properties.unhealthyResourceCount)
| extend healthyResourceCount = toint(properties.healthyResourceCount)
| extend controlMaxScore = toint(properties.score.max)
| extend currentScore = todouble(properties.score.current)
| join kind=leftouter (
securityresources
| where type == "microsoft.security/securescores"
| where name == "ascScore"
| extend environment = tostring(properties.environment)
| extend scopeMaxScore = toint(properties.score.max)
| extend scopeWeight = toint(properties.weight)
| parse id with scope "/providers/Microsoft.Security/secureScores" *
| where environment in ("AWS", "Azure", "AzureDevOps", "DockerHub", "GCP", "GitHub", "GitLab", "JFrog")
| project scope, scopeWeight, scopeMaxScore, joinOn = 1
) on scope
| extend potentialScoreIncrease = controlMaxScore - currentScore
| project subscriptionId, resourceGroup, controlDisplayName, controlName, maxScore = controlMaxScore, currentScore, potentialScoreIncrease, status = properties.status.code, unhealthyResourceCount, healthyResourceCount, assessmentKeys, controlData = pack_all()
| summarize assessmentKeys = any(assessmentKeys),
controlDisplayName = any(controlDisplayName),
notApplicableResourceCount = sum(notApplicableResourceCount),
unhealthyResourceCount = sum(unhealthyResourceCount),
healthyResourceCount = sum(healthyResourceCount),
controlMaxScore = max(controlMaxScore),
sumParentScopeWeight = max(sumParentScopeWeight),
impactRatio = sum(iff(scopeMaxScore == 0, todouble(0), scopeWeight / scopeMaxScore)),
controlAggregatedCurrentScoreSum = sum(iff(scopeMaxScore == 0, todouble(0), scopeWeight * currentScore / scopeMaxScore)) by controlName
| extend controlAggregatedMaxScoreSum = impactRatio * controlMaxScore
| extend controlAggregatedCurrentScore = iff(controlAggregatedMaxScoreSum == 0, todouble(0), controlAggregatedCurrentScoreSum / controlAggregatedMaxScoreSum) * controlMaxScore
| extend potentialScoreIncrease = iff(sumParentScopeWeight == 0, todouble(0), (controlAggregatedMaxScoreSum - controlAggregatedCurrentScoreSum) / sumParentScopeWeight) * 100
| project controlsAssessmentsData = pack_all(), controlMaxScore
| extend assessmentKeys = controlsAssessmentsData.assessmentKeys
| extend controlData = pack(
"controlDisplayName", controlsAssessmentsData.controlDisplayName,
"controlName", controlsAssessmentsData.controlName,
"assessmentKeys", controlsAssessmentsData.assessmentKeys,
"notApplicableResourceCount", controlsAssessmentsData.notApplicableResourceCount,
"unhealthyResourceCount", controlsAssessmentsData.unhealthyResourceCount,
"healthyResourceCount", controlsAssessmentsData.healthyResourceCount,
"totalResourceCount", toint(controlsAssessmentsData.notApplicableResourceCount) + toint(controlsAssessmentsData.unhealthyResourceCount) + toint(controlsAssessmentsData.healthyResourceCount),
"maxScore", controlsAssessmentsData.controlMaxScore,
"currentScore", controlsAssessmentsData.controlAggregatedCurrentScore,
"potentialScoreIncrease", controlsAssessmentsData.potentialScoreIncrease);
// Combine with security assessments
securityresources
| where type == 'microsoft.security/assessments'
| join kind=leftouter (resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscription=name)
on subscriptionId
| extend resourceId = tolower(tostring(properties.resourceDetails.ResourceId))
| join kind=leftouter (resources | project resourceId=tolower(id), rtags=tags.SystemID, resourceName=name) on resourceId
| join kind=leftouter (controlsAssessmentsData | project controlData, controlName) on controlName
| project
subscription,
resourceGroup,
resourceName,
resourceType=tostring(properties.resourceDetails.ResourceType),
SystemID=rtags,
recommendationSeverity=properties.metadata.severity,
recommendationStatus =properties.status.code,
recommendationName=properties.displayName,
description=properties.metadata.description,
remediationDescription=properties.metadata.remediationDescription,
portalLink=properties.links.azurePortal,
resourceId,
controlData,
unhealthyResourceCount,
healthyResourceCount,
controlMaxScore,
currentScore
Hoping to get the categories along with the individual unhealthy resources. Please advise, Serge
If I could get this query to show all the tags per resource, I could alter the csv to present what I need in a pivot table
securityresources
| where type == 'microsoft.security/assessments'
//above section will provide all information regarding on resources with status on recommendation.
| join kind=leftouter (resourcecontainers
| where type == 'microsoft.resources/subscriptions'
| project subscriptionId, subscription=name)
on subscriptionId
//above section will pull all the subscriptions along with the subID and create a column called subscription that will hold the actual name and not the ID
| extend resourceId = tolower(tostring(properties.resourceDetails.ResourceId))
| extend resourceTag = tags
//above will create a column all resourceId that will be mae of the resource ID from the assessments table
| join kind=leftouter (resources | project resourceId=tolower(id), tags, resourceName=name) on resourceId
//above join pulls from the resources table and collects tags based on resource and resource ID and then does a join wiht assessments.
| project
subscription,
resourceGroup,
resourceName,
resourceType=tostring(properties.resourceDetails.ResourceType),
tags,
recommendationSeverity=properties.metadata.severity,
recommendationStatus =properties.status.code,
recommendationName=properties.displayName,
description=properties.metadata.description,
remediationDescription=properties.metadata.remediationDescription,
portalLink=properties.links.azurePortal,
resourceId
Appreciate any assistance...This query is for Azure Resource Graph.
Share Improve this question edited 19 hours ago SergeT asked yesterday SergeTSergeT 196 bronze badges 1- 1 Are you trying to run it in Azure Resource Graph right! – Jahnavi Commented yesterday
1 Answer
Reset to default 0let
expression is a part of the KQL query statements and it is mainly used to simplify a complex expression into multiple parts, each of which is represented by a variable to continue with the query operations.
Refer MSDoc for more relevant information.
And as it is thrown an error, there are some limitations on working with the let
expression in Azure Resource Graph explorer.
Firstly, when using joins
operator with let
expression to create the variables and combine the queries based on their type and sub resource type as a single query. This operation is not allowed to perform in graph explorer.
As a workaround to this, you can use Union operator available in KQL to combine the queries.
Once it's done, now use Summarise operator which,
Produces a table that aggregates the content of the input table.
You can also remove some parts of the query which is not required mainly to reduce the query partitions.
Saying that, I've modified your query accordingly to execute in my environment as shown below with join
and summarise
operators and worked as expected.
securityresources
| where type == "microsoft.security/assessments"
| extend controlName = name
| extend unhealthyResourceCount = toint(properties.unhealthyResourceCount)
| project controlName, unhealthyResourceCount
| join kind=leftouter (
securityresources
| where type == "microsoft.security/assessments/subassessments"
| extend resourceId = tolower(tostring(properties.resourceDetails.ResourceId))
| extend recommendationSeverity = tostring(properties.metadata.severity)
| project resourceId, recommendationSeverity
) on $left.controlName == $right.resourceId
| summarize
totalUnhealthyResources = sum(unhealthyResourceCount),
severities = make_list(recommendationSeverity)
by controlName
| project controlName, totalUnhealthyResources, severities
Output:
本文标签: resolve kql quotLetquot clause for Azure Resource Graph ExplorerStack Overflow
版权声明:本文标题:resolve kql "Let" clause for Azure Resource Graph Explorer - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736600173a1945206.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论