```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 ```