557 lines
14 KiB
PowerShell
557 lines
14 KiB
PowerShell
```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
|
|
```
|