Udostępnij za pośrednictwem


Dodawanie danych Defender dla Chmury do usługi Power BI

Łącząc dane Microsoft Defender dla Chmury z usługą Microsoft Power BI, można łatwo monitorować i analizować metryki zabezpieczeń. Integracja umożliwia wizualizowanie szczegółowych informacji o zabezpieczeniach i szybkie identyfikowanie potencjalnych zagrożeń i luk w zabezpieczeniach. W tym artykule przedstawiono procedurę łączenia Defender dla Chmury danych z usługą Power BI, co ułatwia przekształcanie złożonych informacji o zabezpieczeniach w czytelne, praktyczne szczegółowe informacje.

Wymagania wstępne

Łączenie usługi Power BI z usługą Azure Resource Graph

Aby połączyć dane Defender dla Chmury z usługą Power BI, musisz najpierw połączyć usługę Power BI z usługą Azure Resource Graph.

  1. Na pulpicie otwórz program Power BI Desktop.

  2. Wybierz pozycję Pusty raport.

  3. Wybierz pozycję Pobierz dane>więcej.

    Zrzut ekranu głównego programu Power BI Desktop pokazujący, gdzie znajduje się przycisk Pobierz dane, i więcej opcji.

  4. Wyszukaj i wybierz pozycję Azure Resource Graph.

  5. Wybierz pozycję Połącz.

Wykonywanie zapytań Defender dla Chmury danych w usłudze Power BI

Gdy program Power BI Desktop jest połączony z usługą Azure Resource Graph, możesz użyć usługi Azure Resource Graph do wykonywania zapytań o różne źródła danych z Defender dla Chmury do usługi Power BI.

Zapytania podane na tej stronie to przykłady, które dostarczają wyniki. Usługa Azure Resource Graph umożliwia wykonywanie zapytań dotyczących szerokiego zakresu danych, które można tworzyć i dostosowywać w celu zwracania wyników odpowiadających konkretnym wymaganiom.

  1. Skopiuj i wklej jedno z podanych zapytań do edytora zapytań w programie Power BI Desktop.

    To zapytanie pobiera zalecenia dotyczące zabezpieczeń według ryzyka z usługi MDC, co umożliwia analizowanie ocen i identyfikowanie obszarów wymagających uwagi.

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

    Zrzut ekranu pokazujący, gdzie należy wprowadzić zapytanie usługi Azure Resource Graph i gdzie znajduje się przycisk OK.

    Uwaga

    Domyślnie usługa Resource Graph ogranicza wszystkie zapytania do zwracania tylko 1000 rekordów. Ta kontrolka chroni zarówno Użytkownika, jak i usługę przed niezamierzonymi zapytaniami, które mogłyby spowodować duże zestawy danych. Jeśli chcesz, aby wyniki zapytania nie są obcinane przez limit 1000 rekordów, ustaw wartość "Opcja zaawansowana — $resultTruncated (opcjonalnie)" na WARTOŚĆ FALSE.

    Zrzut ekranu przedstawiający lokalizację opcji zaawansowanych i sposób ustawiania jej na wartość false.

  3. Wybierz Załaduj.

Usługa Azure Resource Graph zapewnia elastyczność pobierania i analizowania wszystkich danych dostępnych w środowisku Defender dla Chmury, zapewniając kompleksowe i dostosowane szczegółowe informacje. Po dodaniu danych do usługi Power BI możesz tworzyć wizualizacje i pulpity nawigacyjne w celu efektywnego monitorowania stanu zabezpieczeń i zarządzania nim.

Następny krok