# audit_windows.ps1
# Script de auditoría para Windows (equivalente PowerShell del script Linux)
# Requiere PowerShell 7+ para colores; si no, eliminar los códigos de color.

# Definimos el fichero donde se grabará todo el output
$LogFile = "auditoria_permisos_win.txt"
Start-Transcript -Path $LogFile -Force

$RED   = "`e[31m"
$GREEN = "`e[32m"
$NC    = "`e[0m"

function Write-Color($text, $color) {
    Write-Host "$color$text$NC"
}

# --- Comprobar privilegios de administrador ---
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
    ).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Color "Este script debe ejecutarse como Administrador." $RED
    exit 1
}

Write-Host ""
Write-Host "==============================="
Write-Color "Control Op.acc.1 – Identificación" $NC
Write-Host "==============================="

Write-Color "Verificar si hay usuarios habilitados sin requerir contraseña" $NC

# Filtrar para ignorar cuentas de sistema
$users = Get-LocalUser |
    Where-Object {
        $_.Enabled -eq $true -and
        $_.Name -notin @('DefaultAccount','WDAGUtilityAccount','Invitado')
    }
$vulnerables = 0

foreach ($user in $users) {
    if ($user.PasswordRequired -eq $false) {
        Write-Color "Usuario habilitado sin requerir contraseña: $($user.Name)" $RED
        $vulnerables++
    }
}

if ($vulnerables -eq 0) {
    Write-Color "Todos los usuarios habilitados requieren contraseña." $GREEN
}

Write-Host ""
Write-Color "Verificar si hay usuarios con configuración sospechosa (contraseña que nunca expira o expiración definida)" $NC

$bandera = 0

# Verificación de contraseña que nunca expira usando WMI, filtrando cuentas de sistema
$wmiUsers = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount=True" |
    Where-Object { $_.Name -notin @('DefaultAccount','WDAGUtilityAccount','Invitado') }

foreach ($user in $wmiUsers) {
    if ($user.PasswordExpires -eq $false -and $user.Disabled -eq $false) {
        Write-Color "Usuario con contraseña que nunca expira: $($user.Name)" $RED
        $bandera++
    }
}

# Verificación de fecha de expiración definida (menos común)
foreach ($user in $users) {
    if ($user.AccountExpires -and $user.AccountExpires -ne 0) {
        Write-Color "Usuario con fecha de expiración definida: $($user.Name) expira el $($user.AccountExpires)" $RED
        $bandera++
    }
}

if ($bandera -eq 0) {
    Write-Color "Todos los usuarios tienen una configuración adecuada de expiración." $GREEN
}


Write-Host ""
Write-Host "==============================="
Write-Color "Control Op.acc.2 – Requisitos de acceso" $NC
Write-Host "==============================="

Write-Color "Verificar si hay usuarios en grupos privilegiados (Administradores, Usuarios de escritorio remoto, Operadores de copia de seguridad)" $NC

$gruposCriticos = @(
    "Administradores",
    "Usuarios de escritorio remoto",
    "Operadores de copia de seguridad"
)

foreach ($grupo in $gruposCriticos) {
    try {
        $miembros = Get-LocalGroupMember -Group $grupo -ErrorAction Stop
        foreach ($miembro in $miembros) {
            Write-Color "Usuario con privilegios en grupo $grupo – $($miembro.Name)" $RED
        }
        if ($miembros.Count -eq 0) {
            Write-Color "No hay miembros en el grupo $grupo." $GREEN
        }
    } catch {
        Write-Color "No se pudo acceder al grupo $grupo (puede no existir)." $NC
    }
}


Write-Host ""
Write-Host "==============================="
Write-Color "Control Op.acc.4 – Proceso de gestión de derechos de acceso" $NC
Write-Host "==============================="

Write-Color "Verificar cuentas deshabilitadas (bloqueadas pero no eliminadas)" $NC

$disabled = Get-LocalUser | Where-Object { $_.Enabled -eq $false }
if ($disabled.Count -gt 0) {
    foreach ($user in $disabled) {
        Write-Color "Cuenta deshabilitada: $($user.Name)" $RED
    }
} else {
    Write-Color "No hay cuentas deshabilitadas." $GREEN
}

