← Volver al portfolio

Soporte técnico · Proyecto 05

Centro de soporte

Un helpdesk pensado para un instituto: registra incidencias de aulas y departamentos, las prioriza con plazos de SLA, guía al usuario con un asistente de diagnóstico y documenta cada solución.

Rol
Soporte técnico IT
Stack
JavaScript · PowerShell · Windows/Linux
Tipo
Aplicación interactiva

ⓘ Datos ficticios, inspirados en trabajo real de soporte en centros educativos. Los cambios se guardan en tu navegador.

IES Demo · Soporte

Departamento TIC · Curso 2026/27

Desliza para ver todas las columnas · usa ‹ › para mover un ticket

Cómo funciona

1

Registro

Cada incidencia entra como ticket con aula, categoría y solicitante. Antes, el asistente guiado resuelve lo sencillo (un cable, la entrada del proyector, la cola de impresión) y, si no basta, adjunta al ticket los pasos ya comprobados.

2

Diagnóstico y priorización (SLA)

La prioridad fija el plazo: Crítica 4 h, Alta 8 h, Media 24 h y Baja 72 h. El tablero muestra la cuenta atrás y marca los vencidos, para atender primero lo que deja una clase sin poder trabajar.

3

Resolución y documentación

Ningún ticket se cierra sin nota de resolución. Esas notas forman la base de conocimiento y alimentan las métricas: tiempo medio, cumplimiento de SLA y carga por categoría o técnico.

Código destacado

El primer paso con un equipo que da problemas: un script que recoge en segundos lo que normalmente se pregunta por teléfono y deja un informe listo para adjuntar al ticket. Debajo, el arreglo más repetido en una sala de profesores: reiniciar la cola de impresión.

diagnostico.ps1Descargar
<#
.SYNOPSIS
    Genera un informe de diagnóstico del equipo para adjuntarlo a un ticket de soporte.
.EXAMPLE
    powershell -ExecutionPolicy Bypass -File .\diagnostico.ps1
#>
[CmdletBinding()]
param(
    [string]$Destino = [Environment]::GetFolderPath('Desktop')
)

$informe = [System.Collections.Generic.List[string]]::new()
function Add-Seccion([string]$Titulo) {
    $informe.Add('')
    $informe.Add("=== $Titulo ".PadRight(60, '='))
}

# --- Equipo y sistema -------------------------------------------------
$os = Get-CimInstance -ClassName Win32_OperatingSystem
$cs = Get-CimInstance -ClassName Win32_ComputerSystem
$uptime = (Get-Date) - $os.LastBootUpTime

Add-Seccion 'EQUIPO'
$informe.Add("Equipo            : $env:COMPUTERNAME")
$informe.Add("Usuario           : $env:USERDOMAIN\$env:USERNAME")
$informe.Add("Modelo            : $($cs.Manufacturer) $($cs.Model)")
$informe.Add("Sistema operativo : $($os.Caption) ($($os.Version), build $($os.BuildNumber))")
$informe.Add(('Encendido desde   : {0:dd/MM/yyyy HH:mm} ({1}d {2}h {3}m)' -f $os.LastBootUpTime, $uptime.Days, $uptime.Hours, $uptime.Minutes))

# --- Discos: avisa si queda menos de un 10 % libre ----------------------
Add-Seccion 'DISCOS'
Get-CimInstance -ClassName Win32_LogicalDisk -Filter 'DriveType=3' | ForEach-Object {
    $libre = [math]::Round($_.FreeSpace / $_.Size * 100)
    $aviso = if ($libre -lt 10) { '  <-- POCO ESPACIO' } else { '' }
    $informe.Add(('{0}  {1,7:N1} GB libres de {2,7:N1} GB ({3}%){4}' -f $_.DeviceID, ($_.FreeSpace / 1GB), ($_.Size / 1GB), $libre, $aviso))
}

# --- Configuración IP ---------------------------------------------------
Add-Seccion 'RED'
$adaptadores = @(Get-NetIPConfiguration | Where-Object { $_.NetAdapter.Status -eq 'Up' })
foreach ($a in $adaptadores) {
    $ipv4 = $a.IPv4Address.IPAddress
    $dns  = ($a.DNSServer | Where-Object AddressFamily -eq 2).ServerAddresses
    $informe.Add("Adaptador : $($a.InterfaceAlias) ($($a.NetAdapter.MacAddress))")
    $informe.Add("  IPv4    : $($ipv4 -join ', ')")
    $informe.Add("  Puerta  : $($a.IPv4DefaultGateway.NextHop -join ', ')")
    $informe.Add("  DNS     : $($dns -join ', ')")
    if ($ipv4 -like '169.254.*') { $informe.Add('  AVISO   : IP automática (APIPA), el DHCP no responde') }
}

# --- Conectividad: puerta de enlace, DNS e Internet ---------------------
Add-Seccion 'CONECTIVIDAD'
$destinos = [ordered]@{}
foreach ($a in $adaptadores) {
    foreach ($gw in $a.IPv4DefaultGateway.NextHop) { $destinos["Puerta de enlace $gw"] = $gw }
    foreach ($d in ($a.DNSServer | Where-Object AddressFamily -eq 2).ServerAddresses) { $destinos["DNS $d"] = $d }
}
$destinos['Internet (1.1.1.1)'] = '1.1.1.1'
foreach ($nombre in $destinos.Keys) {
    $ok = Test-Connection -ComputerName $destinos[$nombre] -Count 2 -Quiet -ErrorAction SilentlyContinue
    $informe.Add(('{0,-34} {1}' -f $nombre, $(if ($ok) { 'OK' } else { 'SIN RESPUESTA' })))
}

# --- Windows Update: actualizaciones pendientes y reinicio --------------
Add-Seccion 'ACTUALIZACIONES'
try {
    $buscador   = (New-Object -ComObject Microsoft.Update.Session).CreateUpdateSearcher()
    $pendientes = $buscador.Search("IsInstalled=0 and IsHidden=0 and Type='Software'").Updates
    $informe.Add("Pendientes: $($pendientes.Count)")
    foreach ($u in $pendientes) { $informe.Add("  - $($u.Title)") }
} catch {
    $informe.Add("No se pudo consultar Windows Update: $($_.Exception.Message)")
}
$reinicio = Test-Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
$informe.Add("Reinicio pendiente: $(if ($reinicio) { 'Sí' } else { 'No' })")

# --- Guardar el informe -------------------------------------------------
if (-not (Test-Path -Path $Destino)) { New-Item -ItemType Directory -Path $Destino -Force | Out-Null }
$archivo = Join-Path $Destino ('diagnostico_{0}_{1:yyyyMMdd-HHmm}.txt' -f $env:COMPUTERNAME, (Get-Date))
$informe | Out-File -FilePath $archivo -Encoding utf8
Write-Host "Informe guardado en $archivo" -ForegroundColor Green
reiniciar-cola-impresion.ps1 · como administrador
# Detiene la cola, borra los trabajos atascados y la vuelve a arrancar
Stop-Service -Name Spooler -Force
Remove-Item -Path "$env:SystemRoot\System32\spool\PRINTERS\*" -Force -ErrorAction SilentlyContinue
Start-Service -Name Spooler
Get-Service -Name Spooler | Select-Object Status, Name, DisplayName

# Equivalente en un .bat (cmd ejecutado como administrador):
#   net stop spooler
#   del /q /f "%SystemRoot%\System32\spool\PRINTERS\*.*"
#   net start spooler