次の方法で共有


Power BI に Defender for Cloud データを追加する

Microsoft Defender for Cloud のデータを Microsoft Power BI に接続することで、セキュリティ メトリックを簡単に監視および分析できます。 統合により、セキュリティの分析情報を視覚化し、潜在的な脅威と脆弱性をすばやく特定できます。 この記事では、Defender for Cloud データを Power BI に接続する手順について説明します。これにより、複雑なセキュリティ情報を明確で実用的な分析情報に変換できます。

前提条件

Power BI を Azure Resource Graph に接続する

Defender for Cloud のデータを Power BI に接続するには、まず Power BI を Azure Resource Graph に接続する必要があります。

  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 を使用して、Defender for Cloud から Power BI にさまざまなデータ ソースをクエリできます。

このページで提供されるクエリは、結果を提供する例です。 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. OK を選択します。

    Azure Resource Graph クエリを入力する場所と [OK] ボタンが配置されている場所を示すスクリーンショット。

    Note

    既定では、Resource Graph ではどのクエリも 1000 個のレコードしか返さないように制限されます。 このコントロールにより、ユーザーとサービスの両方が、大規模なデータ セットになる意図しないクエリから保護されます。 クエリ結果を 1,000 レコードの制限で切り捨てないようにするには、[詳細 オプション - $resultTruncated (オプション)] の値を [False] に設定します。

    詳細オプションが配置されている場所と、それを false に設定する方法を示すスクリーンショット。

  3. [読み込み] を選択します。

Azure Resource Graph を使用すると、Defender for Cloud 環境内で利用できるデータを柔軟に取得および分析でき、包括的で調整された分析情報が得られます。 データが Power BI に追加されたら、視覚化とダッシュボードを作成して、セキュリティ体制を効果的に監視および管理できます。

次のステップ