Power BI에 클라우드용 Defender 데이터 추가
클라우드용 Microsoft Defender의 데이터를 Microsoft Power BI와 연결하면 보안 메트릭을 쉽게 모니터링하고 분석할 수 있습니다. 통합을 통해 보안 인사이트를 시각화하고 잠재적인 위협과 취약성을 신속하게 식별할 수 있습니다. 이 문서에서는 복잡한 보안 정보를 명확하고 실행 가능한 인사이트로 변환하는 데 도움이 되는 Defender for Cloud 데이터를 Power BI에 연결하는 단계를 안내합니다.
Azure Resource Graph에 액세스할 수 있는 올바른 권한이 있는지 확인합니다.
클라우드용 Defender의 데이터를 Power BI에 연결하려면 먼저 Power BI를 Azure Resource Graph에 연결해야 합니다.
데스크톱에서 Power BI Desktop을 엽니다.
빈 보고서를 선택합니다.
데이터 가져오기>더 보기를 선택합니다.
Azure Resource Graph를 검색하여 선택합니다.
연결을 선택합니다.
Power BI Desktop이 Azure Resource Graph에 연결되면, Azure 리소스 그래프를 사용하여 클라우드용 Defender의 다양한 데이터 원본을 Power BI로 쿼리할 수 있습니다.
이 페이지에 제공된 쿼리는 결과를 제공하는 예시입니다. Azure Resource Graph를 사용하면 특정 요구 사항에 맞는 결과를 반환하도록 생성하고 사용자 지정할 수 있는 광범위한 데이터를 쿼리할 수 있습니다.
제공된 쿼리 중 하나를 복사하여 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
확인을 선택합니다.
로드를 선택합니다.
Azure Resource Graph를 사용하면 클라우드용 Defender 환경 내에서 사용 가능한 모든 데이터를 유연하게 검색하고 분석하여 포괄적이고 맞춤화된 인사이트를 확보할 수 있습니다. 데이터를 Power BI에 추가하면 비주얼리제이션과 대시보드를 만들어 보안 상태를 효과적으로 모니터링하고 관리할 수 있습니다.