Saltar al contenido
Microsoft scripts

Scripts de Defender

Microsoft Secure Score y su tendencia

Da tu puntuación actual de Secure Score, el porcentaje alcanzado y el cambio día con día, para reportar avance con números.

Antes de correrloUna caída no siempre es una falla tuya: Microsoft también agrega y cambia recomendaciones, y eso mueve el máximo. Compara también la columna Maximo. El rol se asigna en Microsoft Entra ID, porque Microsoft indica que el RBAC unificado de Defender aún no aplica a Secure Score por Graph.

Ejemplo en México

Logística y transporte en Monterrey, 120 personas

El corporativo pide cada mes la evidencia de que la postura de seguridad mejora, y el administrador la armaba a mano con capturas de pantalla.

.\get-puntuacion-seguridad.ps1 -Dias 30 -RutaCsv .\puntuacion.csv

Obtiene el historial del mes en un CSV y grafica la tendencia para la reunión con el corporativo.

Cómo implementarlo

  1. Instala el módulo si no lo tienes: Install-Module Microsoft.Graph.Authentication -Scope CurrentUser.
  2. Corre el script con -Dias y el periodo que vas a reportar.
  3. Inicia sesión con una cuenta con el rol Lector de seguridad.
  4. Revisa la columna Cambio: investiga las caídas y lleva la tendencia a tu reporte mensual.
Ver el código completo de get-puntuacion-seguridad.ps1
<#
.SYNOPSIS
    ¿Cuál es mi Microsoft Secure Score hoy y cómo ha cambiado en los últimos días?

.DESCRIPTION
    Muestra la puntuación más reciente, el porcentaje alcanzado y el cambio día con día en los
    últimos N días. Sirve para reportar avance a la dirección o al corporativo.
    Solo lectura: no cambia nada en el tenant.

.PARAMETER Dias
    Días de historial. Por defecto, 30.

.PARAMETER RutaCsv
    Ruta del CSV de salida. Si se omite, solo se muestra en pantalla.

.EXAMPLE
    .\get-puntuacion-seguridad.ps1 -Dias 90 -RutaCsv .\puntuacion.csv

.NOTES
    Permisos: SecurityEvents.Read.All
    Rol mínimo: Lector de seguridad
    Licencia: Sin plan específico: Secure Score muestra recomendaciones de los productos que tengas con licencia (Microsoft Entra ID, Exchange Online, Microsoft Defender, entre otros). Aplica a 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(
    [ValidateRange(1, 365)]
    [int]$Dias = 30,
    [string]$RutaCsv
)

$ErrorActionPreference = 'Stop'
$permisos = @('SecurityEvents.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

function ConvertirUtc($valor) {
    if ($valor -is [datetime]) { $valor.ToUniversalTime() } else { ([datetimeoffset]"$valor").UtcDateTime }
}

# Un registro por día; se pide uno de más para calcular el cambio del primer día mostrado.
$uri = "https://graph.microsoft.com/v1.0/security/secureScores?`$top=$($Dias + 1)"
$puntuaciones = while ($uri) {
    $pagina = Invoke-MgGraphRequest -Method GET -Uri $uri
    $pagina.value
    $uri = $pagina.'@odata.nextLink'
}

$historial = @($puntuaciones | Sort-Object { ConvertirUtc $_.createdDateTime } -Descending | Select-Object -First ($Dias + 1))
[array]::Reverse($historial)

$anterior = $null
$filas = foreach ($p in $historial) {
    $puntos = [double]$p.currentScore
    $maximo = [double]$p.maxScore
    [pscustomobject]@{
        Fecha      = (ConvertirUtc $p.createdDateTime).ToString('yyyy-MM-dd')
        Puntos     = $puntos
        Maximo     = $maximo
        Porcentaje = if ($maximo) { [math]::Round($puntos / $maximo * 100, 1) } else { $null }
        Cambio     = if ($null -ne $anterior) { ($puntos - $anterior).ToString('+0.##;-0.##;0') } else { $null }
    }
    $anterior = $puntos
}

if ($filas) {
    $primera = @($filas)[0]
    $actual = @($filas)[-1]
    Write-Host "Puntuación actual: $($actual.Puntos) de $($actual.Maximo) ($($actual.Porcentaje) %) al $($actual.Fecha)"
    Write-Host "Cambio desde $($primera.Fecha): $(($actual.Puntos - $primera.Puntos).ToString('+0.##;-0.##;0')) puntos"
} else {
    Write-Host 'Graph no devolvió puntuaciones para este tenant.'
}
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
}

Relacionados