HealthCheck.ps1 (Documentación del script)

HealthCheck.ps1 realiza una auditoría de salud sobre Windows (server o workstation) y genera un reporte HTML junto con múltiples archivos JSON para integración y análisis automatizado. Se recomienda ejecutarlo como Administrador para poder leer eventos de seguridad, hotfixes, etc.


Parámetros

Parámetro Descripción Default
RutaOrigen Carpeta donde se guardará el reporte y los datos ".\\"
DIASAtras Días hacia atrás para eventos y hotfixes 90
RutaSoftInstalado Ruta a un JSON de software instalado externo (si se desea) (vacío)
ExportJson Exporta datasets adicionales en JSON en la carpeta de salida False
EnableLog Habilita logging a archivo (carpeta logs dentro de RutaOrigen) True
ExportGpResultHtml Genera gpresult.html (informe de GPO aplicado) True
ParallelDiagnostics Ejecuta diagnósticos en paralelo (Start-Job). Si falla, hace fallback secuencial. True
EnableGpResultXmlDetails Habilita detalles XML para gpresult (más granularidad) False

Salidas generadas

En RutaOrigen se genera un HTML con timestamp (por ejemplo HealthCheck_YYYYMMDD_HHMMSS.html). Cuando ExportJson está activo, también exporta múltiples archivos JSON (por ejemplo informacion_computadora.json, estado_cpu.json, resumen_salud.json, etc.).

Ejemplos de uso

# Ejecución básica (salida en carpeta actual)
.\\HealthCheck.ps1

# Definir carpeta de salida y rango de días
.\\HealthCheck.ps1 -RutaOrigen "C:\\Temp\\Health" -DIASAtras 30

# Exportar datasets JSON + deshabilitar modo paralelo
.\\HealthCheck.ps1 -RutaOrigen "C:\\Temp\\Health" -ExportJson -ParallelDiagnostics:$false

# Usar un JSON de software externo
.\\HealthCheck.ps1 -RutaOrigen "C:\\Temp\\Health" -RutaSoftInstalado "C:\\Temp\\software_instalado.json"
¡Copiado!

Funciones clave (resumen)

Snippets del script

Bloque de parámetros

[CmdletBinding()]
param(
  [string]$RutaOrigen = ".\\",
  [int]$DIASAtras = 90,
  [string]$RutaSoftInstalado,
  [switch]$ExportJson,
  [switch]$EnableLog = $true,
  [switch]$ExportGpResultHtml = $true,
  [switch]$ParallelDiagnostics = $true,
  [switch]$EnableGpResultXmlDetails = $false
)
¡Copiado!

Ensure-Folder

function Ensure-Folder {
  param([string]$Path)
  if (-not $Path) { throw "RutaOrigen no puede ser vacío o nulo." }
  if (-not (Test-Path -LiteralPath $Path)) {
    New-Item -ItemType Directory -Path $Path -Force | Out-Null
  }
}
¡Copiado!

Write-HealthLog (logging con niveles)

function Write-HealthLog {
  param(
    [Parameter(Mandatory = $true)]
    [string]$Message,

    [Parameter(Mandatory = $false)]
    [ValidateSet('INFO', 'WARNING', 'ERROR', 'DEBUG', 'SUCCESS')]
    [string]$Level = 'INFO',

    [Parameter(Mandatory = $false)]
    [System.Management.Automation.ErrorRecord]$ErrorRecord = $null
  )

  if (-not $Script:LogFile) { return }

  try {
    $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff'
    $logEntry = "[$timestamp] [$Level] $Message"
    Add-Content -Path $Script:LogFile -Value $logEntry -Encoding UTF8 -ErrorAction SilentlyContinue

    switch ($Level) {
      'ERROR' { Write-Host $Message -ForegroundColor Red }
      'WARNING' { Write-Host $Message -ForegroundColor Yellow }
      'SUCCESS' { Write-Host $Message -ForegroundColor Green }
      'DEBUG' { Write-Verbose $Message }
      default { Write-Host $Message -ForegroundColor Cyan }
    }
  }
  catch {
    Write-Warning "Error escribiendo al log: $($_.Exception.Message)"
  }
}
¡Copiado!

Invoke-DiagnosticJob (paralelismo con fallback)

function Invoke-DiagnosticJob {
  param(
    [Parameter(Mandatory = $true)][string]$Name,
    [Parameter(Mandatory = $true)][scriptblock]$JobScript,
    [Parameter(Mandatory = $false)][object[]]$ArgumentList = @(),
    [Parameter(Mandatory = $true)][scriptblock]$FallbackScript,
    [Parameter(Mandatory = $false)][int]$TimeoutSec = 900
  )

  if (-not $ParallelDiagnostics) {
    return & $FallbackScript
  }

  $job = $null
  try {
    $job = Start-Job -Name $Name -ScriptBlock $JobScript -ArgumentList $ArgumentList
    $completed = Wait-Job -Job $job -Timeout $TimeoutSec
    if (-not $completed) {
      try { Stop-Job -Job $job -Force | Out-Null } catch { }
      throw "Timeout en job '$Name' (${TimeoutSec}s)"
    }

    $data = Receive-Job -Job $job -ErrorAction Stop
    return $data
  }
  catch {
    Write-Host "[Parallel] Job '$Name' falló, usando modo secuencial: $($_.Exception.Message)" -ForegroundColor DarkYellow
    Write-HealthLog "Job '$Name' falló, usando modo secuencial: $($_.Exception.Message)" -Level WARNING -ErrorRecord $_
    return & $FallbackScript
  }
  finally {
    if ($job) {
      try { Remove-Job -Job $job -Force -ErrorAction SilentlyContinue | Out-Null } catch { }
    }
  }
}
¡Copiado!

Script completo

Este bloque carga automáticamente el contenido real de MisScripts\HealthCheck.ps1.

Cargando script...
¡Copiado!