Volver
Módulo 8 - Administración del Sistema AVANZADO

Automatización de Usuarios

Automatiza la gestión completa de usuarios del sistema con scripts profesionales

La automatización de la gestión de usuarios es una tarea crítica para administradores de sistemas. Bash proporciona herramientas poderosas para crear, modificar, eliminar y mantener usuarios de forma eficiente y consistente.

Comandos Básicos de Gestión de Usuarios

Comando Función Ejemplo
useradd Crear nuevo usuario useradd -m -s /bin/bash juan
usermod Modificar usuario existente usermod -G admin,dev juan
userdel Eliminar usuario userdel -r juan
passwd Cambiar contraseña passwd juan
chage Gestionar caducidad de cuenta chage -M 90 juan
groups Mostrar grupos del usuario groups juan
id Información detallada del usuario id juan

Script Básico para Crear Usuarios

Creación básica - create_user.sh
bash
#!/bin/bash

# Script básico para crear usuarios
# Requiere privilegios de root

set -euo pipefail

# Verificar privilegios de root
if [ "$EUID" -ne 0 ]; then
    echo "Error: Este script debe ejecutarse como root" >&2
    exit 1
fi

# Función para logging
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}

# Función para crear usuario
crear_usuario() {
    local username="$1"
    local full_name="$2"
    local shell="${3:-/bin/bash}"
    local groups="$4"
    
    log "Creando usuario: $username"
    
    # Verificar si el usuario ya existe
    if id "$username" &>/dev/null; then
        log "WARN: El usuario $username ya existe"
        return 1
    fi
    
    # Crear usuario con directorio home
    useradd -m -s "$shell" -c "$full_name" "$username"
    
    if [ $? -eq 0 ]; then
        log "✓ Usuario $username creado exitosamente"
    else
        log "✗ Error al crear usuario $username"
        return 1
    fi
    
    # Agregar a grupos adicionales si se especifican
    if [ -n "$groups" ]; then
        usermod -a -G "$groups" "$username"
        log "✓ Usuario $username agregado a grupos: $groups"
    fi
    
    # Configurar contraseña temporal
    echo "$username:temporal123" | chpasswd
    
    # Forzar cambio de contraseña en el primer login
    chage -d 0 "$username"
    log "✓ Configurada contraseña temporal para $username"
    
    return 0
}

