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.
Soporte técnico · Proyecto 05
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.
ⓘ Datos ficticios, inspirados en trabajo real de soporte en centros educativos. Los cambios se guardan en tu navegador.
Departamento TIC · Curso 2026/27
Desliza para ver todas las columnas · usa ‹ › para mover un ticket
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.
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.
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.
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.
<#
.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
# 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