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.).
- Reporte HTML: resumen + tablas + métricas (generado por
New-HealthCheckHtmlReport) - JSON: datasets listos para consumir en automatización / SIEM / inventario
- Logs: archivo
logs/HealthCheck_YYYYMMDD_HHMMSS.logcuandoEnableLogestá activo - GPO:
gpresult.htmlcuandoExportGpResultHtmlestá activo
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"
Funciones clave (resumen)
- Ensure-Folder: valida/crea la carpeta de salida (
RutaOrigen). - Write-HealthLog + Inicializar-HealthLog: logging con niveles y rotación de logs.
- Format-JsonOutput: convierte objetos a JSON compacto y formatea arrays para que cada objeto quede por línea.
- Invoke-DiagnosticJob: wrapper para ejecutar diagnósticos en paralelo con timeout + fallback secuencial.
- New-HealthCheckHtmlReport: constructor del reporte HTML (dashboard, tablas filtrables, etc.).
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
)
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
}
}
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)"
}
}
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 { }
}
}
}
Script completo
Este bloque carga automáticamente el contenido real de MisScripts\HealthCheck.ps1.
Cargando script...