# Función principal
main() {
    if [ $# -lt 2 ]; then
        echo "Uso: $0 nombre_usuario nombre_completo [shell] [grupos]"
        echo "Ejemplo: $0 juan 'Juan Pérez' /bin/bash 'users,developers'"
        exit 1
    fi
    
    local username="$1"
    local full_name="$2"
    local shell="${3:-/bin/bash}"
    local groups="${4:-}"
    
    log "Iniciando creación de usuario"
    
    if crear_usuario "$username" "$full_name" "$shell" "$groups"; then
        log "Proceso completado exitosamente"
        
        # Mostrar información del usuario creado
        echo ""
        echo "=== INFORMACIÓN DEL USUARIO ==="
        id "$username"
        echo "Directorio home: $(getent passwd "$username" | cut -d: -f6)"
        echo "Shell: $(getent passwd "$username" | cut -d: -f7)"
        echo "Grupos: $(groups "$username")"
        echo ""
        echo "NOTA: La contraseña temporal es 'temporal123'"
        echo "El usuario debe cambiarla en el primer login"
    else
        log "Error en el proceso de creación"
        exit 1
    fi
}

main "$@"
sudo ./create_user.sh developer "Juan Desarrollador" /bin/bash "developers,users"

Sistema Avanzado de Gestión de Usuarios

Gestión completa - user_manager.sh
bash
#!/bin/bash

# Sistema avanzado de gestión de usuarios
# Autor: Admin del Sistema
# Versión: 2.0

set -euo pipefail

# Configuración
declare -g CONFIG_FILE="${CONFIG_FILE:-/etc/user_manager.conf}"
declare -g LOG_FILE="${LOG_FILE:-/var/log/user_manager.log}"
declare -g DEFAULT_SHELL="/bin/bash"
declare -g DEFAULT_GROUPS="users"
declare -g HOME_BASE="/home"
declare -g BACKUP_DIR="/var/backups/user_manager"

# Crear directorio de backup si no existe
mkdir -p "$BACKUP_DIR"

# Función de logging avanzado
log() {
    local level="$1"
    shift
    local message="$*"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local log_entry="[$timestamp] [$level] $message"
    
    echo "$log_entry" | tee -a "$LOG_FILE" >&2
}

# Funciones de logging específicas
log_info() { log "INFO" "$@"; }
log_warn() { log "WARN" "$@"; }
log_error() { log "ERROR" "$@"; }

# Verificar privilegios
check_root() {
    if [ "$EUID" -ne 0 ]; then
        log_error "Este script debe ejecutarse como root"
        exit 1
    fi
}

# Validar nombre de usuario
validate_username() {
    local username="$1"
    
    # Verificar longitud
    if [ ${#username} -lt 3 ] || [ ${#username} -gt 32 ]; then
        log_error "El nombre de usuario debe tener entre 3 y 32 caracteres"
        return 1
    fi
    
    # Verificar formato
    if [[ ! "$username" =~ ^[a-z][a-z0-9_-]*$ ]]; then
        log_error "Nombre de usuario inválido. Debe comenzar con letra minúscula y contener solo letras, números, _ y -"
        return 1
    fi
    
    return 0
}

# Generar contraseña segura
generate_password() {
    local length="${1:-12}"
    
    # Usar openssl si está disponible
    if command -v openssl >/dev/null; then
        openssl rand -base64 "$length" | tr -d "=+/" | cut -c1-"$length"
    else
        # Fallback usando /dev/urandom
        tr -dc A-Za-z0-9 /dev/null; then
        log_error "El usuario $username ya existe"
        return 1
    fi
    
    # Crear backup
    local backup_path
    backup_path=$(backup_system_files)
    
    # Construir comando useradd
    local useradd_cmd="useradd -m"
    useradd_cmd+=" -d $HOME_BASE/$username"
    useradd_cmd+=" -s $shell"
    useradd_cmd+=" -c '$full_name'"
    
    # Agregar fecha de expiración si se especifica
    if [ -n "$expire_date" ]; then
        useradd_cmd+=" -e $expire_date"
    fi
    
    useradd_cmd+=" $username"
    
    # Ejecutar creación
    log_info "Ejecutando: $useradd_cmd"
    eval "$useradd_cmd"
    
    if [ $? -eq 0 ]; then
        log_info "✓ Usuario $username creado exitosamente"
    else
        log_error "Error al crear usuario $username"
        return 1
    fi
    
    # Agregar a grupos
    if [ "$groups" != "users" ] && [ -n "$groups" ]; then
        usermod -a -G "$groups" "$username"
        log_info "✓ Usuario agregado a grupos: $groups"
    fi
    
    # Configurar contraseña
    local password
    if [ "$generate_pwd" = true ]; then
        password=$(generate_password)
        echo "$username:$password" | chpasswd
        log_info "✓ Contraseña generada automáticamente"
        
        # Guardar contraseña de forma segura
        echo "$username:$password" >> "$backup_path/passwords.txt"
        chmod 600 "$backup_path/passwords.txt"
    else
        # Forzar cambio de contraseña en próximo login
        chage -d 0 "$username"
        password="[Usuario debe configurar]"
    fi
    
    # Configurar estructura del directorio home
    setup_user_home "$username"
    
    # Crear información del usuario
    create_user_info_file "$username" "$full_name" "$email" "$password"
    
    log_info "Usuario $username creado completamente"
    return 0
}

# Configurar directorio home del usuario
setup_user_home() {
    local username="$1"
    local home_dir="$HOME_BASE/$username"
    
    log_info "Configurando directorio home para $username"
    
    # Crear directorios básicos
    su - "$username" -c "mkdir -p ~/bin ~/tmp ~/docs ~/projects"
    
    # Configurar bashrc personalizado
    cat >> "$home_dir/.bashrc" << 'EOF'

# Configuración personalizada del usuario
export PATH="$HOME/bin:$PATH"
alias ll='ls -la'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'

# Prompt personalizado
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
EOF
    
    # Crear archivo de información
    cat > "$home_dir/.user_info" << EOF
Usuario creado: $(date)
Administrador: $(whoami)
Sistema: $(uname -a)
EOF
    
    # Ajustar permisos
    chown -R "$username:$username" "$home_dir"
    chmod 755 "$home_dir"
    
    log_info "✓ Directorio home configurado"
}

# Crear archivo de información del usuario
create_user_info_file() {
    local username="$1"
    local full_name="$2"
    local email="$3"
    local password="$4"
    local info_file="/tmp/user_${username}_info.txt"
    
    cat > "$info_file" << EOF
=== INFORMACIÓN DEL USUARIO ===
Usuario: $username
Nombre completo: $full_name
Email: $email
Contraseña inicial: $password
Directorio home: $HOME_BASE/$username
Shell: $(getent passwd "$username" | cut -d: -f7)
Grupos: $(groups "$username" | cut -d: -f2-)
UID: $(id -u "$username")
GID: $(id -g "$username")
Creado: $(date)
Administrador: $(whoami)

INSTRUCCIONES PARA EL USUARIO:
1. La contraseña inicial es temporal
2. Debe cambiarla en el primer login
3. El directorio home está en $HOME_BASE/$username
4. Se han creado directorios básicos (bin, tmp, docs, projects)

=== COMANDOS ÚTILES ===
- Cambiar contraseña: passwd
- Ver información: id
- Ver grupos: groups
- Listar archivos: ls -la

EOF
    
    chmod 600 "$info_file"
    log_info "Archivo de información creado: $info_file"
}

# Modificar usuario existente
modify_user() {
    local username="$1"
    local action="$2"
    local value="$3"
    
    log_info "Modificando usuario $username: $action = $value"
    
    # Verificar que el usuario existe
    if ! id "$username" &>/dev/null; then
        log_error "El usuario $username no existe"
        return 1
    fi
    
    # Crear backup
    backup_system_files
    
    case "$action" in
        "shell")
            usermod -s "$value" "$username"
            log_info "✓ Shell cambiado a $value"
            ;;
        "groups")
            usermod -G "$value" "$username"
            log_info "✓ Grupos actualizados a: $value"
            ;;
        "add_groups")
            usermod -a -G "$value" "$username"
            log_info "✓ Agregado a grupos: $value"
            ;;
        "expire")
            chage -E "$value" "$username"
            log_info "✓ Fecha de expiración establecida: $value"
            ;;
        "lock")
            usermod -L "$username"
            log_info "✓ Usuario bloqueado"
            ;;
        "unlock")
            usermod -U "$username"
            log_info "✓ Usuario desbloqueado"
            ;;
        *)
            log_error "Acción no reconocida: $action"
            return 1
            ;;
    esac
    
    return 0
}

