DefenderConfigAssessment.psm1

# Define the functions to be included in the module

function Connect-Graph {
    try {
        Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Yellow
        $WarningPreference = 'SilentlyContinue'
        Connect-MgGraph -Scopes "DeviceManagementConfiguration.Read.All" -NoWelcome | Out-Null
        $WarningPreference = 'Continue'
        Write-Host "Connected to Microsoft Graph successfully." -ForegroundColor Green
    } catch {
        Write-Host "Failed to connect to Microsoft Graph. Exiting script." -ForegroundColor Red
        exit
    }
}

function Get-DeviceConfigurationProfiles {
    Write-Host "Retrieving device configuration profiles from Intune..." -ForegroundColor Yellow
    $profiles = Get-MgDeviceManagementDeviceConfiguration -All
    return $profiles
}

function Get-DefenderConfiguration {
    Write-Host "Retrieving Defender for Endpoint configuration..." -ForegroundColor Yellow
    $defenderConfig = Get-MpPreference
    return $defenderConfig
}

function Convert-ASRValue {
    param (
        [int]$value
    )

    switch ($value) {
        0 { return "Not configured or Disabled" }
        1 { return "Block" }
        2 { return "Audit" }
        6 { return "Warn" }
        default { return "Unknown" }
    }
}

function Convert-SettingValue {
    param (
        [string]$setting,
        [int]$value
    )

    switch ($setting) {
        "MAPSReporting" {
            switch ($value) {
                0 { return "Disabled" }
                1 { return "Basic" }
                2 { return "Advanced" }
                default { return "Unknown" }
            }
        }
        default { return $value }
    }
}

function Get-TenantInformation {
    Write-Host "Retrieving tenant information..." -ForegroundColor Yellow
    $tenant = Get-MgOrganization | Select-Object DisplayName
    return $tenant
}

function Test-DefenderConfiguration {
    param (
        [Parameter(Mandatory=$true)]
        [PSCustomObject]$config,
        [Parameter(Mandatory=$true)]
        [PSCustomObject]$tenantInfo
    )
    
    $evaluationResults = @()

    $bestPractices = @{
        "CloudProtection" = @{ Setting = "MAPSReporting"; Value = "Advanced" }
        "SampleSubmission" = @{ Setting = "SubmitSamplesConsent"; Value = "Always" }
        "BlockAtFirstSeen" = @{ Setting = "DisableBlockAtFirstSeen"; Value = 0 }
        "IOAVProtection" = @{ Setting = "DisableIOAVProtection"; Value = 0 }
        "CloudBlockLevel" = @{ Setting = "CloudBlockLevel"; Value = "High" }
        "RealtimeMonitoring" = @{ Setting = "DisableRealtimeMonitoring"; Value = 0 }
        "BehaviorMonitoring" = @{ Setting = "DisableBehaviorMonitoring"; Value = 0 }
        "ScriptScanning" = @{ Setting = "DisableScriptScanning"; Value = 0 }
        "RemovableDriveScanning" = @{ Setting = "DisableRemovableDriveScanning"; Value = 0 }
        "PUAProtection" = @{ Setting = "PUAProtection"; Value = "Enabled" }
        "ArchiveScanning" = @{ Setting = "DisableArchiveScanning"; Value = 0 }
        "EmailScanning" = @{ Setting = "DisableEmailScanning"; Value = 0 }
        "ControlledFolderAccess" = @{ Setting = "EnableControlledFolderAccess"; Value = "Enabled" }
        "NetworkProtection" = @{ Setting = "EnableNetworkProtection"; Value = "Enabled" }
        "ExploitProtection" = @{ Setting = "ProcessMitigation"; Value = "Configured" }
    }

    $asrRules = @{
        "56a863a9-875e-4185-98a7-b882c64b5ce5" = "Block abuse of exploited vulnerable signed drivers"
        "7674ba52-37eb-4a4f-a9a1-f0f9a1619a2c" = "Block Adobe Reader from creating child processes"
        "d4f940ab-401b-4efc-aadc-ad5f3c50688a" = "Block all Office applications from creating child processes"
        "9e6c4e1f-7d60-472f-ba1a-a39ef669e4b2" = "Block credential stealing from the Windows local security authority subsystem (lsass.exe)"
        "be9ba2d9-53ea-4cdc-84e5-9b1eeee46550" = "Block executable content from email client and webmail"
        "01443614-cd74-433a-b99e-2ecdc07bfc25" = "Block executable files from running unless they meet a prevalence, age, or trusted list criterion"
        "5beb7efe-fd9a-4556-801d-275e5ffc04cc" = "Block execution of potentially obfuscated scripts"
        "d3e037e1-3eb8-44c8-a917-57927947596d" = "Block JavaScript or VBScript from launching downloaded executable content"
        "3b576869-a4ec-4529-8536-b80a7769e899" = "Block Office applications from creating executable content"
        "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84" = "Block Office applications from injecting code into other processes"
        "26190899-1602-49e8-8b27-eb1d0a1ce869" = "Block Office communication application from creating child processes"
        "e6db77e5-3df2-4cf1-b95a-636979351e5b" = "Block persistence through WMI event subscription"
        "d1e49aac-8f56-4280-b9ba-993a6d77406c" = "Block process creations originating from PSExec and WMI commands"
        "33ddedf1-c6e0-47cb-833e-de6133960387" = "Block rebooting machine in Safe Mode (preview)"
        "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4" = "Block untrusted and unsigned processes that run from USB"
        "c0033c00-d16d-4114-a5a0-dc9b3a7d2ceb" = "Block use of copied or impersonated system tools (preview)"
        "a8f5898e-1dc8-49a9-9878-85004b8a61e6" = "Block Webshell creation for Servers"
        "92e97fa1-2edf-4476-bdd6-9dd0b4dddc7b" = "Block Win32 API calls from Office macros"
        "c1db55ab-c21a-4637-bb3f-a12568109d35" = "Use advanced protection against ransomware"
    }

    foreach ($bp in $bestPractices.GetEnumerator()) {
        $setting = $bp.Value.Setting
        $expectedValue = $bp.Value.Value
        $actualValue = Convert-SettingValue -setting $setting -value $config.$setting

        $result = [PSCustomObject]@{
            TenantName    = $tenantInfo.DisplayName
            Setting       = $setting
            ExpectedValue = $expectedValue
            ActualValue   = $actualValue
            Compliant     = $actualValue -eq $expectedValue
        }

        $evaluationResults += $result
    }

    foreach ($rule in $asrRules.GetEnumerator()) {
        $ruleId = $rule.Key
        $ruleName = $rule.Value
        $actualValueCode = if ($config.AttackSurfaceReductionRules_Ids -contains $ruleId) { 1 } else { 0 }
        $expectedValue = "Enabled"
        $actualValue = Convert-ASRValue -value $actualValueCode

        $result = [PSCustomObject]@{
            TenantName    = $tenantInfo.DisplayName
            Setting       = $ruleName
            ExpectedValue = $expectedValue
            ActualValue   = $actualValue
            Compliant     = $actualValue -eq $expectedValue
        }

        $evaluationResults += $result
    }

    return $evaluationResults
}

