commit 9860c48b11e83fe9d7a1bb1dfd7865622fbc1627 Author: Tu Nombre Date: Thu Sep 24 15:19:05 2026 +0200 Commint Inicial diff --git a/setup.ps1 b/setup.ps1 new file mode 100644 index 0000000..2aeff46 --- /dev/null +++ b/setup.ps1 @@ -0,0 +1,556 @@ +```powershell +#Requires -Version 5.1 + +<# + setup.ps1 + ------------------------------------------------------------ + Configuración inicial de Windows 10 + + Este script: + + 1. Se ejecuta como Administrador (se autoeleva si es necesario). + 2. Crea el usuario local "tecnica" si no existe. + 3. Solicita la contraseña dos veces al crear el usuario. + 4. Añade "tecnica" al grupo de Administradores. + 5. Activa Escritorio Remoto (RDP) en Windows. + 6. Activa las reglas correspondientes del Firewall. + 7. Añade "tecnica" al grupo de usuarios de Escritorio Remoto. + 8. Oculta "tecnica" de la pantalla de inicio de sesión. + 9. Puede ejecutarse varias veces sin recrear ni modificar + innecesariamente el usuario. + + IMPORTANTE: + - La ocultación del usuario NO es una medida de seguridad. + - La cuenta sigue existiendo y puede utilizarse mediante RDP. + - Si "tecnica" ya existe, NO se modifica su contraseña. +#> + +# ------------------------------------------------------------ +# CONFIGURACIÓN +# ------------------------------------------------------------ + +$Username = "tecnica" + +# ------------------------------------------------------------ +# COMPROBAR SI SOMOS ADMINISTRADOR +# ------------------------------------------------------------ + +function Test-IsAdministrator { + + $identity = [Security.Principal.WindowsIdentity]::GetCurrent() + + $principal = New-Object Security.Principal.WindowsPrincipal($identity) + + return $principal.IsInRole( + [Security.Principal.WindowsBuiltInRole]::Administrator + ) +} + +# ------------------------------------------------------------ +# AUTOELEVAR EL SCRIPT +# ------------------------------------------------------------ + +function Restart-AsAdministrator { + + if (Test-IsAdministrator) { + return + } + + Write-Host "" + Write-Host "El script necesita permisos de Administrador." -ForegroundColor Yellow + Write-Host "Solicitando elevación..." -ForegroundColor Yellow + Write-Host "" + + # Volvemos a ejecutar este mismo script como Administrador. + Start-Process ` + -FilePath "powershell.exe" ` + -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" ` + -Verb RunAs + + # Cerramos esta instancia sin privilegios. + exit +} + +# ------------------------------------------------------------ +# COMPROBAR SI EXISTE UN USUARIO LOCAL +# ------------------------------------------------------------ + +function Test-LocalUserExists { + + param ( + [Parameter(Mandatory)] + [string]$Name + ) + + try { + + Get-LocalUser ` + -Name $Name ` + -ErrorAction Stop | + Out-Null + + return $true + } + catch { + + return $false + } +} + +# ------------------------------------------------------------ +# COMPROBAR SI UN USUARIO PERTENECE A UN GRUPO +# ------------------------------------------------------------ + +function Test-UserInLocalGroup { + + param ( + [Parameter(Mandatory)] + [string]$User, + + [Parameter(Mandatory)] + [string]$Group + ) + + try { + + $members = Get-LocalGroupMember ` + -Group $Group ` + -ErrorAction Stop + + foreach ($member in $members) { + + # Ejemplo: + # DESKTOP-123456\tecnica + + if ($member.Name -match "\\$([regex]::Escape($User))$") { + return $true + } + } + + return $false + } + catch { + + return $false + } +} + +# ------------------------------------------------------------ +# BUSCAR UN GRUPO LOCAL POR SU NOMBRE EN ESPAÑOL O INGLÉS +# ------------------------------------------------------------ + +function Get-LocalGroupByKnownNames { + + param ( + [Parameter(Mandatory)] + [string[]]$Names + ) + + foreach ($name in $Names) { + + try { + + $group = Get-LocalGroup ` + -Name $name ` + -ErrorAction Stop + + return $group + } + catch { + # Probamos el siguiente nombre. + } + } + + throw "No se encontró ninguno de estos grupos: $($Names -join ', ')" +} + +# ------------------------------------------------------------ +# PEDIR CONTRASEÑA DOS VECES +# ------------------------------------------------------------ + +function Read-AndConfirmPassword { + + while ($true) { + + Write-Host "" + Write-Host "Introduce la contraseña para '$Username'." ` + -ForegroundColor Cyan + + $password1 = Read-Host ` + "Contraseña" ` + -AsSecureString + + $password2 = Read-Host ` + "Repite la contraseña" ` + -AsSecureString + + # Convertimos temporalmente a texto para poder comparar. + $ptr1 = [Runtime.InteropServices.Marshal]::SecureStringToBSTR( + $password1 + ) + + $ptr2 = [Runtime.InteropServices.Marshal]::SecureStringToBSTR( + $password2 + ) + + try { + + $plain1 = [Runtime.InteropServices.Marshal]::PtrToStringBSTR( + $ptr1 + ) + + $plain2 = [Runtime.InteropServices.Marshal]::PtrToStringBSTR( + $ptr2 + ) + + if ([string]::IsNullOrWhiteSpace($plain1)) { + + Write-Host "" + Write-Host "La contraseña no puede estar vacía." ` + -ForegroundColor Red + + continue + } + + if ($plain1 -cne $plain2) { + + Write-Host "" + Write-Host "Las contraseñas no coinciden." ` + -ForegroundColor Red + + continue + } + + return $password1 + } + finally { + + # Liberamos los BSTR de memoria. + if ($ptr1 -ne [IntPtr]::Zero) { + [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr1) + } + + if ($ptr2 -ne [IntPtr]::Zero) { + [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr2) + } + + $plain1 = $null + $plain2 = $null + } + } +} + +# ------------------------------------------------------------ +# CREAR EL USUARIO SI NO EXISTE +# ------------------------------------------------------------ + +function Ensure-LocalUser { + + param ( + [Parameter(Mandatory)] + [string]$Name + ) + + if (Test-LocalUserExists -Name $Name) { + + Write-Host "[OK] El usuario '$Name' ya existe." ` + -ForegroundColor Green + + return Get-LocalUser -Name $Name + } + + Write-Host "" + Write-Host "El usuario '$Name' no existe." ` + -ForegroundColor Yellow + + $password = Read-AndConfirmPassword + + Write-Host "" + Write-Host "Creando usuario '$Name'..." ` + -ForegroundColor Cyan + + New-LocalUser ` + -Name $Name ` + -Password $password ` + -Description "Cuenta técnica de administración" ` + -AccountNeverExpires ` + -PasswordNeverExpires:$true + + Write-Host "[OK] Usuario '$Name' creado." ` + -ForegroundColor Green + + return Get-LocalUser -Name $Name +} + +# ------------------------------------------------------------ +# AÑADIR USUARIO A UN GRUPO +# ------------------------------------------------------------ + +function Ensure-UserInGroup { + + param ( + [Parameter(Mandatory)] + [string]$User, + + [Parameter(Mandatory)] + [string[]]$PossibleGroupNames + ) + + # Buscar el nombre real del grupo en este Windows. + $group = Get-LocalGroupByKnownNames ` + -Names $PossibleGroupNames + + $groupName = $group.Name + + if (Test-UserInLocalGroup ` + -User $User ` + -Group $groupName) { + + Write-Host "[OK] '$User' ya pertenece a '$groupName'." ` + -ForegroundColor Green + + return + } + + Write-Host "" + Write-Host "Añadiendo '$User' a '$groupName'..." ` + -ForegroundColor Cyan + + Add-LocalGroupMember ` + -Group $groupName ` + -Member $User + + Write-Host "[OK] Usuario añadido a '$groupName'." ` + -ForegroundColor Green +} + +# ------------------------------------------------------------ +# ACTIVAR ESCRITORIO REMOTO +# ------------------------------------------------------------ + +function Enable-RemoteDesktop { + + Write-Host "" + Write-Host "Configurando Escritorio remoto..." ` + -ForegroundColor Cyan + + # -------------------------------------------------------- + # 1. Permitir conexiones RDP + # + # fDenyTSConnections = 0 + # significa que NO se deniegan las conexiones RDP. + # -------------------------------------------------------- + + $rdpRegistryPath = + "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" + + Set-ItemProperty ` + -Path $rdpRegistryPath ` + -Name "fDenyTSConnections" ` + -Type DWord ` + -Value 0 + + Write-Host "[OK] Conexiones RDP habilitadas." ` + -ForegroundColor Green + + + # -------------------------------------------------------- + # 2. Configurar el servicio de Escritorio remoto + # -------------------------------------------------------- + + $service = Get-Service ` + -Name "TermService" ` + -ErrorAction Stop + + # Dejamos el servicio con inicio manual. + # Windows puede iniciarlo cuando sea necesario. + Set-Service ` + -Name "TermService" ` + -StartupType Manual + + # Si no está funcionando, lo arrancamos. + if ($service.Status -ne "Running") { + + Start-Service ` + -Name "TermService" ` + -ErrorAction Stop + } + + Write-Host "[OK] Servicio de Escritorio remoto iniciado." ` + -ForegroundColor Green + + + # -------------------------------------------------------- + # 3. Abrir el Firewall para RDP + # + # DisplayGroup puede aparecer en español o inglés, + # dependiendo de la instalación. + # -------------------------------------------------------- + + $firewallRules = Get-NetFirewallRule ` + -ErrorAction SilentlyContinue | + Where-Object { + + $_.DisplayGroup -in @( + "Remote Desktop", + "Escritorio remoto" + ) + } + + if ($firewallRules) { + + $firewallRules | + Enable-NetFirewallRule + + Write-Host "[OK] Firewall configurado para RDP." ` + -ForegroundColor Green + } + else { + + Write-Host "[AVISO] No se encontraron las reglas de Firewall de RDP." ` + -ForegroundColor Yellow + } +} + +# ------------------------------------------------------------ +# OCULTAR USUARIO DE LA PANTALLA DE LOGIN +# ------------------------------------------------------------ + +function Hide-UserFromLoginScreen { + + param ( + [Parameter(Mandatory)] + [string]$User + ) + + Write-Host "" + Write-Host "Ocultando '$User' de la pantalla de login..." ` + -ForegroundColor Cyan + + $registryPath = + "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList" + + # Crear la clave si no existe. + if (-not (Test-Path $registryPath)) { + + New-Item ` + -Path $registryPath ` + -Force | + Out-Null + } + + # DWORD 0 = no mostrar en la pantalla de login. + New-ItemProperty ` + -Path $registryPath ` + -Name $User ` + -PropertyType DWord ` + -Value 0 ` + -Force | + Out-Null + + Write-Host "[OK] '$User' ocultado de la pantalla de login." ` + -ForegroundColor Green +} + +# ============================================================ +# INICIO DEL SCRIPT +# ============================================================ + +Clear-Host + +Write-Host "==================================================" ` + -ForegroundColor Cyan + +Write-Host " CONFIGURACIÓN INICIAL DE WINDOWS 10" ` + -ForegroundColor Cyan + +Write-Host "==================================================" ` + -ForegroundColor Cyan + +Write-Host "" + +# ------------------------------------------------------------ +# 1. ELEVAR A ADMINISTRADOR +# ------------------------------------------------------------ + +Restart-AsAdministrator + +Write-Host "[OK] Ejecutando con privilegios de Administrador." ` + -ForegroundColor Green + +Write-Host "" + +# ------------------------------------------------------------ +# 2. CREAR USUARIO "TECNICA" +# ------------------------------------------------------------ + +Ensure-LocalUser ` + -Name $Username | + Out-Null + +# ------------------------------------------------------------ +# 3. HACERLO ADMINISTRADOR +# ------------------------------------------------------------ + +Ensure-UserInGroup ` + -User $Username ` + -PossibleGroupNames @( + "Administradores", + "Administrators" + ) + +# ------------------------------------------------------------ +# 4. ACTIVAR ESCRITORIO REMOTO EN WINDOWS +# ------------------------------------------------------------ + +Enable-RemoteDesktop + +# ------------------------------------------------------------ +# 5. PERMITIR AL USUARIO "TECNICA" USAR RDP +# ------------------------------------------------------------ + +Ensure-UserInGroup ` + -User $Username ` + -PossibleGroupNames @( + "Usuarios de escritorio remoto", + "Remote Desktop Users" + ) + +# ------------------------------------------------------------ +# 6. OCULTAR "TECNICA" DEL LOGIN +# ------------------------------------------------------------ + +Hide-UserFromLoginScreen ` + -User $Username + +# ============================================================ +# FINAL +# ============================================================ + +Write-Host "" +Write-Host "==================================================" ` + -ForegroundColor Green + +Write-Host " CONFIGURACIÓN COMPLETADA" ` + -ForegroundColor Green + +Write-Host "==================================================" ` + -ForegroundColor Green + +Write-Host "" + +Write-Host "Usuario: $Username" +Write-Host "Administrador: SI" +Write-Host "Escritorio remoto: ACTIVADO" +Write-Host "Usuario autorizado: SI" +Write-Host "Firewall RDP: CONFIGURADO" +Write-Host "Visible en login: NO" + +Write-Host "" +Write-Host "El script es idempotente y puede volver a ejecutarse." ` + -ForegroundColor Green + +Write-Host "" +Write-Host "Pulsa ENTER para salir..." +Read-Host +```