# Eliminar usuario
delete_user() {
    local username="$1"
    local keep_home="${2:-false}"
    
    log_info "Eliminando usuario: $username (mantener home: $keep_home)"
    
    # Verificar que el usuario existe
    if ! id "$username" &>/dev/null; then
        log_error "El usuario $username no existe"
        return 1
    fi
    
    # Crear backup
    local backup_path
    backup_path=$(backup_system_files)
    
    # Crear backup del directorio home si existe
    local home_dir
    home_dir=$(getent passwd "$username" | cut -d: -f6)
    
    if [ -d "$home_dir" ]; then
        log_info "Creando backup del directorio home"
        tar -czf "$backup_path/home_${username}_$(date +%Y%m%d_%H%M%S).tar.gz" -C "$(dirname "$home_dir")" "$(basename "$home_dir")"
    fi
    
    # Eliminar usuario
    if [ "$keep_home" = true ]; then
        userdel "$username"
        log_info "✓ Usuario eliminado (directorio home mantenido)"
    else
        userdel -r "$username"
        log_info "✓ Usuario y directorio home eliminados"
    fi
    
    return 0
}

# Listar usuarios del sistema
list_users() {
    local filter="${1:-all}"
    
    echo "=== USUARIOS DEL SISTEMA ==="
    
    case "$filter" in
        "human")
            # Usuarios con UID >= 1000 (usuarios humanos)
            awk -F: '$3 >= 1000 && $3 < 65534 { printf "%-15s %-25s %s\n", $1, $5, $6 }' /etc/passwd
            ;;
        "system")
            # Usuarios del sistema (UID < 1000)
            awk -F: '$3 < 1000 { printf "%-15s %-25s %s\n", $1, $5, $6 }' /etc/passwd
            ;;
        *)
            # Todos los usuarios
            awk -F: '{ printf "%-15s %-25s %s\n", $1, $5, $6 }' /etc/passwd
            ;;
    esac
}

