Condividi tramite


Aggiungere i dati di Defender per il cloud a Power BI

Connettendo i dati di Microsoft Defender per il cloud a Microsoft Power BI, è possibile monitorare e analizzare facilmente le metriche di sicurezza. L'integrazione consente di visualizzare informazioni dettagliate sulla sicurezza e di identificare rapidamente le potenziali minacce e le vulnerabilità. Questo articolo illustra i passaggi per connettere i dati di Defender per il cloud a Power BI, favorendo la trasformazione di informazioni di sicurezza complesse in informazioni dettagliate chiare e fruibili.

Prerequisiti

Connettere Power BI ad Azure Resource Graph

Per poter connettere i dati di Defender per il cloud a Power BI, è necessario connettere prima Power BI ad Azure Resource Graph.

  1. Sul desktop aprire Power BI Desktop.

  2. Selezionare un report vuoto.

  3. Selezionare Recupera dati>altro.

    Screenshot della schermata principale di Power BI Desktop che mostra la posizione del pulsante Recupera dati e dell'opzione altro.

  4. Cercare e selezionare Azure Resource Graph.

  5. Selezionare Connetti.

Eseguire query sui dati di Defender per il cloud in Power BI

Dopo aver connesso Power BI Desktop ad Azure Resource Graph, è possibile usare Azure Resource Graph per eseguire query su varie origini dati da Defender per il cloud in Power BI.

Le query fornite in questa pagina sono esempi che forniscono risultati. Azure Resource Graph consente di eseguire query su un'ampia gamma di dati che è possibile creare e personalizzare per restituire risultati conformi ai propri requisiti.

  1. Copiare e incollare una delle query fornite nell'editor di query in Power BI Desktop.

    Questa query recupera le raccomandazioni sulla sicurezza in base al rischio da Data center modulare, consentendo di analizzare le valutazioni e di identificare le aree che richiedono attenzione.

    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. Selezionare OK.

    Screenshot che mostra dove immettere la query di Azure Resource Graph e dove si trova il pulsante OK.

    Nota

    Per impostazione predefinita, Resource Graph limita a 1000 record i risultati che possono essere restituiti da ogni query. Questo controllo protegge l'utente e il servizio da query non intenzionali che restituirebbero set di dati di grandi dimensioni. Se si desidera che i risultati delle query non vengano troncati dal limite di 1.000 record, impostare il valore di "Opzione avanzata - $resultTruncated (facoltativo)" su FALSE.

    Screenshot che mostra dove si trovano le opzioni avanzate e come impostarle su false.

  3. Seleziona Carica.

Azure Resource Graph garantisce la flessibilità necessaria per recuperare e analizzare i dati disponibili all'interno dell'ambiente Defender per il cloud, offrendo informazioni dettagliate complete e personalizzate. Dopo aver aggiunto i dati a Power BI, è possibile creare visualizzazioni e dashboard per monitorare e gestire in modo efficace la postura di sicurezza.

Passaggio successivo