<# .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 }