Hinzufügen von Defender for Cloud Daten zu Power BI

Du kannst Microsoft Defender for Cloud Daten mit Microsoft Power BI verbinden. Nutzen Sie dieses Setup, um Sicherheitskennzahlen zu verfolgen und Bedrohungen zu erkennen. Dieser Artikel zeigt, wie Sie Defender for Cloud mit Power BI verknüpfen und aus Ihren Sicherheitsdaten klare Bilder erstellen können. Bevor Sie beginnen, überprüfen Sie die Voraussetzungen , um sicherzustellen, dass Sie die erforderlichen Einrichtungen und Berechtigungen haben.

Voraussetzungen

Bevor Sie Defender for Cloud Daten mit Power BI verbinden, stellen Sie sicher, dass Sie die folgenden Voraussetzungen erfüllen:

Verbinden von Power BI mit Azure Resource Graph

So verbinden Sie Power BI mit Azure Resource Graph:

  1. Öffnen Sie auf Ihrem Desktop Power BI Desktop.

  2. Wählen Sie Leerer Bericht aus.

  3. Wählen Sie Daten abrufen>Mehr aus.

    Screenshot des Power BI Desktop-Hauptbildschirms mit der Schaltfläche „Daten abrufen“ und der Option „Weitere Optionen“.

  4. Suchen Sie die Option Azure Resource Graph, und wählen Sie sie aus.

  5. Wählen Sie Verbinden aus.

Defender for Cloud-Daten in Power BI abfragen

Verwenden Sie Azure Resource Graph-Abfragen in Power BI, um Defender for Cloud-Daten abzurufen. So fragen Sie Defender for Cloud Daten in Power BI ab:

Defender for Cloud-Abfragen ausführen

Sobald Power BI Desktop mit Azure Resource Graph verbunden ist, können Sie Azure Resource Graph verwenden, um verschiedene Datenquellen aus Defender for Cloud in Power BI abzufragen.

Die folgenden Beispielanfragen sind Beispiele, die Beispielergebnisse liefern. Azure Resource Graph unterstützt viele Datenabfragen, und Sie können sie an Ihre Anforderungen anpassen.

  1. Kopieren und fügen Sie eine der bereitgestellten Abfragen in den Abfrage-Editor in Power BI Desktop ein.

    Diese Abfrage ruft Sicherheitsempfehlungen nach Risiko von Defender for Cloud ab, sodass Sie Bewertungen analysieren und Bereiche identifizieren können, die Aufmerksamkeit benötigen.

    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. Wählen Sie "OK" aus.

    Der Screenshot zeigt, wo die Azure Resource Graph-Abfrage einzugeben ist und wo die Schaltfläche „OK“ platziert ist.

    Note

    Standardmäßig sind in Resource Graph alle Abfragen so beschränkt, dass nur 1.000 Datensätze zurückgegeben werden. Durch diese Steuerung werden sowohl Sie als auch der Dienst vor unbeabsichtigten Abfragen geschützt, die zu großen Datasets führen. Wenn Sie möchten, dass die Abfrageergebnisse nicht durch die Begrenzung auf 1.000 Datensätze abgeschnitten werden, setzen Sie den Wert von „Erweiterte Option - $resultTruncated (optional)“ auf FALSE.

    Der Screenshot zeigt, wo sich die erweiterten Optionen befinden und wie sie auf „false“ festgelegt werden.

  3. Wählen Sie und laden Sie.

Nächste Schritte