public/cis/Test-MtCisSafeAntiPhishingPolicy.ps1
|
<# .SYNOPSIS Checks if the anti-phishing policy matches CIS recommendations .DESCRIPTION The anti-phishing policy should be enabled, and the settings for PhishThresholdLevel, EnableMailboxIntelligenceProtection, EnableMailboxIntelligence, EnableSpoofIntelligence controls match CIS recommendations CIS Microsoft 365 Foundations Benchmark v5.0.0 .EXAMPLE Test-MtCisSafeAntiPhishingPolicy Returns true if the default anti-phishing policy matches CIS recommendations .LINK https://maester.dev/docs/commands/Test-MtCisSafeAntiPhishingPolicy #> function Test-MtCisSafeAntiPhishingPolicy { [CmdletBinding()] [OutputType([bool])] param() if (!(Test-MtConnection ExchangeOnline)) { Add-MtTestResultDetail -SkippedBecause NotConnectedExchange return $null } elseif (!(Test-MtConnection SecurityCompliance)) { Add-MtTestResultDetail -SkippedBecause NotConnectedSecurityCompliance return $null } elseif ('P1' -notin (Get-MtLicenseInformation -Product MdoV2)) { Add-MtTestResultDetail -SkippedBecause NotLicensedMdoP1 return $null } try { Write-Verbose 'Getting Anti Phishing Policy...' $policies = Get-MtExo -Request AntiPhishPolicy # We grab the default policy as that is what CIS checks $policy = $policies | Where-Object { $_.IsDefault -eq $true } $antiPhishingPolicyCheckList = @() # Enabled should be True $antiPhishingPolicyCheckList += [pscustomobject] @{ 'CheckName' = 'Enabled' 'Value' = 'True' } # EnableMailboxIntelligenceProtection should be True $antiPhishingPolicyCheckList += [pscustomobject] @{ 'CheckName' = 'EnableMailboxIntelligenceProtection' 'Value' = 'True' } # EnableMailboxIntelligence should be True $antiPhishingPolicyCheckList += [pscustomobject] @{ 'CheckName' = 'EnableMailboxIntelligence' 'Value' = 'True' } # EnableSpoofIntelligence should be True $antiPhishingPolicyCheckList += [pscustomobject] @{ 'CheckName' = 'EnableSpoofIntelligence' 'Value' = 'True' } Write-Verbose 'Executing checks' $failedCheckList = @() foreach ($check in $antiPhishingPolicyCheckList) { $checkResult = $policy | Where-Object { $_.($check.CheckName) -notmatch $check.Value } if ($checkResult) { #If the check fails, add it to the list so we can report on it later $failedCheckList += $check.CheckName } } # Custom check for PhishThresholdLevel # Because it is not exact match, the above logic won't work. Manual check to see if PhishThresholdLevel is 2 or greater if ($policy | Where-Object { $_.PhishThresholdLevel -le 1 }) { #If the check fails, add it to the list so we can report on it later $failedCheckList += 'PhishThresholdLevel' } # We didn't use this in the foreach loop above, but we need to add it now so we get results in the output for the separate check $antiPhishingPolicyCheckList += [pscustomobject] @{ 'CheckName' = 'PhishThresholdLevel' } $testResult = ($failedCheckList | Measure-Object).Count -eq 0 $portalLink = 'https://security.microsoft.com/antiphishing' if ($testResult) { $testResultMarkdown = "Well done. Your tenants default anti-phishing policy matches CIS recommendations($portalLink).`n`n%TestResult%" } else { $testResultMarkdown = "Your tenants default anti-phishing policy does not match CIS recommendations ($portalLink).`n`n%TestResult%" } $resultMd = "| Check Name | Result |`n" $resultMd += "| --- | --- |`n" foreach ($item in $antiPhishingPolicyCheckList) { $itemResult = '❌ Fail' if ($item.CheckName -notin $failedCheckList) { $itemResult = '✅ Pass' } $resultMd += "| $($item.CheckName) | $($itemResult) |`n" } $testResultMarkdown = $testResultMarkdown -replace '%TestResult%', $resultMd Add-MtTestResultDetail -Result $testResultMarkdown return $testResult } catch { Add-MtTestResultDetail -SkippedBecause Error -SkippedError $_ return $null } } |