Azure 资源图查询 - 按订阅名称列出策略状态
Azure Resource Graph Query - List policy state by subscription name
我的目标是创建一个 Azure 仪表板小部件,其中包含订阅列表及其相应的策略状态。
+-------------------+-------+-----------+--------+---------------+------------+
| Subscription name | Total | Compliant | Exempt | Non-compliant | Percentage |
+-------------------+-------+-----------+--------+---------------+------------+
| foo-subscription | 300 | 270 | 0 | 30 | 0.9 |
| bar-subscription | 100 | 80 | 0 | 20 | 0.8 |
+-------------------+-------+-----------+--------+---------------+------------+
为此,我正在使用 Azure 资源图查询。
我能够列出与订阅 ID 相关的策略状态。但与订阅名称无关。
这个查询
policyresources
| extend complianceState=tostring(properties['complianceState']), resourceId=tostring(properties['resourceId'])
| project subscriptionId, complianceState, resourceId
| summarize complianceStates=make_list(complianceState) by subscriptionId, resourceId
| summarize Total = count()
, Compliant = countif((complianceStates notcontains "NonCompliant") and (complianceStates contains "Compliant"))
, Exempt = countif((complianceStates notcontains "NonCompliant") and (complianceStates notcontains "Compliant") and (complianceStates contains "Exempt"))
, NonCompliant = countif (complianceStates contains "NonCompliant")
by subscriptionId
| extend OverallCompliancePerc = round(toreal(Compliant + Exempt) / toreal(Total), 2)
| order by OverallCompliancePerc desc
导致
+--------------------+-------+-----------+--------+---------------+------------+
| Subscription-ID | Total | Compliant | Exempt | Non-compliant | Percentage |
+--------------------+-------+-----------+--------+---------------+------------+
| b4757628-9b24-447a | 300 | 270 | 0 | 30 | 0.9 |
| 86fa64ae-6c30-4157 | 100 | 80 | 0 | 20 | 0.8 |
+--------------------+-------+-----------+--------+---------------+------------+
kusto 语言允许 join tables. However, the kusto language allows the join only for Resources and ResourceContainer tables。不适用于政策资源。
是否可以创建与订阅名称相关的table?
这是一个很好的查询,感谢您的分享。
如果您 运行 在 Azure Resource Graph Explorer 中查询,结果出现,结果上方有一个滑块开关 header 标题为“格式化结果”,切换到开,这会将 SubscriptionId 替换为订阅名称。
有联合方法,但我遇到了困难而且速度很慢。这是一个例子:
Resources
| summarize resourceCount=count() by subscriptionId
| join (ResourceContainers | where type=='microsoft.resources/subscriptions' | project SubName=name, subscriptionId) on subscriptionId
| project-away subscriptionId, subscriptionId1
如果从 PowerShell 运行ning,这是我用来将 subscriptionId 解析为 SubscriptionName 的方法:
# Create a Hash Table for lookups of SubscriptionName by subscriptionId
$LkUpSubs = @{}
For ($sub in (Get-AzSubscription)) {
$LkUpSubs.Add($sub.Id, $sub.Name)
}
// In the Kusto Query, Add and include SubscriptionName in the | project statement
| extend SubscriptionName = ''
# Run Search-AzGraph and assign output to a variable like $results
# Enrich the results
ForEach ($rec in $results) {
$rec.SubscriptionName = $LkUpSub[$rec.subscriptionId]
}
这是一个基于您的查询的工作示例:
$LkUpSubs = @{}
ForEach ($sub in (Get-AzSubscription)) {
$LkUpSubs.Add($sub.Id, $sub.Name)
}
$Query = "policyresources | where tolower(properties.policyAssignmentName) != 'securitycenterbuiltIn'
| extend complianceState=tostring(properties['complianceState']), resourceId=tostring(properties['resourceId'])
| project subscriptionId, complianceState, resourceId
| summarize complianceStates=make_list(complianceState) by subscriptionId, resourceId
| summarize Total = count()
, Compliant = countif((complianceStates notcontains 'NonCompliant') and (complianceStates contains 'Compliant'))
, Exempt = countif((complianceStates notcontains 'NonCompliant') and (complianceStates notcontains 'Compliant') and (complianceStates contains 'Exempt'))
, NonCompliant = countif (complianceStates contains 'NonCompliant') by subscriptionId
| extend OverallCompliancePerc = round(toreal(Compliant + Exempt) / toreal(Total), 2)
| extend SubscriptionName = ''
| project SubscriptionName, subscriptionId, Total, Compliant, Exempt, NonCompliant, OverallCompliancePerc
| order by OverallCompliancePerc desc
"
$Results = Search-AzGraph -Query $Query -First 5000
ForEach ($rec in $Results) {
$rec.SubscriptionName = $LkUpSubs[$rec.subscriptionId]
}
$TimeStamp = (Get-Date -Format 'yyyy-MMdd-HHmm')
$FilePath = ('C:\Temp\ComplianceReports\ResourceCompliance_CountsBySubscription_{0}.csv' -f $TimeStamp)
$Results |
Sort-Object -Property SubscriptionName |
Select-Object -Property SubscriptionName, Total, Compliant, NonCompliant, OverallCompliancePerc |
Export-Csv -Path $FilePath -Encoding UTF8 -Delimiter ',' -NoTypeInformation -Force
祝你好运
很棒的查询,您为我节省了很多时间。我对您的查询进行了一些调整,试图让最后的合规性结果尽可能接近门户仪表板,但速度更快。
policyresources
| extend complianceState=tostring(properties['complianceState']), resourceId=tostring(properties['resourceId']),timestamp=todatetime(tostring(properties['timestamp'])),policyDefinitionName=tostring(properties['policyDefinitionName'])
| where timestamp > ago(1d)
| project subscriptionId, complianceState, resourceId, timestamp,policyDefinitionName
| summarize max(timestamp) by subscriptionId, resourceId,complianceState,policyDefinitionName
| summarize complianceStates=make_list(complianceState) by subscriptionId, resourceId
| summarize Total = count()
, Compliant = countif((complianceStates notcontains "NonCompliant") and (complianceStates contains "Compliant"))
, Exempt = countif((complianceStates notcontains "NonCompliant") and (complianceStates notcontains "Compliant") and (complianceStates contains "Exempt"))
, ['Non-Compliant'] = countif (complianceStates contains "NonCompliant")
by subscriptionId
| extend ['Compliance %'] = round(toreal(Compliant + Exempt)*100 / toreal(Total), 2)
| order by ['Compliance %'] desc
我的目标是创建一个 Azure 仪表板小部件,其中包含订阅列表及其相应的策略状态。
+-------------------+-------+-----------+--------+---------------+------------+
| Subscription name | Total | Compliant | Exempt | Non-compliant | Percentage |
+-------------------+-------+-----------+--------+---------------+------------+
| foo-subscription | 300 | 270 | 0 | 30 | 0.9 |
| bar-subscription | 100 | 80 | 0 | 20 | 0.8 |
+-------------------+-------+-----------+--------+---------------+------------+
为此,我正在使用 Azure 资源图查询。 我能够列出与订阅 ID 相关的策略状态。但与订阅名称无关。
这个查询
policyresources
| extend complianceState=tostring(properties['complianceState']), resourceId=tostring(properties['resourceId'])
| project subscriptionId, complianceState, resourceId
| summarize complianceStates=make_list(complianceState) by subscriptionId, resourceId
| summarize Total = count()
, Compliant = countif((complianceStates notcontains "NonCompliant") and (complianceStates contains "Compliant"))
, Exempt = countif((complianceStates notcontains "NonCompliant") and (complianceStates notcontains "Compliant") and (complianceStates contains "Exempt"))
, NonCompliant = countif (complianceStates contains "NonCompliant")
by subscriptionId
| extend OverallCompliancePerc = round(toreal(Compliant + Exempt) / toreal(Total), 2)
| order by OverallCompliancePerc desc
导致
+--------------------+-------+-----------+--------+---------------+------------+
| Subscription-ID | Total | Compliant | Exempt | Non-compliant | Percentage |
+--------------------+-------+-----------+--------+---------------+------------+
| b4757628-9b24-447a | 300 | 270 | 0 | 30 | 0.9 |
| 86fa64ae-6c30-4157 | 100 | 80 | 0 | 20 | 0.8 |
+--------------------+-------+-----------+--------+---------------+------------+
kusto 语言允许 join tables. However, the kusto language allows the join only for Resources and ResourceContainer tables。不适用于政策资源。
是否可以创建与订阅名称相关的table?
这是一个很好的查询,感谢您的分享。
如果您 运行 在 Azure Resource Graph Explorer 中查询,结果出现,结果上方有一个滑块开关 header 标题为“格式化结果”,切换到开,这会将 SubscriptionId 替换为订阅名称。
有联合方法,但我遇到了困难而且速度很慢。这是一个例子:
Resources
| summarize resourceCount=count() by subscriptionId
| join (ResourceContainers | where type=='microsoft.resources/subscriptions' | project SubName=name, subscriptionId) on subscriptionId
| project-away subscriptionId, subscriptionId1
如果从 PowerShell 运行ning,这是我用来将 subscriptionId 解析为 SubscriptionName 的方法:
# Create a Hash Table for lookups of SubscriptionName by subscriptionId
$LkUpSubs = @{}
For ($sub in (Get-AzSubscription)) {
$LkUpSubs.Add($sub.Id, $sub.Name)
}
// In the Kusto Query, Add and include SubscriptionName in the | project statement
| extend SubscriptionName = ''
# Run Search-AzGraph and assign output to a variable like $results
# Enrich the results
ForEach ($rec in $results) {
$rec.SubscriptionName = $LkUpSub[$rec.subscriptionId]
}
这是一个基于您的查询的工作示例:
$LkUpSubs = @{}
ForEach ($sub in (Get-AzSubscription)) {
$LkUpSubs.Add($sub.Id, $sub.Name)
}
$Query = "policyresources | where tolower(properties.policyAssignmentName) != 'securitycenterbuiltIn'
| extend complianceState=tostring(properties['complianceState']), resourceId=tostring(properties['resourceId'])
| project subscriptionId, complianceState, resourceId
| summarize complianceStates=make_list(complianceState) by subscriptionId, resourceId
| summarize Total = count()
, Compliant = countif((complianceStates notcontains 'NonCompliant') and (complianceStates contains 'Compliant'))
, Exempt = countif((complianceStates notcontains 'NonCompliant') and (complianceStates notcontains 'Compliant') and (complianceStates contains 'Exempt'))
, NonCompliant = countif (complianceStates contains 'NonCompliant') by subscriptionId
| extend OverallCompliancePerc = round(toreal(Compliant + Exempt) / toreal(Total), 2)
| extend SubscriptionName = ''
| project SubscriptionName, subscriptionId, Total, Compliant, Exempt, NonCompliant, OverallCompliancePerc
| order by OverallCompliancePerc desc
"
$Results = Search-AzGraph -Query $Query -First 5000
ForEach ($rec in $Results) {
$rec.SubscriptionName = $LkUpSubs[$rec.subscriptionId]
}
$TimeStamp = (Get-Date -Format 'yyyy-MMdd-HHmm')
$FilePath = ('C:\Temp\ComplianceReports\ResourceCompliance_CountsBySubscription_{0}.csv' -f $TimeStamp)
$Results |
Sort-Object -Property SubscriptionName |
Select-Object -Property SubscriptionName, Total, Compliant, NonCompliant, OverallCompliancePerc |
Export-Csv -Path $FilePath -Encoding UTF8 -Delimiter ',' -NoTypeInformation -Force
祝你好运
很棒的查询,您为我节省了很多时间。我对您的查询进行了一些调整,试图让最后的合规性结果尽可能接近门户仪表板,但速度更快。
policyresources
| extend complianceState=tostring(properties['complianceState']), resourceId=tostring(properties['resourceId']),timestamp=todatetime(tostring(properties['timestamp'])),policyDefinitionName=tostring(properties['policyDefinitionName'])
| where timestamp > ago(1d)
| project subscriptionId, complianceState, resourceId, timestamp,policyDefinitionName
| summarize max(timestamp) by subscriptionId, resourceId,complianceState,policyDefinitionName
| summarize complianceStates=make_list(complianceState) by subscriptionId, resourceId
| summarize Total = count()
, Compliant = countif((complianceStates notcontains "NonCompliant") and (complianceStates contains "Compliant"))
, Exempt = countif((complianceStates notcontains "NonCompliant") and (complianceStates notcontains "Compliant") and (complianceStates contains "Exempt"))
, ['Non-Compliant'] = countif (complianceStates contains "NonCompliant")
by subscriptionId
| extend ['Compliance %'] = round(toreal(Compliant + Exempt)*100 / toreal(Total), 2)
| order by ['Compliance %'] desc