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.
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.csvObtiene 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
- Abre PowerShell 7 e instala el módulo si no lo tienes: Install-Module Microsoft.Graph.Authentication -Scope CurrentUser
- Corre el script con -RutaCsv e inicia sesión con una cuenta con el rol Lector de informes.
- Abre el CSV y revisa primero las filas con EsAdministrador en Sí.
- 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
}