Write-Host ""
Write-Host "Verificar usuarios con cuenta expirada" 
Write-Color "(usando WMI)" $NC

$expired = 0
$wmiUsers = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount=True"
foreach ($user in $wmiUsers) {
    if ($user.AccountExpirationDate) {
        $expiration = [datetime]::Parse($user.AccountExpirationDate)
        if ($expiration -lt (Get-Date)) {
            Write-Color "Usuario expirado: $($user.Name) (expiró el $($expiration.ToShortDateString()))" $RED
            $expired++
        }
    }
}
if ($expired -eq 0) {
    Write-Color "No hay cuentas locales expiradas." $GREEN
}


Write-Host ""
Write-Host "==============================="
Write-Color "Control Op.acc.5 – Mecanismos de autenticación (usuarios externos)" $NC
Write-Host "==============================="

Write-Color "Verificar si el acceso remoto (RDP) está habilitado" $NC
$rdpReg = Get-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -ErrorAction SilentlyContinue
if ($rdpReg -and $rdpReg.fDenyTSConnections -eq 0) {
    Write-Color "RDP está habilitado en este sistema." $RED
} else {
    Write-Color "RDP está deshabilitado (bloqueando acceso remoto)." $GREEN
}

Write-Host ""
Write-Color "Verificar si el usuario 'Administrador' está habilitado y puede iniciar sesión por RDP" $NC
$admin = Get-LocalUser -Name "Administrador" -ErrorAction SilentlyContinue
if ($admin -and $admin.Enabled -eq $true) {
    Write-Color "La cuenta 'Administrador' está habilitada (puede permitir RDP si está en grupo adecuado)." $RED
} else {
    Write-Color "La cuenta 'Administrador' está deshabilitada o no existe." $GREEN
}

Write-Host ""
Write-Color "Verificar miembros del grupo 'Usuarios de escritorio remoto'" $NC
try {
    $rdpUsers = Get-LocalGroupMember -Group "Usuarios de escritorio remoto"
    foreach ($user in $rdpUsers) {
        Write-Color "Usuario con permisos RDP: $($user.Name)" $RED
    }
    if ($rdpUsers.Count -eq 0) {
        Write-Color "No hay usuarios en el grupo de Escritorio Remoto." $GREEN
    }
} catch {
    Write-Color "El grupo 'Usuarios de escritorio remoto' no existe." $NC
}


Write-Host ""
Write-Host "==============================="
Write-Color "Control Op.acc.6 – Mecanismos de autenticación (usuarios internos)" $NC
Write-Host "==============================="

Write-Color "Verificar políticas de contraseña (vigencia, complejidad, bloqueo, etc.)" $NC
$cuenta = net accounts

function Revisar-Valor {
    param (
        [string]$linea,
        [string]$clave,
        [string]$esperado,
        [bool]$invertido = $false
    )
    if ($cuenta -match $linea) {
        $valor = ($cuenta | Select-String $linea).ToString().Split(":")[1].Trim()
        $mensaje = "$clave = $valor"
        if ($invertido) {
            if ($valor -ne $esperado) {
                Write-Color "$mensaje (correcto)" $GREEN
            } else {
                Write-Color "$mensaje (debería ser distinto a $esperado)" $RED
            }
        } else {
            if ($valor -eq $esperado) {
                Write-Color "$mensaje (correcto)" $GREEN
            } else {
                Write-Color "$mensaje (esperado: $esperado)" $RED
            }
        }
    } else {
        Write-Color "$clave no encontrado" $NC
    }
}

Revisar-Valor "Duración máx. de contraseña" "PASS_MAX_DAYS" "90"
Revisar-Valor "Duración mín. de contraseña" "PASS_MIN_DAYS" "1"
Revisar-Valor "Umbral de bloqueo" "INTENTOS_FALLIDOS" "5"

Write-Host ""

# Solo llamamos a Stop-Transcript si realmente se inició Start-Transcript:
try {
    Stop-Transcript
} catch {
    # Si no estaba transcribiendo, se ignora el error silently
}
