Exchange Online: eliminar correos por Message‑ID con PowerShell, Compliance Search y Defender

Cuando un mensaje de phishing, malware o información confidencial se cuela en varios buzones de Exchange Online, la reacción debe ser rápida y certera. El identificador único de cada correo (Message‑ID o InternetMessageId) parece el candidato perfecto para aislar y eliminar ese único mensaje en toda la organización. Sin embargo, hoy no existe un único cmdlet de PowerShell que, partiendo solo del ID, lo busque y lo purgue masivamente. En este artículo se explica por qué, qué alternativas oficiales existen y cómo combinarlas para lograr el mismo resultado con total seguridad.

Índice

Por qué centrarse en el Message‑ID

El Message‑ID es una cadena generada por el servidor de origen que, en teoría, identifica de forma inequívoca un correo electrónico en todo Internet. A diferencia de otros metadatos como asunto o fecha, es un valor inmutable y normalmente único, por lo que:

  • Evita falsos positivos cuando el asunto es genérico o hay reenvíos masivos.
  • Permite rastrear el mismo mensaje a través de distintos dominios y sistemas de transporte.
  • Facilita la correlación con Threat Intelligence externos.

No obstante, algunas herramientas de Microsoft 365 todavía no pueden filtrar directamente por esta propiedad, lo que obliga a planificar rutas de purga alternativas.

Métodos disponibles y sus límites

EscenarioCmdlets / HerramientaVentajasLímites y requisitos
Análisis de transporteGet‑MessageTrace -MessageId "<id>"Encuentra el mensaje en los registros de flujoSolo consulta; no borra nada.
Borrado masivo en líneaNew‑ComplianceSearch → Start‑ComplianceSearch → New‑ComplianceSearchAction -PurgeMétodo oficial para suprimir correos en todos los buzonesNo admite la propiedad Message‑ID; solo Subject, From, To, Received, etc.
Borrado por buzón (legado)Search‑Mailbox … -DeleteContentPuede filtrar por MessageID: en un solo buzónObsoleto, con futuro retiro y limitado a <10 000 buzones.
Seguridad (GUI/API)Defender for Office 365 – Threat Explorer / Real‑time detectionsFiltro directo por InternetMessageId y acciones Soft/Hard deleteRequiere licencia Plan 2/E5 y roles de seguridad.
Automatización finaMicrosoft Graph / EWSPermite buscar internetMessageId y borrar por scriptHay que iterar buzones; complejidad en permisos y paginación.

Ruta recomendada cuando Compliance Search no acepta Message‑ID

A falta de un filtro directo, el truco consiste en construir una consulta basada en otros metadatos que, combinados, identifiquen de forma fiable al mensaje:

  1. Extraer metadatos clave. Usa Get‑MessageTrace o Explorer para obtener asunto, remitente y la fecha de recepción.
  2. Crear la búsqueda.
New-ComplianceSearch -Name "Purga‑Phish‑20250825" -ExchangeLocation All `
  -ContentMatchQuery 'subject:"Revisa tu cuenta" AND received:2025-08-24'
  1. Iniciar y validar.
Start-ComplianceSearch -Identity "Purga‑Phish‑20250825"
Get-ComplianceSearch -Identity "Purga‑Phish‑20250825" | FL
  1. Purga irreversible. Solo cuando estés seguro.
New-ComplianceSearchAction -SearchName "Purga‑Phish‑20250825" `
  -Purge -PurgeType SoftDelete   # o HardDelete

Límites importantes:

  • Máximo 10 elementos por buzón y 50 000 buzones por búsqueda.
  • Roles requeridos: Compliance Search y Search And Purge.
  • Para eliminar definitivamente, ejecuta el Managed Folder Assistant o espera la expiración de Retention Policies.

¿SoftDelete o HardDelete?

SoftDelete mueve los elementos a la carpeta Recoverable Items\Deletions; los usuarios no los ven, pero los administradores aún pueden restaurar durante la retención legal. HardDelete los salta directamente a Purge, haciéndolos inaccesibles para todos salvo eDiscovery. Selecciona según el nivel de riesgo y los requisitos de auditoría.

Uso de Defender for Office 365 para purgas por Message‑ID

