Saltar al contenido
Microsoft scripts

Scripts de Entra

Usuarios sin MFA registrado

Lista a los usuarios habilitados que no han registrado un método de MFA, con los administradores hasta arriba. Te dice a quién perseguir antes de exigir MFA.

Antes de correrloEl reporte no incluye cuentas deshabilitadas y puede tardar hasta 36 horas en reflejar un registro nuevo. No refleja MFA registrado fuera de Microsoft Entra ID, como un proveedor externo. Si el error dice que el tenant no tiene licencia premium aun teniéndola, Microsoft indica que puede ser intermitente cuando solo se concede AuditLog.Read.All.

Ejemplo en México

Despacho contable en Guadalajara, 35 personas

Se acerca el cierre fiscal y el despacho quiere exigir MFA con acceso condicional, pero no sabe quién se quedaría sin poder entrar el día que lo active.

.\get-usuarios-sin-mfa.ps1 -RutaCsv .\sin-mfa.csv

Obtiene seis nombres, uno de ellos administrador. Les pide registrar el método esa semana y activa la política hasta que la lista queda vacía.

Cómo implementarlo

  1. Abre PowerShell 7 e instala el módulo si no lo tienes: Install-Module Microsoft.Graph.Authentication -Scope CurrentUser
  2. Corre el script con -RutaCsv e inicia sesión con una cuenta con el rol Lector de informes.
  3. Abre el CSV y revisa primero las filas con EsAdministrador en Sí.
  4. Pide a esas personas que registren un método de MFA y vuelve a correr el reporte al día siguiente para confirmar el avance.
Ver el código completo de get-usuarios-sin-mfa.ps1
<#
.SYNOPSIS
    ¿Qué usuarios habilitados no tienen un método de MFA registrado?

.DESCRIPTION
    Lee el reporte de registro de métodos de autenticación y lista a quienes aparecen sin MFA registrado.
    Te dice a quién pedirle que registre un método antes de exigir MFA con acceso condicional.
    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-usuarios-sin-mfa.ps1 -RutaCsv .\sin-mfa.csv

.NOTES
    Permisos: AuditLog.Read.All
    Rol mínimo: Lector de informes (Reports Reader)
    Licencia: Microsoft Entra ID P1
    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'
$permisos = @('AuditLog.Read.All')

if (-not (Get-Command Connect-MgGraph -ErrorAction SilentlyContinue)) {
    throw 'Falta el módulo. Instálalo con: Install-Module Microsoft.Graph.Authentication -Scope CurrentUser'
}
Connect-MgGraph -Scopes $permisos -NoWelcome

$uri = 'https://graph.microsoft.com/v1.0/reports/authenticationMethods/userRegistrationDetails?$filter=isMfaRegistered eq false'
$registros = while ($uri) {
    $pagina = Invoke-MgGraphRequest -Method GET -Uri $uri
    $pagina.value
    $uri = $pagina.'@odata.nextLink'
}

$filas = foreach ($r in $registros) {
    $metodos = @($r.methodsRegistered) | Where-Object { $_ }
    [pscustomobject]@{
        Nombre             = $r.userDisplayName
        Cuenta             = $r.userPrincipalName
        Tipo               = if ($r.userType -eq 'guest') { 'Invitado' } else { 'Miembro' }
        EsAdministrador    = if ($r.isAdmin) { 'Sí' } else { 'No' }
        MetodosRegistrados = if ($metodos) { $metodos -join '; ' } else { 'Ninguno' }
    }
}
# Los administradores sin MFA son lo primero que hay que atender.
$filas = $filas | Sort-Object @{ Expression = 'EsAdministrador'; Descending = $true }, Nombre

Write-Host "Usuarios sin MFA registrado: $(@($filas).Count)"
if ($RutaCsv) {
    # Excel ejecutaría como fórmula un nombre que empiece con estos caracteres.
    foreach ($fila in $filas) { foreach ($p in $fila.PSObject.Properties) { if ($p.Value -is [string] -and $p.Value -match '^[=+\-@]') { $p.Value = "'" + $p.Value } } }
    # 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
}

Relacionados