# Generar reporte de usuarios
generate_report() {
    local output_file="${1:-/tmp/users_report_$(date +%Y%m%d_%H%M%S).txt}"
    
    log_info "Generando reporte en: $output_file"
    
    cat > "$output_file" << EOF
=== REPORTE DE USUARIOS DEL SISTEMA ===
Fecha: $(date)
Sistema: $(uname -a)
Administrador: $(whoami)

=== RESUMEN ===
Total usuarios: $(wc -l < /etc/passwd)
Usuarios humanos (UID >= 1000): $(awk -F: '$3 >= 1000 && $3 < 65534' /etc/passwd | wc -l)
Usuarios del sistema (UID < 1000): $(awk -F: '$3 < 1000' /etc/passwd | wc -l)

=== USUARIOS HUMANOS ===
EOF
    
    echo "Usuario         Nombre Completo           UID  GID  Home" >> "$output_file"
    echo "=============== ========================= ==== ==== ============================" >> "$output_file"
    awk -F: '$3 >= 1000 && $3 < 65534 { printf "%-15s %-25s %4d %4d %s\n", $1, $5, $3, $4, $6 }' /etc/passwd >> "$output_file"
    
    echo "" >> "$output_file"
    echo "=== USUARIOS CON CONTRASEÑAS CADUCADAS ===" >> "$output_file"
    
    # Verificar contraseñas caducadas
    while IFS=: read -r username _ _ _ max_days _ _ expire_date _; do
        if [ -n "$expire_date" ] && [ "$expire_date" != "-1" ]; then
            current_date=$(date +%s)
            expire_epoch=$((expire_date * 86400))
            
            if [ "$current_date" -gt "$expire_epoch" ]; then
                echo "- $username (caducó: $(date -d @$expire_epoch '+%Y-%m-%d'))" >> "$output_file"
            fi
        fi
    done < /etc/shadow
    
    log_info "✓ Reporte generado: $output_file"
    echo "$output_file"
}

# Función de ayuda
show_help() {
    cat << EOF
Sistema de Gestión de Usuarios v2.0

USO:
    $0 COMANDO [OPCIONES]

COMANDOS:
    create USERNAME "FULL_NAME" [EMAIL] [SHELL] [GROUPS] [EXPIRE_DATE]
        Crear nuevo usuario
        
    modify USERNAME ACTION VALUE
        Modificar usuario existente
        Acciones: shell, groups, add_groups, expire, lock, unlock
        
    delete USERNAME [keep_home]
        Eliminar usuario (keep_home: true/false)
        
    list [filter]
        Listar usuarios (filter: all/human/system)
        
    report [output_file]
        Generar reporte completo
        
    help
        Mostrar esta ayuda

EJEMPLOS:
    # Crear usuario
    $0 create developer "Juan Desarrollador" [email protected] /bin/bash "developers,users" "2024-12-31"
    
    # Modificar usuario
    $0 modify developer add_groups "admin"
    
    # Eliminar usuario manteniendo home
    $0 delete developer true
    
    # Listar solo usuarios humanos
    $0 list human
    
    # Generar reporte
    $0 report /tmp/mi_reporte.txt

ARCHIVOS:
    Config: $CONFIG_FILE
    Log: $LOG_FILE
    Backup: $BACKUP_DIR
EOF
}

# Función principal
main() {
    check_root
    
    if [ $# -eq 0 ]; then
        show_help
        exit 1
    fi
    
    local command="$1"
    shift
    
    case "$command" in
        "create")
            if [ $# -lt 2 ]; then
                log_error "Argumentos insuficientes para crear usuario"
                echo "Uso: $0 create USERNAME 'FULL_NAME' [EMAIL] [SHELL] [GROUPS] [EXPIRE_DATE]"
                exit 1
            fi
            create_user "$@"
            ;;
        "modify")
            if [ $# -lt 3 ]; then
                log_error "Argumentos insuficientes para modificar usuario"
                echo "Uso: $0 modify USERNAME ACTION VALUE"
                exit 1
            fi
            modify_user "$@"
            ;;
        "delete")
            if [ $# -lt 1 ]; then
                log_error "Debe especificar el nombre de usuario a eliminar"
                exit 1
            fi
            delete_user "$@"
            ;;
        "list")
            list_users "$@"
            ;;
        "report")
            generate_report "$@"
            ;;
        "help"|"-h"|"--help")
            show_help
            ;;
        *)
            log_error "Comando desconocido: $command"
            show_help
            exit 1
            ;;
    esac
}

