Modules/Public/InventoryModules/Security/DefenderSecureScore.ps1

<#
.Synopsis
Inventory for Microsoft Defender for Cloud Secure Score
 
.DESCRIPTION
This script consolidates Secure Score data from Microsoft Defender for Cloud.
Captures overall secure score, security controls, max scores, and current achievements.
Excel Sheet Name: Defender Secure Score
 
.Link
https://github.com/thisismydemo/azure-scout/Modules/Public/InventoryModules/Security/DefenderSecureScore.ps1
 
.COMPONENT
This powershell Module is part of Azure Scout (AZSC)
 
.NOTES
Version: 1.0.0
First Release Date: February 24, 2026
Authors: AzureScout Contributors
 
#>


<######## Default Parameters. Don't modify this ########>

param($SCPath, $Sub, $Intag, $Resources, $Retirements, $Task ,$File, $SmaResources, $TableStyle, $Unsupported)

If ($Task -eq 'Processing')
{
    <######### Insert the resource extraction here ########>

        # Get secure score data from Microsoft Defender for Cloud
        $secureScores = @()

        foreach ($subscription in $Sub) {
            Write-AZSCLog -Message " >> Processing Defender Secure Score for subscription: $($subscription.Name)" -Color 'Cyan'

            try {
                $subScore = Get-AzSecuritySecureScore -ErrorAction SilentlyContinue
                if ($subScore) {
                    $secureScores += $subScore | ForEach-Object {
                        $_ | Add-Member -NotePropertyName 'SubscriptionId' -NotePropertyValue $subscription.Id -Force -PassThru
                    }
                }
            } catch {
                Write-AZSCLog -Message " Failed to retrieve secure score: $_" -Color 'Yellow'
            }
        }

    <######### Insert the resource Process here ########>

    if($secureScores)
        {
            $tmp = foreach ($1 in $secureScores) {
                $ResUCount = 1
                $sub1 = $SUB | Where-Object { $_.Id -eq $1.SubscriptionId }
                $data = $1

                # Calculate score percentage
                $currentScore = if ($data.Score.Current) { [math]::Round($data.Score.Current, 2) } else { 0 }
                $maxScore = if ($data.Score.Max) { [math]::Round($data.Score.Max, 2) } else { 0 }
                $scorePercentage = if ($maxScore -gt 0) {
                    [math]::Round(($currentScore / $maxScore) * 100, 2)
                } else { 0 }

                # Get security controls
                $securityControls = @()
                if ($data.Score.Percentage -ne $null) {
                    try {
                        $controls = Get-AzSecuritySecureScoreControl -ErrorAction SilentlyContinue
                        if ($controls) {
                            foreach ($control in $controls) {
                                $controlScore = if ($control.Score.Current) { [math]::Round($control.Score.Current, 2) } else { 0 }
                                $controlMax = if ($control.Score.Max) { [math]::Round($control.Score.Max, 2) } else { 0 }
                                $controlPercentage = if ($controlMax -gt 0) {
                                    [math]::Round(($controlScore / $controlMax) * 100, 2)
                                } else { 0 }

                                $securityControls += [PSCustomObject]@{
                                    ControlName = $control.DisplayName
                                    CurrentScore = $controlScore
                                    MaxScore = $controlMax
                                    Percentage = $controlPercentage
                                    HealthyResources = if ($control.Score.HealthyResourceCount) { $control.Score.HealthyResourceCount } else { 0 }
                                    UnhealthyResources = if ($control.Score.UnhealthyResourceCount) { $control.Score.UnhealthyResourceCount } else { 0 }
                                }
                            }
                        }
                    } catch {
                        Write-AZSCLog -Message " Failed to retrieve security controls: $_" -Color 'Yellow'
                    }
                }

                $obj = @{
                    'ID'                        = $1.Name;
                    'Subscription'              = $sub1.Name;
                    'Secure Score Name'         = $data.DisplayName;
                    'Current Score'             = $currentScore;
                    'Max Score'                 = $maxScore;
                    'Score Percentage'          = "$scorePercentage%";
                    'Healthy Resources'         = if ($data.Score.HealthyResourceCount) { $data.Score.HealthyResourceCount } else { 0 };
                    'Unhealthy Resources'       = if ($data.Score.UnhealthyResourceCount) { $data.Score.UnhealthyResourceCount } else { 0 };
                    'Not Applicable Resources'  = if ($data.Score.NotApplicableResourceCount) { $data.Score.NotApplicableResourceCount } else { 0 };
                    'Weight'                    = if ($data.Weight) { $data.Weight } else { 'N/A' };
                    'Portal Link'               = "https://portal.azure.com/#blade/Microsoft_Azure_Security/SecurityMenuBlade/SecureScore";
                    'Resource U'                = $ResUCount;
                }
                $obj
                if ($ResUCount -eq 1) { $ResUCount = 0 }
            }
            $tmp
        }
}

<######## Resource Excel Reporting Begins Here ########>

Else
{
    <######## $SmaResources.(RESOURCE FILE NAME) ##########>

    if($SmaResources)
    {

        $TableName = ('DefenderScoreTable_'+(($SmaResources.'Resource U' | Measure-Object -Sum).Sum))
        $Style = New-ExcelStyle -HorizontalAlignment Center -AutoSize -NumberFormat '0'

        # Conditional formatting for low scores
        $condLowScore = New-ConditionalText -ConditionalType LessThan -Text '50' -Range F:F -BackgroundColor '#FFC7CE' -ConditionalTextColor '#9C0006'

        $Exc = New-Object System.Collections.Generic.List[System.Object]
        $Exc.Add('Subscription')
        $Exc.Add('Secure Score Name')
        $Exc.Add('Current Score')
        $Exc.Add('Max Score')
        $Exc.Add('Score Percentage')
        $Exc.Add('Healthy Resources')
        $Exc.Add('Unhealthy Resources')
        $Exc.Add('Not Applicable Resources')
        $Exc.Add('Weight')
        $Exc.Add('Portal Link')
        $Exc.Add('Resource U')

        [PSCustomObject]$SmaResources |
        ForEach-Object { $_ } | Select-Object $Exc |
        Export-Excel -Path $File -WorksheetName 'Defender Secure Score' -AutoSize -MaxAutoSizeRows 100 -TableName $TableName -TableStyle $tableStyle -Style $Style -ConditionalText $condLowScore

    }
}