Skip to content
Regresar

Reporte Visual Automatizado para Windows Server Backup

Publicado:3/6/2025 at 02:09 p. m.

Reporte Visual Automatizado para Windows Server Backup

En la administración de servidores Windows, la gestión de respaldos es una tarea fundamental. Sin embargo, quienes utilizan Windows Server Backup se encuentran con una limitación importante: no existe una forma nativa de generar reportes visuales y exportables sobre el estado y el historial de los respaldos realizados. La información queda dispersa en logs y comandos, lo que dificulta la auditoría, el monitoreo y la presentación de resultados a otros equipos o clientes.

El problema: Sin reportes visuales nativos

A diferencia de soluciones empresariales de backup, Windows Server Backup no ofrece una interfaz ni una función para exportar fácilmente un resumen de los respaldos realizados, su estado, las máquinas virtuales protegidas y otros detalles relevantes en un formato amigable como HTML o PDF. Esto representa un reto para quienes necesitan:

  • Presentar evidencia de respaldos exitosos o fallidos.
  • Auditar la protección de datos.
  • Compartir información clara y visual con otros equipos o clientes.

La solución: Script automatizado en PowerShell

Para suplir esta carencia, he desarrollado un script automatizado en PowerShell que recopila la información de los respaldos recientes y la presenta en un reporte visual en formato HTML y PDF. Este script:

  • Extrae los últimos respaldos realizados, mostrando fecha, hora, estado y detalles de cada job.
  • Obtiene la lista de máquinas virtuales respaldadas y el tamaño de cada una, utilizando el comando wbadmin get items.
  • Genera un archivo HTML visualmente atractivo y fácil de leer.
  • Exporta automáticamente el reporte a PDF usando Microsoft Edge en modo headless.
  • Permite la automatización total mediante el Programador de Tareas de Windows, generando el reporte de forma periódica y sin intervención manual.

¿Por qué es importante este enfoque?

La ausencia de reportes visuales nativos en Windows Server Backup obliga a los administradores a buscar soluciones creativas. Este script:

  • Estandariza la presentación de la información de backup.
  • Reduce el tiempo invertido en la recopilación manual de datos.
  • Mejora la trazabilidad y la capacidad de respuesta ante auditorías o incidentes.

¿Cómo funciona el script?

El script realiza los siguientes pasos:

  1. Verifica y crea la carpeta de reportes si no existe.
  2. Obtiene los últimos 31 respaldos (ideal para reportes mensuales).
  3. Extrae detalles de cada job, incluyendo fecha, hora, estado y VMs protegidas.
  4. Genera un archivo HTML con toda la información, usando tablas y estilos para facilitar la lectura.
  5. Convierte el HTML a PDF automáticamente.
  6. Permite su ejecución programada el primer día de cada mes a las 7:00am, asegurando que el reporte esté siempre actualizado.

Script para generar los Reportes

# Configura la cantidad de backups a mostrar
$BackupCount = 31

# Obtiene los últimos jobs de backup
$jobs = Get-WBJob -Previous $BackupCount

# Obtén el hostname
$hostname = $env:COMPUTERNAME

# Fecha y hora para el nombre del archivo
$now = Get-Date
$filename = "BackupReport-$hostname-$($now.ToString('yyyyMMdd-HHmmss')).html"
$pdfFilename = "BackupReport-$hostname-$($now.ToString('yyyyMMdd-HHmmss')).pdf"
$reportePath = "C:\Reportes\$filename"
$reportePdfPath = "C:\Reportes\$pdfFilename"

if (-not (Test-Path "C:\Reportes")) {
    New-Item -Path "C:\Reportes" -ItemType Directory | Out-Null
} 