# Ejecutar función principal
main "$@"

Creación de Usuarios en Lote

Procesamiento en lote - batch_users.sh
bash
#!/bin/bash

# Script para crear usuarios en lote desde archivo CSV
# Formato CSV: username,full_name,email,groups,shell,expire_date

set -euo pipefail

# Configuración
CSV_FILE="$1"
LOG_FILE="/var/log/batch_users_$(date +%Y%m%d_%H%M%S).log"
REPORT_FILE="/tmp/batch_users_report_$(date +%Y%m%d_%H%M%S).txt"

# Contadores
declare -g USERS_CREATED=0
declare -g USERS_FAILED=0
declare -g USERS_SKIPPED=0

# Array para almacenar información de usuarios creados
declare -ga CREATED_USERS=()

# Función de logging
log() {
    local message="[$(date '+%Y-%m-%d %H:%M:%S')] $*"
    echo "$message" | tee -a "$LOG_FILE"
}

# Verificar privilegios de root
check_root() {
    if [ "$EUID" -ne 0 ]; then
        echo "Error: Este script debe ejecutarse como root" >&2
        exit 1
    fi
}

# Validar archivo CSV
validate_csv() {
    local csv_file="$1"
    
    if [ ! -f "$csv_file" ]; then
        log "ERROR: Archivo CSV no encontrado: $csv_file"
        exit 1
    fi
    
    if [ ! -r "$csv_file" ]; then
        log "ERROR: No se puede leer el archivo CSV: $csv_file"
        exit 1
    fi
    
    # Verificar que tiene contenido
    if [ ! -s "$csv_file" ]; then
        log "ERROR: El archivo CSV está vacío"
        exit 1
    fi
    
    log "Archivo CSV validado: $csv_file"
}

# Generar contraseña segura
generate_password() {
    openssl rand -base64 12 | tr -d "=+/" | cut -c1-12
}

# Procesar una línea del CSV
process_user_line() {
    local line="$1"
    local line_number="$2"
    
    # Saltar líneas vacías o comentarios
    if [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]]; then
        return 0
    fi
    
    # Parsear CSV (manejo básico, sin comillas complejas)
    IFS=',' read -ra FIELDS <<< "$line"
    
    local username="${FIELDS[0]:-}"
    local full_name="${FIELDS[1]:-}"
    local email="${FIELDS[2]:-}"
    local groups="${FIELDS[3]:-users}"
    local shell="${FIELDS[4]:-/bin/bash}"
    local expire_date="${FIELDS[5]:-}"
    
    # Validar campos requeridos
    if [ -z "$username" ] || [ -z "$full_name" ]; then
        log "WARN: Línea $line_number - Campos requeridos faltantes (username, full_name)"
        ((USERS_SKIPPED++))
        return 1
    fi
    
    # Limpiar espacios en blanco
    username=$(echo "$username" | xargs)
    full_name=$(echo "$full_name" | xargs)
    email=$(echo "$email" | xargs)
    groups=$(echo "$groups" | xargs)
    shell=$(echo "$shell" | xargs)
    expire_date=$(echo "$expire_date" | xargs)
    
    log "Procesando usuario: $username ($full_name)"
    
    # Verificar si el usuario ya existe
    if id "$username" &>/dev/null; then
        log "WARN: El usuario $username ya existe - omitiendo"
        ((USERS_SKIPPED++))
        return 1
    fi
    
    # Crear el usuario
    if create_batch_user "$username" "$full_name" "$email" "$groups" "$shell" "$expire_date"; then
        ((USERS_CREATED++))
        return 0
    else
        ((USERS_FAILED++))
        return 1
    fi
}

