你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将 Defender for Cloud 数据添加到 Power BI

通过将 Microsoft Defender for Cloud 的数据与 Microsoft Power BI 连接,你可以轻松监视和分析安全指标。 通过集成,你可以可视化安全见解并快速识别潜在威胁和漏洞。 本文指导你完成将 Defender for Cloud 数据连接到 Power BI 的步骤,帮助你将复杂的安全信息转换为清晰、可操作的见解。

先决条件

将 Power BI 连接到 Azure Resource Graph

必须先将 Power BI 连接到 Azure Resource Graph,然后才能将 Defender for Cloud 的数据连接到 Power BI。

  1. 在桌面上打开 Power BI Desktop。

  2. 选择空白报表

  3. 选择获取数据>更多

    Power BI Desktop 主屏幕的屏幕截图,其中显示了“获取数据”按钮的位置以及更多选项。

  4. 搜索并选择 Azure Resource Graph

  5. 选择“连接” 。

在 Power BI 中查询 Defender for Cloud 数据

将 Power BI Desktop 连接到 Azure Resource Graph 后,你可以使用 Azure Resource Graph 在 Power BI 中查询 Defender for Cloud 的各种数据源。

本页提供的查询是提供结果的示例。 Azure Resource Graph 允许你查询各种数据,你可以创建和自定义这些数据以返回适合您特定要求的结果。

  1. 将提供的查询之一复制并粘贴到 Power BI Desktop 内的查询编辑器中。

    此查询从 MDC 按风险检索安全建议,让你能够分析评估并确定需要关注的领域。

    securityresources 
            | where type =~ "microsoft.security/assessments"
            | extend assessmentType = iff(type == "microsoft.security/assessments", tostring(properties.metadata.assessmentType), dynamic(null))
            | where (type == "microsoft.security/assessments" and (assessmentType in~ ("BuiltIn", "CustomerManaged")))
            | extend assessmentTypeSkimmed = iff(type == "microsoft.security/assessments", case(
                        tostring(properties.metadata.assessmentType) == "BuiltIn", "BuiltIn",
                        tostring(properties.metadata.assessmentType) == "BuiltInPolicy", "BuiltIn",
                        tostring(properties.metadata.assessmentType) == "CustomPolicy", "Custom",
                        tostring(properties.metadata.assessmentType) == "CustomerManaged", "Custom",
                        tostring(properties.metadata.assessmentType) == "ManualCustomPolicy", "Custom",
                        tostring(properties.metadata.assessmentType) == "ManualBuiltInPolicy", "BuiltIn",
                        dynamic(null)
                    ), dynamic(null))
            | extend assessmentId = tolower(id)
            | extend assessmentKey = iff(type == "microsoft.security/assessments", name, dynamic(null))
            | extend source = iff(type == "microsoft.security/assessments", trim(' ', tolower(tostring(properties.resourceDetails.Source))), dynamic(null))
            | extend statusCode = iff(type == "microsoft.security/assessments", tostring(properties.status.code), dynamic(null))
            | extend resourceId = iff(type == "microsoft.security/assessments", trim(" ", tolower(tostring(case(source =~ "azure", properties.resourceDetails.Id,
                (type == "microsoft.security/assessments" and (source =~ "aws" and isnotempty(tostring(properties.resourceDetails.ConnectorId)))), properties.resourceDetails.Id,
                (type == "microsoft.security/assessments" and (source =~ "gcp" and isnotempty(tostring(properties.resourceDetails.ConnectorId)))), properties.resourceDetails.Id,
                source =~ "aws", properties.resourceDetails.AzureResourceId,
                source =~ "gcp", properties.resourceDetails.AzureResourceId,
                extract("^(?i)(.+)/providers/Microsoft.Security/assessments/.+$",1,id)
                )))), dynamic(null))
            | extend resourceName = iff(type == "microsoft.security/assessments", tostring(coalesce(properties.resourceDetails.ResourceName, properties.additionalData.CloudNativeResourceName, properties.additionalData.ResourceName, properties.additionalData.resourceName, split(resourceId, '/')[-1], extract(@"(.+)/(.+)", 2, resourceId))), dynamic(null))
            | extend resourceType = iff(type == "microsoft.security/assessments", tolower(properties.resourceDetails.ResourceType), dynamic(null))
            | extend riskLevelText = iff(type == "microsoft.security/assessments", tostring(properties.risk.level), dynamic(null))
            | extend riskLevel = iff(type == "microsoft.security/assessments", case(riskLevelText =~ "Critical", 4,
                      riskLevelText =~ "High", 3,
                      riskLevelText =~ "Medium", 2,
                      riskLevelText =~ "Low", 1,
                      0), dynamic(null))
            | extend riskFactors = iff(type == "microsoft.security/assessments", iff(isnull(properties.risk.riskFactors), dynamic([]), properties.risk.riskFactors), dynamic(null))
            | extend attackPaths = array_length(iff(type == "microsoft.security/assessments", iff(isnull(properties.risk.attackPathsReferences), dynamic([]), properties.risk.attackPathsReferences), dynamic(null)))           
            | extend displayName = iff(type == "microsoft.security/assessments", tostring(properties.displayName), dynamic(null))
            | extend statusCause = iff(type == "microsoft.security/assessments", tostring(properties.status.cause), dynamic(null))
            | extend isExempt = iff(type == "microsoft.security/assessments", iff(statusCause == "Exempt", tobool(1), tobool(0)), dynamic(null))
            | extend statusChangeDate = tostring(iff(type == "microsoft.security/assessments", todatetime(properties.status.statusChangeDate), dynamic(null)))
            | project assessmentId,
                        statusChangeDate,
                        isExempt,
                        riskLevel,
                        riskFactors,
                        attackPaths,
                        statusCode,
                        displayName,
                        resourceId,               
                        assessmentKey,
                        resourceType,
                        resourceName,
                        assessmentTypeSkimmed               
                | join kind=leftouter (
                    securityresources
                    | where type == 'microsoft.security/assessments/governanceassignments'
                    | extend assignedResourceId = tolower(iff(type == "microsoft.security/assessments/governanceassignments", tostring(properties.assignedResourceId), dynamic(null)))
                    | extend dueDate = iff(type == "microsoft.security/assessments/governanceassignments", todatetime(properties.remediationDueDate), dynamic(null))
                    | extend owner = iff(type == "microsoft.security/assessments/governanceassignments", iff(isempty(tostring(properties.owner)), "unspecified", tostring(properties.owner)), dynamic(null))
                    | extend governanceStatus = iff(type == "microsoft.security/assessments/governanceassignments", case(
                                isnull(todatetime(properties.remediationDueDate)), "NoDueDate",
                                todatetime(properties.remediationDueDate) >= bin(now(), 1d), "OnTime",
                                "Overdue"
                            ), dynamic(null))
                    | project assignedResourceId, dueDate, owner, governanceStatus
                ) on $left.assessmentId == $right.assignedResourceId
                | extend completionStatusNumber = case(governanceStatus == "Overdue", 5,
                                                           governanceStatus == "OnTime", 4,
                                                           statusCode == "Unhealthy", 3, 
                                                           isExempt, 7,
                                                           1)
                    | extend completionStatus = case(completionStatusNumber == 5, "Overdue",
                                                     completionStatusNumber == 4, "OnTime",
                                                     completionStatusNumber == 3, "Unassigned",
                                                     completionStatusNumber == 7, "Exempted",
                                                     "Completed")
                | where completionStatus in~ ("OnTime","Overdue","Unassigned")
                | project-away assignedResourceId, governanceStatus, isExempt
                           | order by riskLevel desc, attackPaths desc, displayName
    
  2. 选择“确定”。

    显示输入 Azure Resource Graph 查询的位置以及“确定”按钮所在位置的屏幕截图。

    注意

    默认情况下,Resource Graph 限制任何查询都只能返回 1,000 条记录。 这项控制措施可保护你和服务不受会生成大型数据集的意外查询影响。 如果你希望查询结果不会因 1000 条记录的限制而被截断,请将“高级选项 - $resultTruncated (可选)”的值设置为 FALSE。

    屏幕截图显示了高级选项的位置以及如何将其设置为 false。

  3. 选择“加载”

借助 Azure Resource Graph,你可以灵活地检索和分析 Defender for Cloud 环境中提供的任何数据,确保获得全面的定制见解。 将数据添加到 Power BI 后,你可以创建可视化效果和仪表板,以有效地监视和管理安全状况。

下一步