# Construye la tabla HTML
$html = @"
<html>
<head>
    <title>Reporte de Backups - $hostname</title>
    <style>
        body { font-family: Arial, sans-serif; background: #f8f8f8; }
        h2 { color: #2d5fa4; }
        table { border-collapse: collapse; width: 100%; background: #fff; }
        th, td { border: 1px solid #ddd; padding: 8px; }
        th { background: #2d5fa4; color: white; }
        tr:nth-child(even) { background: #f2f2f2; }
        .ok { color: green; font-weight: bold; }
        .fail { color: red; font-weight: bold; }
        ul { margin: 0; padding-left: 20px; }
    </style>
</head>
<body>
    <h2>Reporte de Backups - $hostname</h2>
    <table>
        <tr>
            <th>Tipo</th>
            <th>Inicio</th>
            <th>Fin</th>
            <th>Estado</th>
            <th>VMs Respaldadas (Tamaño)</th>
        </tr>
"@

foreach ($job in $jobs) {

    # Estado visual
    $stateClass = if ($job.JobState -eq "Completed") { "ok" } else { "fail" }

    # Formatea las fechas en DD/MM/YYYY HH:mm:ss
    $startDate = Get-Date $job.StartTime -Format "dd/MM/yyyy hh:mm tt"
    $endDate = Get-Date $job.EndTime -Format "dd/MM/yyyy hh:mm tt"

    # Obtener la lista de VMs y tamaños usando wbadmin
    $vmInfo = ""
    if ($job.VersionId) {
        $wbadminOutput = wbadmin get items -version:$($job.VersionId) 2>&1
        $vmLines = $wbadminOutput | Select-String -Pattern "VM name:|Total Size:"
        if ($vmLines) {
            $vms = @()
            for ($i = 0; $i -lt $vmLines.Count; $i++) {
                if ($vmLines[$i] -match "VM name: (.+)") {
                    $vmName = $Matches[1].Trim()
                    $vmSize = ""
                    # Busca el siguiente "Total Size" después del VM name
                    if ($i+1 -lt $vmLines.Count -and $vmLines[$i+1] -match "Total Size: (.+)") {
                        $vmSize = $Matches[1].Trim()
                    }
                    $vms += "$vmName ($vmSize)"
                }
            }
            if ($vms.Count -gt 0) {
                $vmInfo = "<ul>" + ($vms | ForEach-Object { "<li>$_</li>" }) -join "" + "</ul>"
            } else {
                $vmInfo = "<i>No hay VMs</i>"
            }
        } else {
            $vmInfo = "<i>No hay VMs</i>"
        }
    } else {
        $vmInfo = "<i>No disponible</i>"
    }

    $html += @"
        <tr>
            <td>$($job.JobType)</td>
            <td>$startDate</td>
            <td>$endDate</td>
            <td class='$stateClass'>$($job.JobState)</td>
            <td>$vmInfo</td>
        </tr>
"@
}

$html += @"
    </table>
    <p style="font-size:12px;color:#888;">Generado el $(Get-Date -Format "dd/MM/yyyy HH:mm:ss")</p>
</body>
</html>
"@

# Guarda el reporte con nombre único
$html | Out-File -Encoding UTF8 $reportePath

Write-Host "Reporte generado en: $reportePath"

Start-Process "msedge.exe" "--headless --disable-gpu --print-to-pdf=$reportePdfPath file:///$reportePath" -Wait

Write-Host "Reporte PDF generado en: $reportePdfPath"

Automatización y envío por correo electrónico

Si quieres automatizar la ejecución del script para que se ejecute periódicamente (por ejemplo, el primer día de cada mes a las 7:00am), puedes hacerlo fácilmente desde PowerShell utilizando el Programador de Tareas de Windows. Solo ejecuta el siguiente comando:

$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Reportes\BackupReport.ps1"'
$Trigger = New-ScheduledTaskTrigger -Monthly -DaysOfMonth 1 -At 7:00am
$Principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -TaskName "BackupReportMensual" -Action $Action -Trigger $Trigger -Principal $Principal -Description "Genera el reporte mensual de backups" 

💡 Reemplaza el nombre del Script correspondiente a tu caso En este ejemplo se asume que el fichero se llama BackupReport.ps1 y está guardado en C:\Reportes

Pasos extra

Si deseas enviar el reporte generado por correo electrónico, puedes experimentar agregando las configuraciones y líneas de comando necesarias usando el cmdlet Send-MailMessage de PowerShell. Así podrás compartir el reporte automáticamente con tu equipo o destinatarios de interés.