# Crear usuario en lote
create_batch_user() {
    local username="$1"
    local full_name="$2"
    local email="$3"
    local groups="$4"
    local shell="$5"
    local expire_date="$6"
    
    log "Creando usuario: $username"
    
    # Generar contraseña
    local password
    password=$(generate_password)
    
    # Construir comando useradd
    local useradd_cmd="useradd -m -s '$shell' -c '$full_name'"
    
    if [ -n "$expire_date" ]; then
        useradd_cmd+=" -e '$expire_date'"
    fi
    
    useradd_cmd+=" '$username'"
    
    # Ejecutar creación
    if eval "$useradd_cmd"; then
        log "✓ Usuario $username creado"
    else
        log "✗ Error al crear usuario $username"
        return 1
    fi
    
    # Establecer contraseña
    echo "$username:$password" | chpasswd
    
    # Forzar cambio de contraseña en el primer login
    chage -d 0 "$username"
    
    # Agregar a grupos adicionales
    if [ "$groups" != "users" ] && [ -n "$groups" ]; then
        if usermod -a -G "$groups" "$username"; then
            log "✓ $username agregado a grupos: $groups"
        else
            log "WARN: Error al agregar $username a grupos: $groups"
        fi
    fi
    
    # Configurar estructura básica del directorio home
    setup_user_directory "$username"
    
    # Almacenar información para el reporte
    CREATED_USERS+=("$username:$full_name:$email:$password:$groups")
    
    return 0
}

# Configurar directorio del usuario
setup_user_directory() {
    local username="$1"
    local home_dir="/home/$username"
    
    # Crear directorios básicos
    su - "$username" -c "mkdir -p ~/Documents ~/Downloads ~/bin" 2>/dev/null || true
    
    # Configurar .bashrc básico
    if [ ! -f "$home_dir/.bashrc" ]; then
        cat >> "$home_dir/.bashrc" << 'EOF'
# Aliases útiles
alias ll='ls -la'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias grep='grep --color=auto'

# Configuración de PATH
export PATH="$HOME/bin:$PATH"
EOF
    fi
    
    # Ajustar permisos
    chown -R "$username:$username" "$home_dir"
    chmod 755 "$home_dir"
}

