<# .SYNOPSIS ¿Qué opciones de mis políticas anti-phishing, Safe Links y Safe Attachments están débiles? .DESCRIPTION Compara cada política con el nivel Standard que Microsoft recomienda y lista las opciones por debajo. Las opciones que el cmdlet no devuelve se omiten, y si tu licencia no incluye Safe Links o Safe Attachments, el reporte lo indica en vez de fallar. Solo lectura: no cambia nada en el tenant. .PARAMETER RutaCsv Ruta del CSV de salida. Si se omite, solo se muestra en pantalla. .EXAMPLE .\get-politicas-antiphishing.ps1 -RutaCsv .\politicas.csv .NOTES Permisos: Ninguno de Graph; usa roles de Exchange Online (ExchangeOnlineManagement) Rol mínimo: Lector de seguridad Licencia: Anti-phishing básico en todo buzón en la nube. Safe Links, Safe Attachments y protección contra suplantación requieren Microsoft Defender for Office 365 Plan 1 o superior (Plan 1 viene en Microsoft 365 Business Premium) Licencia del código: MIT. Se entrega TAL CUAL, sin garantía. Pruébalo primero en un tenant de pruebas. #> [CmdletBinding()] param( [string]$RutaCsv ) $ErrorActionPreference = 'Stop' if (-not (Get-Command Connect-ExchangeOnline -ErrorAction SilentlyContinue)) { throw 'Falta el módulo. Instálalo con: Install-Module ExchangeOnlineManagement -Scope CurrentUser' } Connect-ExchangeOnline -ShowBanner:$false # Debil lista los valores por debajo de Standard en "Recommended settings for EOP and Defender for Office 365". function Regla($opcion, $debil, $recomendado, $riesgo, $efecto) { @{ Opcion = $opcion; Debil = $debil; Recomendado = $recomendado; Riesgo = $riesgo; Efecto = $efecto } } $revisiones = @( @{ Tipo = 'Anti-phishing' Cmdlet = 'Get-AntiPhishPolicy' Reglas = @( Regla 'Enabled' @($false) 'True' 'Alto' 'La política está apagada.' Regla 'EnableSpoofIntelligence' @($false) 'True' 'Alto' 'No se detecta la suplantación de remitentes.' Regla 'HonorDmarcPolicy' @($false) 'True' 'Medio' 'No se respeta la política DMARC del dominio que envía.' Regla 'EnableFirstContactSafetyTips' @($false) 'True' 'Bajo' 'No se avisa al recibir correo de un remitente nuevo.' Regla 'EnableUnauthenticatedSender' @($false) 'True' 'Bajo' 'No se marca al remitente sin autenticar.' Regla 'EnableViaTag' @($false) 'True' 'Bajo' 'No se muestra la etiqueta "via".' Regla 'PhishThresholdLevel' @(1, 2) '3 o más' 'Medio' 'El umbral de phishing es menos agresivo que el recomendado.' Regla 'EnableTargetedUserProtection' @($false) 'True, con lista de usuarios' 'Alto' 'No se protege a usuarios clave de la suplantación.' Regla 'EnableOrganizationDomainsProtection' @($false) 'True' 'Alto' 'No se protegen tus dominios de la suplantación.' Regla 'EnableTargetedDomainsProtection' @($false) 'True, con lista de dominios' 'Medio' 'No se protegen dominios de socios o proveedores.' Regla 'EnableMailboxIntelligence' @($false) 'True' 'Medio' 'La inteligencia de buzón está apagada.' Regla 'EnableMailboxIntelligenceProtection' @($false) 'True' 'Medio' 'La inteligencia de buzón no actúa contra la suplantación.' Regla 'TargetedUserProtectionAction' @('NoAction') 'Quarantine' 'Alto' 'La suplantación de usuarios se detecta, pero no se actúa.' Regla 'TargetedDomainProtectionAction' @('NoAction') 'Quarantine' 'Alto' 'La suplantación de dominios se detecta, pero no se actúa.' Regla 'MailboxIntelligenceProtectionAction' @('NoAction') 'MoveToJmf' 'Medio' 'Lo que detecta la inteligencia de buzón no recibe acción.' Regla 'EnableSimilarUsersSafetyTips' @($false) 'True' 'Bajo' 'No se avisa de usuarios parecidos.' Regla 'EnableSimilarDomainsSafetyTips' @($false) 'True' 'Bajo' 'No se avisa de dominios parecidos.' Regla 'EnableUnusualCharactersSafetyTips' @($false) 'True' 'Bajo' 'No se avisa de caracteres inusuales en el remitente.' ) } @{ Tipo = 'Safe Links' Cmdlet = 'Get-SafeLinksPolicy' Reglas = @( Regla 'EnableSafeLinksForEmail' @($false) 'True' 'Alto' 'Safe Links no revisa las ligas del correo.' Regla 'EnableSafeLinksForTeams' @($false) 'True' 'Medio' 'Safe Links no revisa las ligas de Microsoft Teams.' Regla 'EnableSafeLinksForOffice' @($false) 'True' 'Medio' 'Safe Links no revisa las ligas en aplicaciones de Office.' Regla 'EnableForInternalSenders' @($false) 'True' 'Medio' 'No se revisan las ligas del correo interno: una cuenta tomada las puede repartir.' Regla 'ScanUrls' @($false) 'True' 'Alto' 'No se analizan en tiempo real las ligas sospechosas.' Regla 'DeliverMessageAfterScan' @($false) 'True' 'Medio' 'El correo se entrega antes de terminar de analizar sus ligas.' Regla 'DisableUrlRewrite' @($true) 'False' 'Medio' 'Las ligas no se reescriben, así que dependen solo de la revisión por API.' Regla 'TrackClicks' @($false) 'True' 'Medio' 'No se registran los clics, y pierdes la evidencia para investigar.' Regla 'AllowClickThrough' @($true) 'False' 'Alto' 'El usuario puede seguir a la liga original aunque Safe Links lo advierta.' ) } @{ Tipo = 'Safe Attachments' Cmdlet = 'Get-SafeAttachmentPolicy' Reglas = @( Regla 'Enable' @($false) 'True' 'Alto' 'La política no analiza adjuntos.' Regla 'Action' @('Allow') 'Block' 'Alto' 'Los adjuntos con malware se entregan: el modo Monitor solo observa.' ) } ) $filas = try { foreach ($revision in $revisiones) { if (-not (Get-Command $revision.Cmdlet -ErrorAction SilentlyContinue)) { [pscustomobject]@{ Tipo = $revision.Tipo; Politica = '-'; Opcion = '-'; ValorActual = '-'; Recomendado = '-'; Riesgo = '-'; Hallazgo = "No disponible: $($revision.Cmdlet) no existe en tu sesión. Revisa la licencia o el rol." } continue } foreach ($politica in & $revision.Cmdlet) { $debiles = @(foreach ($regla in $revision.Reglas) { $valor = $politica.($regla.Opcion) # Null significa que tu licencia o la versión del cmdlet no expone esa opción. if ($null -eq $valor -or $valor -notin $regla.Debil) { continue } [pscustomobject]@{ Tipo = $revision.Tipo; Politica = $politica.Name; Opcion = $regla.Opcion; ValorActual = "$valor"; Recomendado = $regla.Recomendado; Riesgo = $regla.Riesgo; Hallazgo = $regla.Efecto } }) if ($debiles) { $debiles } else { [pscustomobject]@{ Tipo = $revision.Tipo; Politica = $politica.Name; Opcion = '-'; ValorActual = '-'; Recomendado = '-'; Riesgo = '-'; Hallazgo = 'Sin debilidades frente a Standard' } } } } } finally { Disconnect-ExchangeOnline -Confirm:$false } $hallazgos = @($filas | Where-Object Opcion -NE '-') Write-Host "Opciones débiles: $($hallazgos.Count). Riesgo alto: $(@($hallazgos | Where-Object Riesgo -EQ 'Alto').Count)" if ($RutaCsv) { # UTF-8 con BOM para que Excel en español muestre bien los acentos. $filas | Export-Csv -Path $RutaCsv -NoTypeInformation -Encoding utf8BOM Write-Host "CSV guardado en $RutaCsv" } else { $filas | Format-Table -AutoSize }