Si dispones de licencias P2/E5, Threat Explorer ofrece la vía más rápida:

  1. Abre Defender Portal › Email & Collaboration › Explorer.
  2. Agrega el filtro Internet message ID y pega el valor completo <…>.
  3. Selecciona todos los resultados y elige Soft delete o Hard delete. Opcionalmente, crea una etiqueta de incidente.

Tras unos minutos, cada buzón afectado registra la acción en MailboxAuditLog con la operación HardDelete o SoftDelete, lo que facilita la trazabilidad.

Automatización con Microsoft Graph

Cuando el volumen de buzones es asumible o no se dispone de P2, se puede iterar usuario por usuario:

$tenantId = "<id‑tenant>"
Connect-MgGraph -Scopes "Mail.ReadWrite", "User.Read.All"

$users = Get-MgUser -Filter "mail ne null" -All | Select-Object -ExpandProperty UserPrincipalName
$targetId = "<message-id>"   # Incluir los < >

foreach ($u in $users) {
    $msg = Get-MgUserMessage -UserId $u -Filter "internetMessageId eq '$targetId'"
    foreach ($m in $msg) {
        Remove-MgUserMessage -UserId $u -MessageId $m.Id
        Write-Host "Purged $($m.Id) from $u"
    }
}

Aspectos clave:

  • Permisos. Se necesita una app registration con Mail.ReadWrite.All o similar.
  • Paginación. Usa @odata.nextLink si esperas más de 100 mensajes por buzón.
  • Control de errores. Implementa reintentos y control de throttling.

Comparativa de licencias, roles y escalabilidad

MétodoLicencia mínimaRoles necesariosEscalabilidadAuditoría
Compliance SearchExchange Online Plan 2 (incluido en E3)Compliance Search
Search And Purge
50 000 buzones × 10 itemsAudit.General; registros en PurgeStats
Threat ExplorerDefender for Office 365 Plan 2 o M365 E5Security Admin / Threat Investigator>200 000 buzonesMailboxAuditLog, UnifiedAuditLog
Microsoft GraphCualquier; app con permisosN/D (app‑only)Limitado por throttling (10 000 llamadas/minuto)MailboxAuditLog individual

Buenas prácticas antes de purgar

  • Prueba en un entorno piloto. Clona al menos un buzón real en una cuenta de prueba para verificar los filtros.
  • Validación 100 %. Revisa la muestra aleatoria de resultados con Get-ComplianceSearch -Preview.
  • Comunicación. Informa al equipo de soporte y a legal antes de usar HardDelete; podría afectar a investigaciones.
  • Registro. Exporta logs de auditoría antes y después; sirven de evidencia y evitan disputas de usuario.
  • Revisión post‑purga. Ejecuta Threat Analytics o tu SIEM para confirmar que no quedan copias residuales.

Preguntas frecuentes

¿Puedo restaurar un mensaje después de HardDelete?
No. Solo un eDiscovery con Legal Hold previo podría retenerlo. De lo contrario, el elemento pasa a la carpeta Purge y es purgado permanentemente al completarse la retención.

¿Search-Mailbox sigue funcionando?
Sí, pero Microsoft lo retirará en los próximos años. Además, no escala y no registra acciones en Unified Audit Log.

¿Hay límite de tamaño de mensaje para la purga?
El límite de elementos por búsqueda se refiere a cantidad, no a tamaño. Sin embargo, si el mensaje supera 150 MB no será indexado y es posible que no aparezca en Compliance Search.

¿Qué ocurre con buzones compartidos o archivados?
Compliance Search incluye primary, archive y buzones de grupo si usas -ExchangeLocation All. Threat Explorer también los muestra siempre que tengan Exchange Online como backend.

Conclusiones

Hoy por hoy, no existe un cmdlet “todo en uno” que use solo el Message‑ID para encontrar y purgar un correo en toda la organización. La estrategia óptima depende de las licencias y del tiempo de respuesta requerido:

  • Volumen masivo y rapidez: Threat Explorer (Defender P2) con filtrado directo y acciones de un clic.
  • Licencia estándar: Compliance Search con metadatos alternativos (asunto, remitente, fecha), validación exhaustiva y Soft/Hard Delete.
  • Casos puntuales o automatización granular: Script con Microsoft Graph o EWS iterando buzones.

Independientemente del método, valida siempre antes de purgar y documenta cada paso. Una purga mal filtrada es irreversible y puede comprometer pruebas legales o forenses.

Índice