Windows Server 2019
Essentials
Guía completa de instalación, configuración inicial, servicios de red, gestión de usuarios y mantenimiento preventivo para entornos de pequeña y mediana empresa.
CPU
RAM
Disco sistema
Red
Pantalla
Instalación
Lista de verificación previa
- BIOS/UEFI actualizado — Verifica la versión y actualiza si hay versión estable disponible del fabricante.
- Modo de arranque UEFI activo — Desactiva CSM/Legacy Boot para instalar en GPT (recomendado).
- Secure Boot — Puedes dejarlo activo; WS2019 es compatible.
- RAID/Almacenamiento verificado — Si usas RAID por hardware, configura el controlador antes de instalar.
- Drivers disponibles — Descarga drivers de NIC, RAID y chipset del fabricante del servidor.
- IP estática planificada — Decide la IP, máscara, gateway y DNS antes de comenzar.
- Nombre del servidor planificado — Máximo 15 caracteres, sin espacios ni caracteres especiales.
- Licencia disponible — Clave de producto o acceso a KMS/MAK listo.
- USB de instalación creado — Con Rufus (GPT + UEFI) o la herramienta de Microsoft.
Crear USB booteable con Rufus
1. Descargar Rufus desde https://rufus.ie
2. Insertar USB de 8 GB o más (se borrará todo)
3. En Rufus seleccionar:
Dispositivo: USB insertado
Tipo de arranque: Imagen de disco → Seleccionar ISO
Esquema part.: GPT
Sistema destino: UEFI (no CSM)
Sistema archivos: NTFS
4. Clic en EMPEZAR y confirmar el borradoComprobar integridad del ISO descargado
# Verificar hash SHA256 del ISO (compara con el publicado por Microsoft)
Get-FileHash "C:\Downloads\WS2019_Essentials.iso" -Algorithm SHA256Fase 1 — Arranque desde USB
- Conecta el USB booteable e inicia el servidor. Pulsa la tecla de boot menu (generalmente
F11,F12oESCsegún fabricante). - Selecciona el USB en el menú de arranque. Si no aparece, verifica que UEFI boot esté habilitado y CSM desactivado.
- En la pantalla de Windows Setup: selecciona Español (España), formato de hora y moneda, y teclado.
- Clic en Instalar ahora.
- Introduce la clave de producto o selecciona «No tengo clave de producto» (se puede activar después).
Fase 2 — Selección de edición y tipo de instalación
- Selecciona Windows Server 2019 Essentials (Experiencia de escritorio) — esta es la versión con GUI completa.
- Tipo de instalación: selecciona siempre Personalizada: instalar solo Windows para una instalación limpia.
Fase 3 — Particionado del disco (recomendado)
Esquema recomendado para un servidor con un SSD de 120 GB:
Partición 1 (EFI): 300 MB — Creada automáticamente
Partición 2 (MSR): 16 MB — Creada automáticamente
Partición 3 (Sistema): 60 GB — C:\ — Sistema operativo
Partición 4 (Datos): ~59 GB — D:\ — Datos / Carpetas compartidas
Consejo: NUNCA almacenes datos de usuarios en C:\
Así puedes reinstalar el SO sin perder datos.Fase 4 — Después del primer arranque (OOBE)
- Establece una contraseña de Administrador robusta: mínimo 12 caracteres, mayúsculas, minúsculas, números y símbolo. Anótala en un gestor de contraseñas.
- Windows arrancará y ejecutará automáticamente el Asistente de configuración de Essentials al primer inicio de sesión.
- En el asistente: introduce el nombre de la empresa, nombre del dominio interno (ej:
empresa.local) y datos del administrador. - Espera a que el asistente configure Active Directory, DNS y DHCP. Este proceso tarda entre 15 y 30 minutos.
.local para redes internas (ej: miempresa.local). Si ya tienes un dominio real en Internet (ej: miempresa.com), considera usarlo aquí también para evitar conflictos de DNS con el tiempo. No uses solo el nombre NetBIOS sin sufijo.Verificar instalación desde CMD
:: Verificar versión y edición instalada
winver
:: Ver detalles desde línea de comandos
wmic os get Caption, Version, BuildNumber, OSArchitecture
:: Comprobar estado de activación
slmgr /dli
:: Ver información completa de licencia
slmgr /dlvNombre del servidor y zona horaria
# Cambiar nombre del servidor (requiere reinicio)
Rename-Computer -NewName "SRV-EMPRESA-01" -Restart
# Ver nombre actual
$env:COMPUTERNAME
# Configurar zona horaria (España peninsular)
Set-TimeZone -Id "Romance Standard Time"
# Ver zonas horarias disponibles
Get-TimeZone -ListAvailable | Where-Object {$_.Id -like "*Spain*"}
# Sincronizar hora con servidor NTP externo
w32tm /config /manualpeerlist:"pool.ntp.org" /syncfromflags:manual /reliable:YES /update
net stop w32time
net start w32time
w32tm /resync /forceInstalar drivers y verificar hardware
# Ver dispositivos sin driver correcto
Get-PnpDevice | Where-Object {$_.Status -ne "OK"}
# Ver todos los dispositivos y estado
Get-PnpDevice | Select-Object Status, Class, FriendlyName | Sort-Object Status
# Instalar driver de archivo INF manualmente
pnputil /add-driver "C:\Drivers\NIC\driver.inf" /install
# Ver todos los drivers instalados
Get-WindowsDriver -Online | Select-Object Driver, ClassName, ProviderName, DateConfigurar Server Manager — Tareas iniciales
- Abrir Server Manager (se abre automáticamente) → Panel de control principal del servidor.
- Administración de servidor local → Verifica que el Firewall esté activo, IE Enhanced Security configurado y actualizaciones habilitadas.
- Cambiar a «No iniciar Server Manager automáticamente» en producción si prefieres (Manage → Server Manager Properties).
:: Abrir Server Manager desde CMD
ServerManager.exe
:: Abrir herramientas administrativas
control admintools
:: Verificar roles instalados
Get-WindowsFeature | Where-Object {$_.InstallState -eq "Installed"}
:: Ver todos los roles disponibles
Get-WindowsFeature | Format-Table -AutoSizePolítica de contraseñas y seguridad básica
:: Configurar política de contraseñas local
net accounts /minpwlen:12 /maxpwage:90 /minpwage:1 /uniquepw:5
:: Deshabilitar cuenta Administrador local por defecto (usa una con nombre diferente)
net user Administrator /active:no
:: Ver política de contraseñas actual
net accounts
:: Abrir editor de directivas de grupo local
gpedit.msc
:: Abrir herramienta de seguridad local
secpol.mscConfigurar IP estática
# Ver adaptadores de red disponibles
Get-NetAdapter | Select-Object Name, InterfaceIndex, Status, LinkSpeed
# Asignar IP estática (ajusta los valores a tu red)
New-NetIPAddress -InterfaceAlias "Ethernet" `
-IPAddress "192.168.1.10" `
-PrefixLength 24 `
-DefaultGateway "192.168.1.1"
# Configurar DNS (el servidor es su propio DNS primario)
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" `
-ServerAddresses "192.168.1.10","8.8.8.8"
# Verificar configuración
Get-NetIPConfigurationGestión del servidor DHCP
# Instalar rol DHCP si no está instalado
Install-WindowsFeature DHCP -IncludeManagementTools
# Autorizar el servidor DHCP en AD
Add-DhcpServerInDC
# Crear scope (rango de IPs para clientes)
Add-DhcpServerv4Scope -Name "Red Local" `
-StartRange "192.168.1.100" `
-EndRange "192.168.1.200" `
-SubnetMask "255.255.255.0" `
-State Active
# Configurar opciones del scope (gateway y DNS)
Set-DhcpServerv4OptionValue -ScopeId "192.168.1.0" `
-Router "192.168.1.1" `
-DnsServer "192.168.1.10" `
-DnsDomain "empresa.local"
# Excluir IPs de equipos con IP estática
Add-DhcpServerv4ExclusionRange -ScopeId "192.168.1.0" `
-StartRange "192.168.1.1" `
-EndRange "192.168.1.50"
# Ver leases activos
Get-DhcpServerv4Lease -ScopeId "192.168.1.0"
# Abrir consola DHCP gráfica
dhcpmgmt.mscVerificación de red y DNS
:: Comprobar conectividad básica
ping 8.8.8.8
ping google.com
:: Ver tabla de rutas
route print
:: Verificar que el servicio DNS responde
nslookup empresa.local 192.168.1.10
nslookup google.com 192.168.1.10
:: Ver zonas DNS configuradas
Get-DnsServerZone
:: Limpiar caché DNS del servidor
Clear-DnsServerCache
:: Ver estadísticas del servidor DNS
Get-DnsServerStatisticsCrear usuarios desde PowerShell
# Crear usuario en Active Directory
New-ADUser `
-Name "Juan García" `
-SamAccountName "jgarcia" `
-UserPrincipalName "jgarcia@empresa.local" `
-GivenName "Juan" `
-Surname "García" `
-DisplayName "Juan García" `
-Department "Ventas" `
-Office "Madrid" `
-AccountPassword (ConvertTo-SecureString "P@ssw0rd2026!" -AsPlainText -Force) `
-Enabled $true `
-PasswordNeverExpires $false `
-ChangePasswordAtLogon $true
# Crear usuario local (no en AD)
New-LocalUser -Name "LocalAdmin" `
-Password (ConvertTo-SecureString "S3gura!2026" -AsPlainText -Force) `
-FullName "Administrador Local" `
-Description "Cuenta admin de emergencia"
# Listar todos los usuarios de AD
Get-ADUser -Filter * | Select-Object Name, SamAccountName, Enabled
# Buscar usuario específico
Get-ADUser -Identity "jgarcia" -Properties *
# Deshabilitar usuario
Disable-ADAccount -Identity "jgarcia"
# Eliminar usuario
Remove-ADUser -Identity "jgarcia" -Confirm:$false
# Restablecer contraseña
Set-ADAccountPassword -Identity "jgarcia" `
-NewPassword (ConvertTo-SecureString "NuevoP@ss2026" -AsPlainText -Force) `
-ResetGestión de grupos
# Crear grupo de seguridad
New-ADGroup -Name "GRP-Ventas" `
-GroupScope Global `
-GroupCategory Security `
-Description "Grupo del departamento de Ventas"
# Añadir usuario a grupo
Add-ADGroupMember -Identity "GRP-Ventas" -Members "jgarcia"
# Ver miembros del grupo
Get-ADGroupMember -Identity "GRP-Ventas"
# Ver grupos a los que pertenece un usuario
Get-ADPrincipalGroupMembership -Identity "jgarcia"
# Eliminar usuario de grupo
Remove-ADGroupMember -Identity "GRP-Ventas" -Members "jgarcia" -Confirm:$falseCrear múltiples usuarios desde CSV (bulk)
# Formato del CSV (usuarios.csv):
# Name,SamAccountName,Department,Password
# María López,mlopez,Contabilidad,P@ss2026!
# Importar usuarios desde CSV
Import-Csv "C:\Admin\usuarios.csv" | ForEach-Object {
New-ADUser `
-Name $_.Name `
-SamAccountName $_.SamAccountName `
-Department $_.Department `
-AccountPassword (ConvertTo-SecureString $_.Password -AsPlainText -Force) `
-Enabled $true `
-ChangePasswordAtLogon $true
Write-Host "Creado: $($_.Name)" -ForegroundColor Green
}Crear carpetas compartidas
# Crear estructura de carpetas en D:\
New-Item -Path "D:\Compartido\Empresa" -ItemType Directory
New-Item -Path "D:\Compartido\Ventas" -ItemType Directory
New-Item -Path "D:\Compartido\RRHH" -ItemType Directory
New-Item -Path "D:\Usuarios" -ItemType Directory
# Compartir carpeta en red
New-SmbShare -Name "Empresa" `
-Path "D:\Compartido\Empresa" `
-FullAccess "Domain Admins" `
-ReadAccess "Domain Users" `
-Description "Carpeta compartida general"
# Compartir con acceso solo a un grupo
New-SmbShare -Name "Ventas" `
-Path "D:\Compartido\Ventas" `
-FullAccess "Domain Admins" `
-ChangeAccess "GRP-Ventas"
# Listar carpetas compartidas
Get-SmbShare
# Ver conexiones activas a carpetas compartidas
Get-SmbSession
# Eliminar carpeta compartida (sin borrar archivos)
Remove-SmbShare -Name "Ventas" -Confirm:$falsePermisos NTFS (el modelo correcto: AGDLP)
Acuenta → Grupo Global → Domain Local group → Permission. Asigna siempre los permisos NTFS a grupos de dominio local, no directamente a usuarios ni a grupos globales.
# Ver permisos NTFS de una carpeta
Get-Acl "D:\Compartido\Ventas" | Format-List
# Añadir permiso de escritura a un grupo
$acl = Get-Acl "D:\Compartido\Ventas"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"empresa\GRP-Ventas", "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl.SetAccessRule($rule)
Set-Acl "D:\Compartido\Ventas" $acl
# Aplicar permisos de forma recursiva con icacls
icacls "D:\Compartido\Ventas" /grant "empresa\GRP-Ventas:(OI)(CI)M" /T
# Quitar permisos heredados y asignar solo los necesarios
icacls "D:\Compartido\RRHH" /inheritance:r
icacls "D:\Compartido\RRHH" /grant "empresa\GRP-RRHH:(OI)(CI)M"
icacls "D:\Compartido\RRHH" /grant "empresa\Domain Admins:(OI)(CI)F"Mapear unidades en clientes (GPO)
# Mapear unidad de red manualmente en cliente
net use Z: \\SRV-EMPRESA-01\Empresa /persistent:yes
net use V: \\SRV-EMPRESA-01\Ventas /persistent:yes
# Con PowerShell (más moderno)
New-PSDrive -Name Z -PSProvider FileSystem `
-Root "\\SRV-EMPRESA-01\Empresa" -Persist
# Desconectar unidad
net use Z: /deleteEstructura de Unidades Organizativas (OUs)
# Ver estructura actual de AD
Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName
# Crear estructura de OUs recomendada
$base = "DC=empresa,DC=local"
New-ADOrganizationalUnit -Name "_Empresa" -Path $base
New-ADOrganizationalUnit -Name "Usuarios" -Path "OU=_Empresa,$base"
New-ADOrganizationalUnit -Name "Equipos" -Path "OU=_Empresa,$base"
New-ADOrganizationalUnit -Name "Grupos" -Path "OU=_Empresa,$base"
New-ADOrganizationalUnit -Name "Cuentas de Servicio" -Path "OU=_Empresa,$base"
# Mover usuario a OU específica
Move-ADObject -Identity "CN=Juan García,CN=Users,DC=empresa,DC=local" `
-TargetPath "OU=Usuarios,OU=_Empresa,DC=empresa,DC=local"Directivas de Grupo (GPO) esenciales
:: Abrir consola de GPO
gpmc.msc
:: Forzar actualización de directivas en el servidor
gpupdate /force
:: Forzar actualización en cliente remoto
Invoke-GPUpdate -Computer "PC-USUARIO01" -Force
:: Ver directivas aplicadas en el equipo local
gpresult /r
:: Generar informe HTML de directivas
gpresult /h C:\Admin\gpresult.html /f
:: Listar todas las GPOs del dominio
Get-GPO -All | Select-Object DisplayName, GpoStatus, CreationTime
:: Crear nueva GPO
New-GPO -Name "GPO-Usuarios-Base" -Comment "Configuración base para todos los usuarios"
:: Vincular GPO a OU
New-GPLink -Name "GPO-Usuarios-Base" `
-Target "OU=Usuarios,OU=_Empresa,DC=empresa,DC=local"Unir equipo cliente al dominio
# Unir equipo al dominio (ejecutar en el equipo cliente)
Add-Computer -DomainName "empresa.local" `
-Credential (Get-Credential) `
-OUPath "OU=Equipos,OU=_Empresa,DC=empresa,DC=local" `
-Restart
# Ver equipos unidos al dominio (desde el servidor)
Get-ADComputer -Filter * | Select-Object Name, OperatingSystem, LastLogonDate
# Eliminar equipo del dominio
Remove-ADComputer -Identity "PC-USUARIO01" -Confirm:$false# Instalar rol de servidor de impresión
Install-WindowsFeature Print-Server -IncludeManagementTools
# Abrir administrador de impresión
printmanagement.msc
# Listar impresoras instaladas
Get-Printer | Select-Object Name, PortName, DriverName, Shared, ShareName
# Añadir impresora por puerto TCP/IP
Add-PrinterPort -Name "IP_192.168.1.50" -PrinterHostAddress "192.168.1.50"
Add-Printer -Name "HP LaserJet Oficina" `
-PortName "IP_192.168.1.50" `
-DriverName "HP Universal Printing PCL 6"
# Compartir impresora en red
Set-Printer -Name "HP LaserJet Oficina" -Shared $true -ShareName "ImpOfi"
# Ver cola de impresión
Get-PrintJob -PrinterName "HP LaserJet Oficina"
# Limpiar cola de impresión atascada
net stop spooler
del /Q /F /S C:\Windows\System32\spool\PRINTERS\*
net start spoolerDirectiva de bloqueo de cuentas
:: Configurar bloqueo de cuenta tras 5 intentos fallidos
net accounts /lockoutthreshold:5 /lockoutduration:15 /lockoutwindow:15
:: Ver directivas de cuenta actuales
net accounts
:: Ver cuentas bloqueadas en AD
Search-ADAccount -LockedOut | Select-Object Name, SamAccountName
:: Desbloquear cuenta de usuario
Unlock-ADAccount -Identity "jgarcia"
:: Ver intentos de inicio de sesión fallidos (últimas 24h)
Get-EventLog -LogName Security -InstanceId 4625 `
-After (Get-Date).AddHours(-24) | Select-Object TimeGenerated, MessageAuditoría de eventos de seguridad
:: Activar auditoría de inicio de sesión
auditpol /set /subcategory:"Logon" /success:enable /failure:enable
:: Activar auditoría de cambios en objetos AD
auditpol /set /subcategory:"Directory Service Changes" /success:enable
:: Activar auditoría de acceso a archivos
auditpol /set /subcategory:"File System" /success:enable /failure:enable
:: Ver configuración de auditoría actual
auditpol /get /category:*
:: IDs de eventos de seguridad importantes:
:: 4624 = Inicio de sesión correcto
:: 4625 = Inicio de sesión fallido
:: 4648 = Inicio de sesión con credenciales explícitas
:: 4720 = Cuenta de usuario creada
:: 4726 = Cuenta de usuario eliminada
:: 4740 = Cuenta bloqueada
:: 4756 = Miembro añadido a grupo privilegiado
:: Buscar evento específico en el log de seguridad
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 20Deshabilitar servicios y protocolos inseguros
# Deshabilitar SMBv1 (vulnerable a WannaCry y EternalBlue)
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Confirm:$false
# Verificar que SMBv1 está desactivado
Get-SmbServerConfiguration | Select-Object EnableSMB1Protocol, EnableSMB2Protocol
# Deshabilitar telnet
Disable-WindowsOptionalFeature -Online -FeatureName TelnetClient
# Deshabilitar RDP si no se usa (puerta de entrada muy atacada)
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 1 /f
# Si necesitas RDP, cambia el puerto por defecto
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber /t REG_DWORD /d 3390 /f
# Verificar versiones de TLS habilitadas
Get-TlsCipherSuite | Select-Object Name | Format-TableInstalar Windows Server Backup
# Instalar característica de backup
Install-WindowsFeature Windows-Server-Backup -IncludeManagementTools
# Abrir consola gráfica de backup
wbadmin get versions
# Ver estado del último backup
wbadmin get statusConfigurar backup programado completo
:: Backup completo diario a disco externo E: a las 23:00
wbadmin enable backup -addtarget:E: -schedule:23:00 -include:C:,D: -quiet
:: Backup completo inmediato a disco externo
wbadmin start backup -backuptarget:E: -include:C:,D: -allCritical -quiet
:: Backup solo del estado del sistema (AD, boot, registro)
wbadmin start systemstatebackup -backuptarget:E: -quiet
:: Backup a carpeta de red (UNC path)
wbadmin start backup `
-backuptarget:\\NAS-EMPRESA\Backups\Servidor `
-include:C:,D: `
-user:empresa\AdminBackup `
-password:P@ssBackup2026 `
-quiet
:: Listar versiones de backup disponibles
wbadmin get versions
:: Restaurar archivo específico desde backup
wbadmin start recovery -version:03/15/2026-23:00 `
-itemtype:File `
-items:D:\Compartido\Empresa\archivo.xlsx `
-recoveryTarget:D:\Restaurados `
-quietScript PowerShell de backup automatizado
# Script de backup con log y notificación de errores
# Guardar como C:\Scripts\backup-diario.ps1
# Programar con Tarea programada a las 23:00
$fecha = Get-Date -Format "yyyyMMdd_HHmm"
$logFile = "C:\Scripts\Logs\backup_$fecha.log"
$destino = "\\NAS-EMPRESA\Backups\Servidor"
Start-Transcript -Path $logFile
# Ejecutar backup
Write-Host "[$(Get-Date)] Iniciando backup..."
wbadmin start backup -backuptarget:$destino -include:C:,D: -allCritical -quiet
if ($LASTEXITCODE -eq 0) {
Write-Host "[$(Get-Date)] BACKUP COMPLETADO CON ÉXITO" -ForegroundColor Green
} else {
Write-Host "[$(Get-Date)] ERROR EN EL BACKUP - Código: $LASTEXITCODE" -ForegroundColor Red
# Enviar email de alerta (requiere Send-MailMessage o SMTP configurado)
}
# Eliminar logs de más de 30 días
Get-ChildItem "C:\Scripts\Logs\" -Filter "*.log" |
Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} |
Remove-Item -Force
Stop-Transcript# Instalar módulo PSWindowsUpdate
Install-Module PSWindowsUpdate -Force
Import-Module PSWindowsUpdate
# Ver actualizaciones disponibles
Get-WindowsUpdate
# Instalar solo actualizaciones de seguridad
Install-WindowsUpdate -Category "Security Updates" -AcceptAll -AutoReboot
# Instalar todas las actualizaciones
Install-WindowsUpdate -AcceptAll -AutoReboot
# Instalar sin reiniciar (para hacerlo en mantenimiento)
Install-WindowsUpdate -AcceptAll -IgnoreReboot
# Ver historial de actualizaciones instaladas
Get-WUHistory | Select-Object -First 20 Date, Title, Result
# Verificar actualizaciones instaladas desde CMD
wmic qfe list full /format:table
# Programar reinicio para las 3:00 AM
shutdown /r /t 0 /f :: reinicio inmediato
at 03:00 shutdown /r /f :: reinicio programado a las 3:00Monitoreo de recursos en tiempo real
# Abrir Monitor de recursos (GUI)
resmon
# Abrir Monitor de rendimiento
perfmon
# CPU — top 10 procesos
Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, CPU, Id
# RAM — uso actual y disponible
$os = Get-WmiObject Win32_OperatingSystem
Write-Host "RAM Total: $([math]::Round($os.TotalVisibleMemorySize/1MB,2)) GB"
Write-Host "RAM Libre: $([math]::Round($os.FreePhysicalMemory/1MB,2)) GB"
Write-Host "RAM Usada: $([math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory)/1MB,2)) GB"
# Disco — espacio por volumen
Get-Volume | Select-Object DriveLetter, FileSystemLabel,
@{N="Total_GB";E={[math]::Round($_.Size/1GB,1)}},
@{N="Free_GB";E={[math]::Round($_.SizeRemaining/1GB,1)}},
@{N="Used_%";E={[math]::Round((($_.Size-$_.SizeRemaining)/$_.Size)*100,1)}},
HealthStatus
# Servicios detenidos que deberían estar activos
Get-Service | Where-Object {$_.Status -eq "Stopped" -and $_.StartType -eq "Automatic"}
# Tiempo de actividad del servidor
(Get-Date) - (gcim Win32_OperatingSystem).LastBootUpTimeAnálisis del Visor de eventos (Event Viewer)
# Abrir visor de eventos
eventvwr.msc
# Últimos 20 errores críticos del sistema
Get-WinEvent -FilterHashtable @{LogName='System'; Level=1,2} -MaxEvents 20 |
Select-Object TimeCreated, LevelDisplayName, Message
# Errores de aplicaciones
Get-WinEvent -FilterHashtable @{LogName='Application'; Level=2} -MaxEvents 20 |
Select-Object TimeCreated, ProviderName, Message
# Exportar log de sistema a CSV
Get-WinEvent -LogName System -MaxEvents 500 |
Export-Csv "C:\Admin\system-log-$(Get-Date -f 'yyyyMMdd').csv" -NoTypeInformation
# Limpiar logs del visor de eventos (mantenimiento)
Get-WinEvent -ListLog * | Where-Object {$_.IsEnabled} |
ForEach-Object {[System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession.ClearLog($_.LogName)}Script de informe de salud diario
# Generar informe de salud del servidor en HTML
$fecha = Get-Date -Format "dd/MM/yyyy HH:mm"
$os = Get-WmiObject Win32_OperatingSystem
$ram_gb = [math]::Round($os.TotalVisibleMemorySize/1MB,2)
$free_g = [math]::Round($os.FreePhysicalMemory/1MB,2)
$uptime = ((Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime)).ToString("dd'd 'hh'h 'mm'm'")
$discos = Get-Volume | Where-Object {$_.DriveLetter} |
Select-Object DriveLetter,
@{N="Total";E={[math]::Round($_.Size/1GB,1)}},
@{N="Libre";E={[math]::Round($_.SizeRemaining/1GB,1)}}
$errores = (Get-WinEvent -FilterHashtable @{LogName='System';Level=2;
StartTime=(Get-Date).AddHours(-24)} -ErrorAction SilentlyContinue).Count
Write-Host "=== INFORME $fecha ==="
Write-Host "Uptime : $uptime"
Write-Host "RAM : $free_g GB libres de $ram_gb GB"
Write-Host "Errores : $errores en las últimas 24h"
$discos | ForEach-Object { Write-Host "Disco $($_.DriveLetter): $($_.Libre)/$($_.Total) GB" }# Plan de energía: "Alto rendimiento" (siempre para servidores físicos)
powercfg /setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c
powercfg /getactivescheme
# Deshabilitar hibernación (innecesaria en servidores)
powercfg /hibernate off
# Ajustar memoria virtual automáticamente
$os = Get-WmiObject -Class Win32_OperatingSystem
$cs = Get-WmiObject -Class Win32_ComputerSystem
$cs.AutomaticManagedPagefile = $false
$cs.Put()
# Deshabilitar indexación en unidades de datos (D:)
Set-WmiInstance -Class Win32_Volume -Filter 'DriveLetter = "D:"' `
-Arguments @{IndexingEnabled=$false}
# Limpiar caché de DNS del servidor
Clear-DnsServerCache
# Servicios que pueden desactivarse de forma segura en WS Essentials
# (solo si se confirma que no se usan)
$servicios_opcionales = @(
"XblAuthManager", # Xbox Live Auth
"XblGameSave", # Xbox Live Game Save
"WSearch", # Windows Search (si no se indexa)
"Fax" # Fax
)
$servicios_opcionales | ForEach-Object {
Set-Service -Name $_ -StartupType Disabled -ErrorAction SilentlyContinue
Stop-Service -Name $_ -Force -ErrorAction SilentlyContinue
}| Problema | Causa más común | Solución rápida |
|---|---|---|
| Clientes no encuentran el servidor | DNS mal configurado en clientes | Verificar que el DNS del cliente apunta a la IP del servidor |
| No se puede unir al dominio | Hora desincronizada (>5 min) o DNS incorrecto | w32tm /resync + verificar DNS |
| Carpetas compartidas inaccesibles | SMB bloqueado por Firewall o permisos | Verificar regla Firewall SMB y permisos NTFS |
| Servicio DHCP no asigna IPs | No autorizado en AD o scope inactivo | Add-DhcpServerInDC y verificar scope |
| Dashboard no carga | Servicio Windows Server Essentials detenido | net start WseEssentialsMgmt |
| Alto uso de CPU constante | Antivirus escaneando, WU actualizando, o proceso zombie | Get-Process | Sort CPU -Desc | Select -First 10 |
| Disco C: casi lleno | Logs, actualizaciones antiguas, WinSxS | DISM /StartComponentCleanup + limpiar TEMP |
Reparar Active Directory
:: Verificar integridad de la base de datos de AD
ntdsutil
:: Dentro de ntdsutil:
:: activate instance ntds
:: files
:: integrity
:: quit
:: Verificar replicación de AD (si hay más DCs)
repadmin /showrepl
repadmin /replsummary
:: Verificar estado general del DC
dcdiag /test:all /v
:: Forzar replicación AD
repadmin /syncall /AdeP
:: Reparar archivos del sistema (siempre el primer paso)
sfc /scannow
DISM /Online /Cleanup-Image /RestoreHealthProblemas de red y conectividad
:: Reset completo de red
ipconfig /flushdns
ipconfig /registerdns
netsh winsock reset
netsh int ip reset
:: Verificar que el servidor se registra en DNS
nslookup SRV-EMPRESA-01
:: Ver sesiones abiertas en carpetas compartidas
net session
:: Ver archivos abiertos en carpetas compartidas
net file
:: Ver conexiones de red activas con proceso
netstat -b -o -nConfigurar RDP de forma segura
# Habilitar Escritorio Remoto
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" `
-Name fDenyTSConnections -Value 0
# Activar autenticación a nivel de red (NLA) — obligatoria
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
-Name UserAuthentication -Value 1
# Cambiar puerto RDP por defecto (evitar escaneos automáticos)
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
-Name PortNumber -Value 3390
# Abrir el nuevo puerto en el Firewall
New-NetFirewallRule -DisplayName "RDP Custom Port" `
-Direction Inbound -Protocol TCP -LocalPort 3390 -Action Allow
# Añadir usuario al grupo de Escritorio Remoto
Add-LocalGroupMember -Group "Remote Desktop Users" -Member "empresa\jgarcia"
# Ver usuarios con acceso RDP
Get-LocalGroupMember -Group "Remote Desktop Users"
# Ver sesiones RDP activas
query session
quser
# Cerrar sesión remota por ID
logoff 2 /server:SRV-EMPRESA-01SSTP VPN integrada en WS Essentials
# Instalar rol de Enrutamiento y Acceso Remoto (RRAS)
Install-WindowsFeature Routing -IncludeManagementTools
Install-WindowsFeature DirectAccess-VPN -IncludeManagementTools
# Configurar VPN (PPTP/L2TP/SSTP) desde la GUI
rrasmgmt.msc
# Ver conexiones VPN activas
Get-RemoteAccessConnectionStatistics
# Ver usuarios conectados por VPN
Get-VpnS2SInterfaceEnviar alertas por SMTP desde PowerShell
# Configurar credenciales SMTP (Gmail como relay)
$smtpServer = "smtp.gmail.com"
$smtpPort = 587
$smtpUser = "alertas@tuempresa.com"
$smtpPass = "contraseña_app" # Usa "contraseña de aplicación" de Google
$credencial = New-Object PSCredential($smtpUser,
(ConvertTo-SecureString $smtpPass -AsPlainText -Force))
# Enviar email de prueba
Send-MailMessage `
-From "alertas@tuempresa.com" `
-To "admin@tuempresa.com" `
-Subject "[SERVIDOR] Test de alertas" `
-Body "El sistema de alertas funciona correctamente." `
-SmtpServer $smtpServer `
-Port $smtpPort `
-UseSsl `
-Credential $credencial
# Función reutilizable para alertas
function Send-Alert ($asunto, $cuerpo) {
Send-MailMessage -From "alertas@tuempresa.com" -To "admin@tuempresa.com" `
-Subject "[SRV-EMPRESA-01] $asunto" -Body $cuerpo `
-SmtpServer $smtpServer -Port $smtpPort -UseSsl -Credential $credencial
}
# Usar en scripts de monitoreo
$disco_libre = (Get-Volume -DriveLetter C).SizeRemaining/1GB
if ($disco_libre -lt 10) {
Send-Alert "⚠️ Disco C casi lleno" "Solo quedan $([math]::Round($disco_libre,1)) GB libres en C:\"
}| Puerto | Protocolo | Servicio | Acción |
|---|---|---|---|
| 53 | TCP/UDP | DNS | Permitir |
| 67-68 | UDP | DHCP | Permitir |
| 80/443 | TCP | HTTP/HTTPS | Permitir salida |
| 135, 445 | TCP | SMB / RPC | Solo red local |
| 389/636 | TCP | LDAP / LDAPS | Permitir |
| 3389 | TCP | RDP | Bloquear (externo) |
| 123 | UDP | NTP | Permitir |
# Ver estado del firewall en todos los perfiles
netsh advfirewall show allprofiles
# Activar firewall en todos los perfiles
netsh advfirewall set allprofiles state on
# Ver todas las reglas activas
Get-NetFirewallRule | Where-Object {$_.Enabled -eq "True"} |
Select-Object DisplayName, Direction, Action | Sort-Object Direction
# Crear regla para permitir puerto específico
New-NetFirewallRule `
-DisplayName "Allow SMB inbound LAN only" `
-Direction Inbound `
-Protocol TCP `
-LocalPort 445 `
-RemoteAddress "192.168.1.0/24" `
-Action Allow `
-Profile Domain,Private
# Bloquear IP sospechosa
New-NetFirewallRule `
-DisplayName "Block Suspicious IP" `
-Direction Inbound `
-RemoteAddress "203.0.113.100" `
-Action Block
# Bloquear rango de IPs
New-NetFirewallRule `
-DisplayName "Block Bad Range" `
-Direction Inbound `
-RemoteAddress "203.0.113.0/24" `
-Action Block
# Eliminar regla
Remove-NetFirewallRule -DisplayName "Block Suspicious IP"
# Exportar configuración del firewall a archivo
netsh advfirewall export "C:\Admin\firewall-backup.wfw"
# Importar configuración del firewall
netsh advfirewall import "C:\Admin\firewall-backup.wfw"
# Abrir consola avanzada del firewall
wf.msc📅 Semanal
- ☐ Revisar el Visor de eventos (errores críticos)
- ☐ Verificar espacio libre en C: y D: (>20%)
- ☐ Confirmar que los backups completaron sin errores
- ☐ Revisar cuentas bloqueadas en AD
- ☐ Verificar estado de Windows Defender
- ☐
Get-Service | Where {$_.Status -eq "Stopped"}
📆 Mensual
- ☐ Aplicar actualizaciones de seguridad (con backup previo)
- ☐ Ejecutar
sfc /scannowyDISM /RestoreHealth - ☐ Revisar usuarios inactivos en AD y deshabilitar
- ☐ Revisar grupos y permisos de carpetas compartidas
- ☐ Limpiar logs del Visor de eventos
- ☐ Probar una restauración desde backup (simulacro)
📊 Trimestral
- ☐ Ejecutar
dcdiag /test:ally revisar errores - ☐ Verificar salud de discos con SMART
- ☐ Revisar directivas de grupo (GPO) aplicadas
- ☐ Actualizar contraseñas de cuentas de servicio
- ☐ Revisar reglas del Firewall (eliminar las no necesarias)
- ☐ Optimizar discos con DISM /StartComponentCleanup
🗓️ Anual
- ☐ Verificar validez de licencias y fecha de soporte
- ☐ Actualizar BIOS/firmware del servidor
- ☐ Limpieza física del hardware (polvo, ventilación)
- ☐ Revisar capacidad del hardware vs. crecimiento
- ☐ Plan de recuperación ante desastres — test completo
- ☐ Revisar documentación y manual del servidor
Comandos de mantenimiento en lote
# Script de mantenimiento mensual completo
Write-Host "=== MANTENIMIENTO MENSUAL $(Get-Date -f 'dd/MM/yyyy') ===" -ForegroundColor Cyan
# 1. Verificar integridad del sistema
Write-Host "`n[1/6] Verificando archivos del sistema..."
sfc /scannow
# 2. Reparar imagen Windows
Write-Host "`n[2/6] Reparando imagen de Windows..."
DISM /Online /Cleanup-Image /RestoreHealth
# 3. Limpiar archivos temporales
Write-Host "`n[3/6] Limpiando archivos temporales..."
Remove-Item "$env:TEMP\*" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Windows\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue
# 4. Limpiar caché WU
Write-Host "`n[4/6] Limpiando caché Windows Update..."
Stop-Service wuauserv -Force
Remove-Item "C:\Windows\SoftwareDistribution\Download\*" -Recurse -Force -ErrorAction SilentlyContinue
Start-Service wuauserv
# 5. Optimizar discos
Write-Host "`n[5/6] Optimizando discos..."
Get-Volume | Where-Object {$_.DriveLetter} | Optimize-Volume -Verbose
# 6. Resumen final
Write-Host "`n[6/6] Resumen del sistema:"
$os = Get-WmiObject Win32_OperatingSystem
Write-Host "RAM libre: $([math]::Round($os.FreePhysicalMemory/1MB,2)) GB"
Get-Volume | Where-Object {$_.DriveLetter} |
Select-Object DriveLetter, @{N="Libre_GB";E={[math]::Round($_.SizeRemaining/1GB,1)}} |
Format-Table
Write-Host "=== MANTENIMIENTO COMPLETADO ===" -ForegroundColor GreenComandos de emergencia — Recuperación
:: Reconstruir BCD si el servidor no arranca
bootrec /fixmbr
bootrec /fixboot
bootrec /scanos
bootrec /rebuildbcd
:: Restaurar sistema desde backup de estado del sistema
wbadmin start systemstaterecovery -version:03/15/2026-23:00 -quiet
:: Restaurar Active Directory en modo DSRM (Directory Services Restore Mode)
:: Arrancar en modo DSRM: En BCDEDIT o F8 durante arranque
bcdedit /set safeboot dsrepair
:: Después de restaurar AD:
bcdedit /deletevalue safeboot
:: Transferir roles FSMO a otro DC (si el primario falla)
ntdsutil
:: roles → connections → connect to server NUEVO-DC → quit
:: seize PDC → seize RID master → seize infrastructure master → quit
:: Ver roles FSMO actuales
netdom query fsmo