# Generar reporte final
generate_final_report() {
    log "Generando reporte final..."
    
    cat > "$REPORT_FILE" << EOF
=== REPORTE DE CREACIÓN DE USUARIOS EN LOTE ===
Fecha: $(date)
Archivo CSV: $CSV_FILE
Log: $LOG_FILE
Ejecutado por: $(whoami)

=== RESUMEN ===
Usuarios creados: $USERS_CREATED
Usuarios fallidos: $USERS_FAILED
Usuarios omitidos: $USERS_SKIPPED
Total procesado: $((USERS_CREATED + USERS_FAILED + USERS_SKIPPED))

=== USUARIOS CREADOS ===
EOF
    
    if [ ${#CREATED_USERS[@]} -gt 0 ]; then
        echo "Usuario         Nombre Completo           Email                     Contraseña   Grupos" >> "$REPORT_FILE"
        echo "=============== ========================= ========================= ============ ===============" >> "$REPORT_FILE"
        
        for user_info in "${CREATED_USERS[@]}"; do
            IFS=':' read -ra INFO <<< "$user_info"
            printf "%-15s %-25s %-25s %-12s %s\n" \
                "${INFO[0]}" "${INFO[1]}" "${INFO[2]}" "${INFO[3]}" "${INFO[4]}" >> "$REPORT_FILE"
        done
    else
        echo "Ningún usuario fue creado." >> "$REPORT_FILE"
    fi
    
    cat >> "$REPORT_FILE" << EOF

=== INSTRUCCIONES PARA LOS USUARIOS ===
1. La contraseña mostrada arriba es temporal
2. Deben cambiarla en el primer login
3. El directorio home está en /home/[username]
4. Se han configurado aliases básicos en .bashrc

=== COMANDOS DE VERIFICACIÓN ===
# Verificar usuarios creados:
cut -d: -f1 /etc/passwd | tail -$USERS_CREATED

# Verificar último login:
lastlog

# Información detallada de usuario:
id [username]
EOF
    
    log "✓ Reporte generado: $REPORT_FILE"
    
    # Mostrar resumen en pantalla
    echo ""
    echo "=== RESUMEN FINAL ==="
    echo "Usuarios creados: $USERS_CREATED"
    echo "Usuarios fallidos: $USERS_FAILED"
    echo "Usuarios omitidos: $USERS_SKIPPED"
    echo ""
    echo "Log completo: $LOG_FILE"
    echo "Reporte detallado: $REPORT_FILE"
    
    # Mostrar contraseñas de forma segura si es necesario
    if [ $USERS_CREATED -gt 0 ]; then
        echo ""
        echo "IMPORTANTE: Las contraseñas temporales están en el reporte."
        echo "Asegúrese de entregar esta información de forma segura a cada usuario."
    fi
}

# Función de ayuda
show_help() {
    cat << EOF
Creador de Usuarios en Lote v1.0

USO:
    $0 archivo.csv

FORMATO DEL CSV:
    username,full_name,email,groups,shell,expire_date
    
    - username: Nombre de usuario (requerido)
    - full_name: Nombre completo (requerido)
    - email: Correo electrónico (opcional)
    - groups: Grupos adicionales separados por : (default: users)
    - shell: Shell del usuario (default: /bin/bash)
    - expire_date: Fecha de expiración YYYY-MM-DD (opcional)

EJEMPLO DE CSV:
    juan,Juan Pérez,[email protected],developers:users,/bin/bash,2024-12-31
    maria,Maria García,[email protected],admin:users,/bin/bash,
    pedro,Pedro López,,users,/bin/zsh,2024-06-30

NOTAS:
    - Las líneas que empiecen con # serán ignoradas
    - Las líneas vacías serán ignoradas
    - Se generan contraseñas automáticamente
    - Los usuarios deben cambiar la contraseña en el primer login

ARCHIVOS GENERADOS:
    - Log: /var/log/batch_users_FECHA.log
    - Reporte: /tmp/batch_users_report_FECHA.txt
EOF
}

# Función principal
main() {
    check_root
    
    if [ $# -eq 0 ]; then
        show_help
        exit 1
    fi
    
    if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
        show_help
        exit 0
    fi
    
    CSV_FILE="$1"
    validate_csv "$CSV_FILE"
    
    log "=== INICIO DE PROCESAMIENTO EN LOTE ==="
    log "Archivo CSV: $CSV_FILE"
    log "Log: $LOG_FILE"
    
    # Procesar cada línea del CSV
    local line_number=0
    while IFS= read -r line || [ -n "$line" ]; do
        ((line_number++))
        process_user_line "$line" "$line_number"
    done < "$CSV_FILE"
    
    log "=== PROCESAMIENTO COMPLETADO ==="
    
    # Generar reporte final
    generate_final_report
}

# Ejecutar función principal
main "$@"

Ejemplo de archivo CSV

# Usuarios del departamento de desarrollo
developer1,Juan Pérez,[email protected],developers:users,/bin/bash,2024-12-31
developer2,María García,[email protected],developers:users,/bin/bash,
tester1,Pedro López,[email protected],testers:users,/bin/bash,2024-06-30
# Admin del sistema
admin1,Ana Administradora,[email protected],admin:users,/bin/bash,

Mejores Prácticas

  • Backups automáticos: Siempre crea respaldos antes de modificar usuarios
  • Logging detallado: Registra todas las operaciones para auditoría
  • Validación estricta: Verifica nombres de usuario y parámetros
  • Contraseñas seguras: Genera contraseñas fuertes automáticamente
  • Estructura consistente: Mantén una estructura estándar de directorios home
  • Grupos organizados: Usa grupos para simplificar la gestión de permisos

Consideraciones de Seguridad

  • Privilegios mínimos: Asigna solo los grupos necesarios a cada usuario
  • Contraseñas temporales: Fuerza cambio de contraseña en el primer login
  • Auditoría: Mantén logs detallados de todas las operaciones
  • Expiración: Configura fechas de expiración apropiadas para cuentas temporales
  • Backup seguro: Protege los archivos de backup que contienen contraseñas

Ejercicios Prácticos

Ejercicio 1: Sistema de Incorporación

Crea un sistema completo para incorporar nuevos empleados:

  • Script que cree usuario con estructura de directorios personalizada
  • Configuración automática de perfiles y aliases
  • Envío de credenciales por email (simulado)
  • Generación de documentación de bienvenida

Ejercicio 2: Gestión de Usuarios Departamentales

Desarrolla scripts para gestión por departamentos:

  • Creación masiva de usuarios por departamento
  • Configuración de grupos y permisos específicos
  • Sistema de rotación de contraseñas departamentales
  • Reportes de actividad y uso de recursos