function Export-Results {
    param (
        [Parameter(Mandatory=$true)]
        [PSCustomObject[]]$results,
        [Parameter(Mandatory=$true)]
        [string]$outputPath
    )

    Write-Host "Exporting results to CSV..." -ForegroundColor Yellow
    $results | Export-Csv -Path $outputPath -NoTypeInformation
    Write-Host "Results exported to $outputPath" -ForegroundColor Green
}

function Show-Banner {
    $banner = @"
##########################################
# #
# Defender Configuration Assessment #
# #
##########################################
 
Column Explanation:
-------------------
TenantName: The name of the tenant the assessment was performed on.
Setting: The specific configuration setting or ASR rule.
ExpectedValue: The recommended value for the setting.
                - 0: Not configured or Disabled
                - 1: Block
                - 2: Audit
                - 6: Warn
ActualValue: The current value of the setting.
                - 0: Not configured or Disabled
                - 1: Block
                - 2: Audit
                - 6: Warn
Compliant: Indicates whether the current value is compliant with the recommended value (True/False).
 
"@

    Write-Host $banner -ForegroundColor Cyan
}

function Start-DefenderConfigAssessment {
    try {
        # Display the banner
        Show-Banner

        # Connect to Microsoft Graph
        Connect-Graph 2>&1 | Out-Null

        # Get tenant information
        $tenantInfo = Get-TenantInformation

        # Get device configuration profiles
        $profiles = Get-DeviceConfigurationProfiles

        # Get Defender configuration
        $defenderConfig = Get-DefenderConfiguration

        # Evaluate configuration
        $evaluationResults = Test-DefenderConfiguration -config $defenderConfig -tenantInfo $tenantInfo

        # Export results
        $outputPath = "DefenderConfigurationAssessmentResults.csv"
        Export-Results -results $evaluationResults -outputPath $outputPath

        Write-Host "Assessment completed successfully." -ForegroundColor Green

    } catch {
        Write-Host "An error occurred: $_" -ForegroundColor Red
    }
}