Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defender Recommendations #325

Open
PixelRobots opened this issue Jan 22, 2025 · 6 comments · May be fixed by #330
Open

Defender Recommendations #325

PixelRobots opened this issue Jan 22, 2025 · 6 comments · May be fixed by #330
Assignees
Labels
enhancement New feature or request

Comments

@PixelRobots
Copy link

Describe the feature

It would be good to get defender recommendations with a link to the azure portal.

@cmendible
Copy link
Member

Hey @PixelRobots can you run the following ARG query and let us know if it's close to what you are looking for?

SecurityResources
| where type == 'microsoft.security/assessments'
| extend resourceId=id,
  recommendationId=name,
  resourceType=type,
  recommendationName=properties.displayName,
  source=properties.resourceDetails.Source,
  recommendationState=properties.status.code,
  description=properties.metadata.description,
  assessmentType=properties.metadata.assessmentType,
  remediationDescription=properties.metadata.remediationDescription,
  policyDefinitionId=properties.metadata.policyDefinitionId,
  implementationEffort=properties.metadata.implementationEffort,
  recommendationSeverity=properties.metadata.severity,
  category=properties.metadata.categories,
  userImpact=properties.metadata.userImpact,
  threats=properties.metadata.threats,
  portalLink=properties.links.azurePortal

@cmendible cmendible self-assigned this Jan 23, 2025
@PixelRobots
Copy link
Author

This is what i am using now to create a csv. I only want the unhealty recommendations you see. and more important information then everything else:

# Fetch the current tenant ID
$tenantId = (az account show --query tenantId -o tsv)
 
# Initialize variables
$MDC_Recommendations = @()
$pageSize = 1000
$iteration = 0
$skipCount = 0
 
# Define the Resource Graph query in a readable multiline format
$queryLines = @(
    "SecurityResources",
    "| where type == 'microsoft.security/assessments'",
    "| where properties.status.code == 'Unhealthy'",
    "| mvexpand Category = properties.metadata.categories",
    "| extend",
    "    AssessmentId = id,",
    "    AssessmentKey = name,",
    "    ResourceId = properties.resourceDetails.Id,",
    "    ResourceIdsplit = split(properties.resourceDetails.Id, '/'),",
    "    RecommendationName = properties.displayName,",
    "    RecommendationState = properties.status.code,",
    "    ActionDescription = properties.metadata.description,",
    "    RemediationDescription = properties.metadata.remediationDescription,",
    "    RecommendationSeverity = properties.metadata.severity,",
    "    PolicyDefinitionId = properties.metadata.policyDefinitionId,",
    "    AssessmentType = properties.metadata.assessmentType,",
    "    Threats = properties.metadata.threats,",
    "    UserImpact = properties.metadata.userImpact,",
    "    AzPortalLink = tostring(properties.links.azurePortal)",
    "| extend",
    "    ResourceSubId = tostring(ResourceIdsplit[2]),",
    "    ResourceGroupName = tostring(ResourceIdsplit[4]),",
    "    ResourceType = tostring(ResourceIdsplit[6]),",
    "    ResourceName = tostring(ResourceIdsplit[8])",
    "| join kind=leftouter (resourcecontainers",
    "    | where type == 'microsoft.resources/subscriptions'",
    "    | project SubscriptionName = name, subscriptionId) on subscriptionId",
    "| project SubscriptionName, ResourceGroupName, ResourceName, Category, RecommendationSeverity, RecommendationName, ActionDescription, RemediationDescription, AzPortalLink"
)
 
# Convert the query into a single line
$query = $queryLines -join " "
 
# Pagination logic
do {
    $iteration += 1
    Write-Verbose "Iteration #$iteration" -Verbose
 
    # Fetch a page of results
    $pageResultsJson = az graph query -q $query --first $pageSize --skip $skipCount --output json
    $pageResults = $pageResultsJson | ConvertFrom-Json
 
    # Extract data field and add to recommendations
    if ($pageResults.data) {
        $MDC_Recommendations += $pageResults.data
    }
 
    # Update skip count
    $skipCount += $pageResults.data.Count
} while ($pageResults.data.Count -eq $pageSize)
 
# Update AzPortalLink to include the tenantId in the URL
$MDC_Recommendations = $MDC_Recommendations | ForEach-Object {
    if ($_.AzPortalLink -match "portal.azure.com") {
        $_.AzPortalLink = $_.AzPortalLink -replace "portal.azure.com", "https://portal.azure.com/$tenantId"
    }
    $_
}
 
# Reorder and select columns explicitly
$OrderedRecommendations = $MDC_Recommendations | Select-Object `
    SubscriptionName, `
    ResourceGroupName, `
    ResourceName, `
    Category, `
    RecommendationSeverity, `
    RecommendationName, `
    ActionDescription, `
    RemediationDescription, `
    AzPortalLink
 
# Output summary
Write-Output "Total recommendations fetched: $($OrderedRecommendations.Count)"
 
# Export results to a CSV
$CsvPath = "UnhealthyRecommendations.csv"
$OrderedRecommendations | Export-Csv -Path $CsvPath -NoTypeInformation -Encoding UTF8
Write-Output "Recommendations exported to $CsvPath."
 
. ./$CsvPath

@cmendible cmendible linked a pull request Jan 23, 2025 that will close this issue
3 tasks
@cmendible
Copy link
Member

@PixelRobots my friend can you try the binaries from here: https://github.com/Azure/azqr/actions/runs/12928181677 and let me know if this works for you?

@PixelRobots
Copy link
Author

That works well. The only thing I would say is the azure portal link needs a bit of manipulation to add the https:// and the tenant ID in if possible. (The reason for the tenant id is when you have multiple tenants it makes it easier to connect to the right one).

Also, when running the scan, the subscription id is not shown when doing the recommendation part as in the image below:

Image

Thanks for this

@cmendible
Copy link
Member

That works well. The only thing I would say is the azure portal link needs a bit of manipulation to add the https:// and the tenant ID in if possible. (The reason for the tenant id is when you have multiple tenants it makes it easier to connect to the right one).

Also, when running the scan, the subscription id is not shown when doing the recommendation part as in the image below:

Image

Thanks for this

The scan runs in batch for "all" subscriptions and that's why logs show one line as for Costs, Defender Status and more.

Let me add the https:// to the link. Not sure about the tenant though...

@PixelRobots
Copy link
Author

Thanks. I can always add the tenant id my side if needed.

@cmendible cmendible added the enhancement New feature or request label Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants