Tutorial

New updates and improvements to Macfleet.

User Creation Management on macOS

Efficiently create and provision user accounts across your MacFleet deployment with enterprise-grade user lifecycle management, automated workflows, and comprehensive security controls. This tutorial transforms basic dscl and sysadminctl commands into robust user provisioning solutions.

Understanding Enterprise User Creation Management

Enterprise user creation requires more than basic account provisioning, demanding:

  • Automated user provisioning workflows with template-based configuration
  • Security-first account creation with proper privilege assignment
  • Standardized user onboarding with consistent directory structures
  • Integration capabilities with enterprise identity systems
  • Audit logging for compliance and security monitoring
  • Bulk user operations for efficient fleet management

Core User Creation Operations

Basic User Creation Commands

# dscl-based user creation
sudo dscl . -create /Users/Username
sudo dscl . -create /Users/Username RealName "John Doe"
sudo dscl . -passwd /Users/Username password_here
sudo dscl . -create /Users/Username UniqueID 1088
sudo dscl . -create /Users/Username PrimaryGroupID 20
sudo dscl . -create /Users/Username UserShell /bin/bash
sudo dscl . -create /Users/Username NFSHomeDirectory /Users/Username

# sysadminctl-based user creation
sysadminctl -addUser <username> -password <password>

These utilize the directory service command-line utility (dscl) and system administrator control (sysadminctl) for user account management.

Enterprise User Creation Management System

#!/bin/bash

# MacFleet Enterprise User Creation Management System
# Comprehensive user provisioning with enterprise controls and automation

# Configuration
SCRIPT_NAME="MacFleet User Creation Manager"
VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_user_creation.log"
AUDIT_LOG="/var/log/macfleet_user_audit.log"
TEMPLATES_DIR="/etc/macfleet/user_templates"
PROVISIONING_DIR="/var/lib/macfleet/provisioning"
TEMP_DIR="/tmp/macfleet_users"
MIN_UID=1000
MAX_UID=65000
DEFAULT_SHELL="/bin/zsh"
HOME_BASE_DIR="/Users"
COMPANY_DOMAIN="company.local"
REQUIRE_SECURE_PASSWORDS=true
ENFORCE_NAMING_CONVENTION=true
AUTO_FILEVAULT_ENABLE=true
STANDARD_GROUPS=("staff" "_appserverusr" "_appserveradm")
ADMIN_GROUPS=("admin" "staff" "_developer")
DEVELOPER_GROUPS=("staff" "_developer" "_appserverusr")

# Create necessary directories
mkdir -p "$TEMPLATES_DIR"
mkdir -p "$PROVISIONING_DIR"
mkdir -p "$TEMP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$AUDIT_LOG")"

# Set secure permissions
chmod 700 "$TEMP_DIR"
chmod 750 "$PROVISIONING_DIR"
chmod 755 "$TEMPLATES_DIR"

# Logging functions
log_operation() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local admin_user=$(whoami)
    echo "[$timestamp] [$level] [$admin_user] $message" | tee -a "$LOG_FILE"
}

log_audit_action() {
    local action_type="$1"
    local target_user="$2"
    local performed_by="$3"
    local details="$4"
    
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local source_ip=$(who am i | awk '{print $5}' | tr -d '()')
    echo "ACTION|$timestamp|$action_type|$target_user|$performed_by|$source_ip|$details" >> "$AUDIT_LOG"
}

# Generate secure random password
generate_secure_password() {
    local length="${1:-12}"
    local complexity="${2:-high}"
    
    case "$complexity" in
        "high")
            # High complexity: uppercase, lowercase, numbers, symbols
            openssl rand -base64 32 | tr -d "=+/" | cut -c1-${length}
            ;;
        "medium")
            # Medium complexity: uppercase, lowercase, numbers
            LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c ${length}
            ;;
        "basic")
            # Basic complexity: lowercase and numbers
            LC_ALL=C tr -dc 'a-z0-9' </dev/urandom | head -c ${length}
            ;;
        *)
            echo "Error: Unknown complexity level"
            return 1
            ;;
    esac
}

# Validate password policy
validate_password() {
    local password="$1"
    local min_length=8
    local errors=()
    
    # Check minimum length
    if [[ ${#password} -lt $min_length ]]; then
        errors+=("Password must be at least $min_length characters")
    fi
    
    # Check for uppercase letter
    if [[ ! "$password" =~ [A-Z] ]]; then
        errors+=("Password must contain at least one uppercase letter")
    fi
    
    # Check for lowercase letter
    if [[ ! "$password" =~ [a-z] ]]; then
        errors+=("Password must contain at least one lowercase letter")
    fi
    
    # Check for number
    if [[ ! "$password" =~ [0-9] ]]; then
        errors+=("Password must contain at least one number")
    fi
    
    # Check for special character
    if [[ ! "$password" =~ [^A-Za-z0-9] ]]; then
        errors+=("Password must contain at least one special character")
    fi
    
    if [[ ${#errors[@]} -gt 0 ]]; then
        echo "Password validation failed:"
        printf '  - %s\n' "${errors[@]}"
        return 1
    fi
    
    return 0
}

# Validate username according to enterprise naming convention
validate_username() {
    local username="$1"
    local errors=()
    
    # Check length (3-20 characters)
    if [[ ${#username} -lt 3 || ${#username} -gt 20 ]]; then
        errors+=("Username must be 3-20 characters long")
    fi
    
    # Check for valid characters (alphanumeric, dots, hyphens, underscores)
    if [[ ! "$username" =~ ^[a-zA-Z0-9._-]+$ ]]; then
        errors+=("Username can only contain letters, numbers, dots, hyphens, and underscores")
    fi
    
    # Check that it starts with a letter
    if [[ ! "$username" =~ ^[a-zA-Z] ]]; then
        errors+=("Username must start with a letter")
    fi
    
    # Check for reserved usernames
    local reserved_names=("admin" "root" "daemon" "nobody" "wheel" "operator" "system")
    for reserved in "${reserved_names[@]}"; do
        if [[ "$username" == "$reserved" ]]; then
            errors+=("Username '$username' is reserved")
        fi
    done
    
    # Check if username already exists
    if dscl . -read "/Users/$username" &>/dev/null; then
        errors+=("Username '$username' already exists")
    fi
    
    if [[ ${#errors[@]} -gt 0 ]]; then
        echo "Username validation failed:"
        printf '  - %s\n' "${errors[@]}"
        return 1
    fi
    
    return 0
}

# Find next available UID
find_next_uid() {
    local start_uid="${1:-$MIN_UID}"
    local max_uid="${2:-$MAX_UID}"
    
    # Get all existing UIDs
    local existing_uids=($(dscl . list /Users UniqueID | awk '{print $2}' | sort -n))
    
    # Find first available UID
    for ((uid=start_uid; uid<=max_uid; uid++)); do
        local uid_exists=false
        for existing_uid in "${existing_uids[@]}"; do
            if [[ $uid -eq $existing_uid ]]; then
                uid_exists=true
                break
            fi
        done
        
        if [[ "$uid_exists" == "false" ]]; then
            echo "$uid"
            return 0
        fi
    done
    
    echo "Error: No available UID found in range $start_uid-$max_uid"
    return 1
}

# Create user account with enterprise settings
create_enterprise_user() {
    local username="$1"
    local real_name="$2"
    local password="$3"
    local user_type="${4:-standard}"
    local department="${5:-General}"
    local admin_user=$(whoami)
    
    log_audit_action "USER_CREATION_START" "$username" "$admin_user" "type=$user_type,department=$department"
    
    # Validate inputs
    if ! validate_username "$username"; then
        log_operation "ERROR" "Username validation failed for: $username"
        return 1
    fi
    
    if [[ "$REQUIRE_SECURE_PASSWORDS" == "true" ]] && ! validate_password "$password"; then
        log_operation "ERROR" "Password validation failed for user: $username"
        return 1
    fi
    
    # Find available UID
    local uid
    uid=$(find_next_uid)
    if [[ $? -ne 0 ]]; then
        log_operation "ERROR" "Failed to find available UID for: $username"
        return 1
    fi
    
    echo "=== Creating Enterprise User: $username ==="
    echo "Real Name: $real_name"
    echo "User Type: $user_type"
    echo "Department: $department"
    echo "Assigned UID: $uid"
    echo "Administrator: $admin_user"
    echo ""
    
    # Create user account using dscl
    echo "Creating user account..."
    
    # Basic user creation
    if ! sudo dscl . -create "/Users/$username"; then
        log_operation "ERROR" "Failed to create user: $username"
        return 1
    fi
    
    # Set real name
    sudo dscl . -create "/Users/$username" RealName "$real_name"
    
    # Set password
    sudo dscl . -passwd "/Users/$username" "$password"
    
    # Set UID
    sudo dscl . -create "/Users/$username" UniqueID "$uid"
    
    # Determine primary group ID based on user type
    local primary_gid
    case "$user_type" in
        "admin")
            primary_gid=80  # admin group
            ;;
        "developer")
            primary_gid=20  # staff group
            ;;
        "standard"|*)
            primary_gid=20  # staff group
            ;;
    esac
    
    sudo dscl . -create "/Users/$username" PrimaryGroupID "$primary_gid"
    
    # Set shell
    sudo dscl . -create "/Users/$username" UserShell "$DEFAULT_SHELL"
    
    # Create home directory
    local home_dir="$HOME_BASE_DIR/$username"
    sudo dscl . -create "/Users/$username" NFSHomeDirectory "$home_dir"
    
    # Add enterprise attributes
    sudo dscl . -create "/Users/$username" Department "$department"
    sudo dscl . -create "/Users/$username" Company "$(hostname -s | cut -d. -f1)"
    sudo dscl . -create "/Users/$username" CreationDate "$(date)"
    sudo dscl . -create "/Users/$username" CreatedBy "$admin_user"
    
    # Add password hint
    sudo dscl . -create "/Users/$username" hint "Contact IT support for password assistance"
    
    # Set up group memberships based on user type
    echo "Configuring group memberships..."
    case "$user_type" in
        "admin")
            for group in "${ADMIN_GROUPS[@]}"; do
                sudo dseditgroup -o edit -a "$username" -t user "$group" 2>/dev/null
            done
            ;;
        "developer")
            for group in "${DEVELOPER_GROUPS[@]}"; do
                sudo dseditgroup -o edit -a "$username" -t user "$group" 2>/dev/null
            done
            ;;
        "standard"|*)
            for group in "${STANDARD_GROUPS[@]}"; do
                sudo dseditgroup -o edit -a "$username" -t user "$group" 2>/dev/null
            done
            ;;
    esac
    
    # Create and configure home directory
    echo "Setting up home directory..."
    if [[ ! -d "$home_dir" ]]; then
        sudo mkdir -p "$home_dir"
        sudo chown "$username:staff" "$home_dir"
        sudo chmod 755 "$home_dir"
    fi
    
    # Copy user template if available
    local template_dir="$TEMPLATES_DIR/$user_type"
    if [[ -d "$template_dir" ]]; then
        echo "Applying user template: $user_type"
        sudo cp -R "$template_dir/"* "$home_dir/" 2>/dev/null
        sudo chown -R "$username:staff" "$home_dir"
    fi
    
    # Enable FileVault for new user if required
    if [[ "$AUTO_FILEVAULT_ENABLE" == "true" ]]; then
        echo "Enabling FileVault access for user..."
        sudo fdesetup add -usertoadd "$username" 2>/dev/null || true
    fi
    
    # Generate user profile report
    local profile_file="$PROVISIONING_DIR/${username}_profile.txt"
    {
        echo "MacFleet User Profile"
        echo "===================="
        echo "Username: $username"
        echo "Real Name: $real_name"
        echo "UID: $uid"
        echo "GID: $primary_gid"
        echo "User Type: $user_type"
        echo "Department: $department"
        echo "Home Directory: $home_dir"
        echo "Shell: $DEFAULT_SHELL"
        echo "Created: $(date)"
        echo "Created By: $admin_user"
        echo "Groups: $(groups "$username" 2>/dev/null | cut -d: -f2)"
        echo ""
        echo "Security Settings:"
        echo "- FileVault Enabled: $AUTO_FILEVAULT_ENABLE"
        echo "- Secure Password: $REQUIRE_SECURE_PASSWORDS"
        echo "- Naming Convention: $ENFORCE_NAMING_CONVENTION"
    } > "$profile_file"
    
    echo "✅ User creation completed successfully"
    echo "Profile saved: $profile_file"
    
    log_operation "INFO" "User created successfully: $username (UID: $uid, Type: $user_type)"
    log_audit_action "USER_CREATION_SUCCESS" "$username" "$admin_user" "uid=$uid,type=$user_type,groups=$(groups "$username" 2>/dev/null | cut -d: -f2)"
    
    return 0
}

# Bulk user creation from CSV file
bulk_create_users() {
    local csv_file="$1"
    local admin_user=$(whoami)
    
    if [[ ! -f "$csv_file" ]]; then
        echo "Error: CSV file not found: $csv_file"
        return 1
    fi
    
    log_audit_action "BULK_CREATION_START" "multiple" "$admin_user" "source=$csv_file"
    
    echo "=== Bulk User Creation ==="
    echo "CSV File: $csv_file"
    echo "Administrator: $admin_user"
    echo ""
    
    local line_count=0
    local success_count=0
    local error_count=0
    local results_file="$PROVISIONING_DIR/bulk_creation_$(date +%Y%m%d_%H%M%S).log"
    
    # Read CSV file (format: username,real_name,user_type,department)
    while IFS=',' read -r username real_name user_type department; do
        line_count=$((line_count + 1))
        
        # Skip header line
        if [[ $line_count -eq 1 && "$username" == "username" ]]; then
            continue
        fi
        
        # Skip empty lines
        if [[ -z "$username" ]]; then
            continue
        fi
        
        # Generate secure password
        local password
        password=$(generate_secure_password 12 "high")
        
        echo "Processing user $line_count: $username"
        
        # Create user
        if create_enterprise_user "$username" "$real_name" "$password" "$user_type" "$department"; then
            success_count=$((success_count + 1))
            echo "SUCCESS: $username,$real_name,$password,$user_type,$department" >> "$results_file"
        else
            error_count=$((error_count + 1))
            echo "ERROR: $username,$real_name,FAILED,$user_type,$department" >> "$results_file"
        fi
        
        echo ""
    done < "$csv_file"
    
    echo "=== Bulk Creation Summary ==="
    echo "Total Processed: $line_count"
    echo "Successful: $success_count"
    echo "Errors: $error_count"
    echo "Results File: $results_file"
    
    log_operation "INFO" "Bulk user creation completed: $success_count successful, $error_count errors"
    log_audit_action "BULK_CREATION_COMPLETE" "multiple" "$admin_user" "total=$line_count,success=$success_count,errors=$error_count"
}

# Create user templates
create_user_template() {
    local template_type="$1"
    local template_dir="$TEMPLATES_DIR/$template_type"
    
    echo "Creating user template: $template_type"
    
    mkdir -p "$template_dir"
    
    case "$template_type" in
        "standard")
            # Standard user template
            mkdir -p "$template_dir/Desktop"
            mkdir -p "$template_dir/Documents"
            mkdir -p "$template_dir/Downloads"
            
            # Create welcome document
            cat > "$template_dir/Desktop/Welcome.txt" << EOF
Welcome to MacFleet!

Your account has been set up with standard user privileges.
For support, please contact IT at support@company.com

Account Type: Standard User
Creation Date: $(date)
EOF
            ;;
        "admin")
            # Admin user template
            mkdir -p "$template_dir/Desktop"
            mkdir -p "$template_dir/Documents/AdminTools"
            mkdir -p "$template_dir/Downloads"
            
            cat > "$template_dir/Desktop/Admin_Welcome.txt" << EOF
Welcome to MacFleet - Administrator Account

Your account has been configured with administrative privileges.
Please use these privileges responsibly.

Account Type: Administrator
Creation Date: $(date)

Important:
- Follow company security policies
- Regular password changes required
- All administrative actions are logged
EOF
            ;;
        "developer")
            # Developer user template
            mkdir -p "$template_dir/Desktop"
            mkdir -p "$template_dir/Documents/Projects"
            mkdir -p "$template_dir/Downloads"
            mkdir -p "$template_dir/Development"
            
            cat > "$template_dir/Desktop/Developer_Setup.txt" << EOF
Developer Account Setup

Your account includes development tools access.

Account Type: Developer
Creation Date: $(date)

Next Steps:
1. Install Xcode from App Store
2. Configure Git credentials
3. Set up development environment
4. Review coding standards documentation
EOF
            ;;
    esac
    
    # Set template permissions
    chmod -R 755 "$template_dir"
    
    echo "Template created: $template_dir"
    log_operation "INFO" "User template created: $template_type"
}

# Generate provisioning report
generate_provisioning_report() {
    local report_type="${1:-summary}"
    local admin_user=$(whoami)
    local report_file="$PROVISIONING_DIR/provisioning_report_$(date +%Y%m%d_%H%M%S).txt"
    
    log_audit_action "PROVISIONING_REPORT" "system" "$admin_user" "type=$report_type"
    
    {
        echo "MacFleet User Provisioning Report"
        echo "================================="
        echo "Report Type: $report_type"
        echo "Generated: $(date)"
        echo "Generated By: $admin_user"
        echo "Hostname: $(hostname)"
        echo ""
        
        case "$report_type" in
            "summary")
                echo "== Provisioning Summary =="
                local total_users=$(dscl . list /Users | grep -v '^_' | wc -l)
                local recent_users=$(find "$PROVISIONING_DIR" -name "*_profile.txt" -mtime -7 | wc -l)
                
                echo "Total Users: $total_users"
                echo "Users Created (Last 7 days): $recent_users"
                echo ""
                
                echo "User Type Distribution:"
                echo "Standard Users: $(dscl . list /Users | xargs -I {} dscl . read /Users/{} PrimaryGroupID 2>/dev/null | grep -c '20')"
                echo "Admin Users: $(dscl . list /Users | xargs -I {} dscl . read /Users/{} PrimaryGroupID 2>/dev/null | grep -c '80')"
                ;;
            "recent")
                echo "== Recent User Creations =="
                echo "Users created in last 30 days:"
                find "$PROVISIONING_DIR" -name "*_profile.txt" -mtime -30 -exec basename {} \; | sed 's/_profile.txt//'
                ;;
            "audit")
                echo "== Audit Information =="
                if [[ -f "$AUDIT_LOG" ]]; then
                    echo "Recent provisioning activities:"
                    grep "USER_CREATION" "$AUDIT_LOG" | tail -10
                else
                    echo "No audit log available"
                fi
                ;;
        esac
        
        echo ""
        echo "== Configuration =="
        echo "Min UID: $MIN_UID"
        echo "Max UID: $MAX_UID"
        echo "Default Shell: $DEFAULT_SHELL"
        echo "Auto FileVault: $AUTO_FILEVAULT_ENABLE"
        echo "Secure Passwords: $REQUIRE_SECURE_PASSWORDS"
        echo "Naming Convention: $ENFORCE_NAMING_CONVENTION"
        
    } > "$report_file"
    
    echo "Provisioning report generated: $report_file"
    log_operation "INFO" "Provisioning report generated: $report_file"
}

# Main user creation management function
main() {
    local action="${1:-help}"
    
    case "$action" in
        "create")
            local username="$2"
            local real_name="$3"
            local password="$4"
            local user_type="${5:-standard}"
            local department="${6:-General}"
            
            if [[ -z "$username" || -z "$real_name" ]]; then
                echo "Usage: $0 create <username> <real_name> [password] [user_type] [department]"
                echo "User types: standard, admin, developer"
                exit 1
            fi
            
            # Generate password if not provided
            if [[ -z "$password" ]]; then
                password=$(generate_secure_password 12 "high")
                echo "Generated secure password: $password"
            fi
            
            create_enterprise_user "$username" "$real_name" "$password" "$user_type" "$department"
            ;;
        "bulk")
            local csv_file="$2"
            
            if [[ -z "$csv_file" ]]; then
                echo "Usage: $0 bulk <csv_file>"
                echo "CSV format: username,real_name,user_type,department"
                exit 1
            fi
            
            bulk_create_users "$csv_file"
            ;;
        "template")
            local template_type="$2"
            
            if [[ -z "$template_type" ]]; then
                echo "Usage: $0 template <template_type>"
                echo "Template types: standard, admin, developer"
                exit 1
            fi
            
            create_user_template "$template_type"
            ;;
        "report")
            local report_type="${2:-summary}"
            
            generate_provisioning_report "$report_type"
            ;;
        "password")
            local length="${2:-12}"
            local complexity="${3:-high}"
            
            echo "Generated password: $(generate_secure_password "$length" "$complexity")"
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Enterprise User Creation Management"
            echo ""
            echo "Usage: $0 <action> [options]"
            echo ""
            echo "Actions:"
            echo "  create <username> <real_name> [password] [type] [dept]  - Create single user"
            echo "  bulk <csv_file>                                         - Create users from CSV"
            echo "  template <type>                                         - Create user template"
            echo "  report [type]                                           - Generate provisioning reports"
            echo "  password [length] [complexity]                         - Generate secure password"
            echo "  help                                                    - Show this help message"
            echo ""
            echo "User Types:"
            echo "  standard    - Standard user with basic privileges"
            echo "  admin       - Administrative user with elevated privileges"
            echo "  developer   - Developer user with development tools access"
            echo ""
            echo "Report Types:"
            echo "  summary     - Overview of user provisioning (default)"
            echo "  recent      - Recently created users"
            echo "  audit       - Audit trail information"
            echo ""
            echo "Password Complexity:"
            echo "  basic       - Lowercase and numbers only"
            echo "  medium      - Letters and numbers"
            echo "  high        - Letters, numbers, and symbols (default)"
            echo ""
            echo "Features:"
            echo "  • Automated user provisioning with enterprise templates"
            echo "  • Security-first account creation with validation"
            echo "  • Bulk user creation from CSV files"
            echo "  • Comprehensive audit logging and compliance"
            echo "  • Integration with FileVault and enterprise security"
            echo "  • Template-based user onboarding"
            echo "  • Automated password generation and validation"
            ;;
    esac
}

# Execute main function with all arguments
main "$@"

Quick Reference Commands

Single User Creation

# Create standard user
./user_creator.sh create john.doe "John Doe"

# Create admin user with custom password
./user_creator.sh create admin.user "Admin User" "SecurePass123!" admin IT

# Create developer user
./user_creator.sh create dev.user "Developer User" "" developer Engineering

# Create user with all parameters
./user_creator.sh create jane.smith "Jane Smith" "CustomPass456!" standard Marketing

Bulk User Operations

# Create users from CSV file
./user_creator.sh bulk users.csv

# CSV format example:
# username,real_name,user_type,department
# john.doe,John Doe,standard,Sales
# jane.admin,Jane Admin,admin,IT
# dev.user,Dev User,developer,Engineering

Template Management

# Create standard user template
./user_creator.sh template standard

# Create admin user template
./user_creator.sh template admin

# Create developer user template
./user_creator.sh template developer

Password Generation

# Generate high-complexity password (default)
./user_creator.sh password

# Generate 16-character password
./user_creator.sh password 16

# Generate medium-complexity password
./user_creator.sh password 12 medium

# Generate basic password
./user_creator.sh password 10 basic

Reporting Operations

# Generate summary report
./user_creator.sh report

# Generate recent users report
./user_creator.sh report recent

# Generate audit report
./user_creator.sh report audit

Advanced User Creation Scenarios

Automated Onboarding Workflow

#!/bin/bash

# Automated new employee onboarding
onboard_employee() {
    local employee_data="$1"  # JSON file with employee details
    
    # Parse employee data
    local username=$(jq -r '.username' "$employee_data")
    local real_name=$(jq -r '.real_name' "$employee_data")
    local department=$(jq -r '.department' "$employee_data")
    local role=$(jq -r '.role' "$employee_data")
    local manager=$(jq -r '.manager' "$employee_data")
    
    # Determine user type based on role
    local user_type="standard"
    case "$role" in
        "Admin"|"IT Manager"|"System Administrator")
            user_type="admin"
            ;;
        "Developer"|"Software Engineer"|"DevOps")
            user_type="developer"
            ;;
    esac
    
    # Create user account
    ./user_creator.sh create "$username" "$real_name" "" "$user_type" "$department"
    
    # Send welcome email with credentials
    send_welcome_email "$username" "$real_name" "$manager"
    
    # Schedule follow-up tasks
    schedule_onboarding_tasks "$username" "$department"
}

Integration with Enterprise Systems

# JAMF Pro integration for user creation
#!/bin/bash

# JAMF Pro script parameters
USERNAME="$4"
REAL_NAME="$5"
USER_TYPE="$6"
DEPARTMENT="$7"

# Download user creator if not present
if [[ ! -f "/usr/local/bin/macfleet_user_creator.sh" ]]; then
    curl -o "/usr/local/bin/macfleet_user_creator.sh" \
         "https://scripts.macfleet.com/user_creator.sh"
    chmod +x "/usr/local/bin/macfleet_user_creator.sh"
fi

# Create user with enterprise settings
/usr/local/bin/macfleet_user_creator.sh create \
    "$USERNAME" "$REAL_NAME" "" "$USER_TYPE" "$DEPARTMENT"

# Report status back to JAMF
if [[ $? -eq 0 ]]; then
    echo "User $USERNAME created successfully"
    exit 0
else
    echo "Failed to create user $USERNAME"
    exit 1
fi

Active Directory Synchronization

#!/bin/bash

# Sync new users with Active Directory
sync_with_active_directory() {
    local username="$1"
    local ad_domain="company.local"
    
    # Wait for user account to be fully created
    sleep 5
    
    # Create AD bind if not exists
    if ! dsconfigad -show | grep -q "Active Directory Domain"; then
        echo "Binding to Active Directory domain: $ad_domain"
        dsconfigad -add "$ad_domain" -username "ad_admin" -password "ad_password"
    fi
    
    # Create mobile account for AD integration
    dscl /Active\ Directory/COMPANY/All\ Domains -create /Users/"$username"
    
    echo "User $username synchronized with Active Directory"
}

Security and Compliance Features

Password Policy Enforcement

# Advanced password policy validation
enforce_enterprise_password_policy() {
    local password="$1"
    local username="$2"
    
    # Check against common passwords
    local common_passwords=("password" "123456" "admin" "welcome")
    for common in "${common_passwords[@]}"; do
        if [[ "${password,,}" == "${common,,}" ]]; then
            echo "Error: Password is too common"
            return 1
        fi
    done
    
    # Check for username in password
    if [[ "${password,,}" =~ ${username,,} ]]; then
        echo "Error: Password cannot contain username"
        return 1
    fi
    
    # Check password history (if implemented)
    check_password_history "$username" "$password"
}

Audit and Compliance Reporting

# Generate compliance report for user creation
generate_compliance_report() {
    local start_date="$1"
    local end_date="$2"
    local report_file="/var/reports/user_creation_compliance_$(date +%Y%m%d).json"
    
    {
        echo "{"
        echo "  \"report_type\": \"user_creation_compliance\","
        echo "  \"period\": \"$start_date to $end_date\","
        echo "  \"generated\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
        echo "  \"total_users_created\": $(grep "USER_CREATION_SUCCESS" "$AUDIT_LOG" | wc -l),"
        echo "  \"policy_violations\": $(grep "POLICY_VIOLATION" "$AUDIT_LOG" | wc -l),"
        echo "  \"security_reviews\": $(grep "SECURITY_REVIEW" "$AUDIT_LOG" | wc -l)"
        echo "}"
    } > "$report_file"
    
    echo "Compliance report generated: $report_file"
}

Best Practices

  1. Use strong password policies with complexity requirements
  2. Implement role-based user types for appropriate privilege assignment
  3. Enable comprehensive audit logging for all user creation activities
  4. Use templates for consistent user onboarding experiences
  5. Integrate with enterprise directory services for centralized management
  6. Automate FileVault enrollment for security compliance
  7. Generate regular compliance reports for audit purposes
  8. Validate usernames against enterprise naming conventions

This enterprise user creation management system provides comprehensive user provisioning capabilities with security controls, audit compliance, and automated workflows for effective MacFleet user lifecycle management.

User Account Management on macOS

Master user account creation and management on your MacFleet devices using powerful command-line tools. This tutorial covers admin and standard user creation, password management, account configuration, and advanced user lifecycle management for enterprise deployments.

Understanding macOS User Management

macOS provides several command-line tools for user account management:

  • sysadminctl - Modern user account management tool (macOS 10.10+)
  • dscl - Directory Services command-line utility for advanced operations
  • passwd - Password management and changes
  • id - User and group information display
  • whoami - Current user identification

Basic User Account Creation

Create Admin User Account

#!/bin/sh

# Set PATH environment variable
export PATH=/usr/bin:/bin:/usr/sbin:/sbin

# Admin user configuration
USERNAME="Daniel"
FULLNAME="Daniel.Hector"
PASSWORD="One@Two#8"
PASSWORDHINT="One to Eight"

# Create admin user account
sysadminctl -addUser "$USERNAME" -fullName "$FULLNAME" -password "$PASSWORD" -hint "$PASSWORDHINT" -admin

echo "Admin user account '$USERNAME' created successfully"

Create Standard User Account

#!/bin/sh

# Set PATH environment variable
export PATH=/usr/bin:/bin:/usr/sbin:/sbin

# Standard user configuration
USERNAME="Daniel"
FULLNAME="Daniel.Hector"
PASSWORD="One@Two#8"
PASSWORDHINT="One to Eight"

# Create standard user account (no -admin flag)
sysadminctl -addUser "$USERNAME" -fullName "$FULLNAME" -password "$PASSWORD" -hint "$PASSWORDHINT"

echo "Standard user account '$USERNAME' created successfully"

Enhanced User Creation with Validation

#!/bin/bash

# Enhanced user creation with validation
create_user_account() {
    local username="$1"
    local fullname="$2"
    local password="$3"
    local hint="$4"
    local is_admin="${5:-false}"
    
    # Validate inputs
    if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
        echo "Error: Username, full name, and password are required"
        return 1
    fi
    
    # Check if user already exists
    if id "$username" &>/dev/null; then
        echo "Error: User '$username' already exists"
        return 1
    fi
    
    # Set PATH environment
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    # Build sysadminctl command
    local cmd="sysadminctl -addUser \"$username\" -fullName \"$fullname\" -password \"$password\""
    
    if [[ -n "$hint" ]]; then
        cmd="$cmd -hint \"$hint\""
    fi
    
    if [[ "$is_admin" == "true" ]]; then
        cmd="$cmd -admin"
        echo "Creating admin user: $username"
    else
        echo "Creating standard user: $username"
    fi
    
    # Execute user creation
    if eval "$cmd"; then
        echo "✓ User '$username' created successfully"
        
        # Display user information
        echo "User details:"
        id "$username"
        return 0
    else
        echo "✗ Failed to create user '$username'"
        return 1
    fi
}

# Usage examples
create_user_account "daniel" "Daniel Hector" "SecurePass123!" "Password hint" "true"
create_user_account "jane" "Jane Smith" "UserPass456!" "Another hint" "false"

Advanced User Management

Batch User Creation

#!/bin/bash

# Batch user creation from configuration
batch_create_users() {
    local config_file="$1"
    
    if [[ ! -f "$config_file" ]]; then
        echo "Error: Configuration file not found: $config_file"
        return 1
    fi
    
    echo "=== Batch User Creation ==="
    
    local success_count=0
    local error_count=0
    
    # Read configuration file (format: username,fullname,password,hint,admin)
    while IFS=',' read -r username fullname password hint is_admin; do
        # Skip empty lines and comments
        [[ -z "$username" || "$username" =~ ^# ]] && continue
        
        echo "Processing user: $username"
        
        if create_user_account "$username" "$fullname" "$password" "$hint" "$is_admin"; then
            ((success_count++))
        else
            ((error_count++))
        fi
        
        echo "---"
    done < "$config_file"
    
    echo "Batch creation completed:"
    echo "✓ Success: $success_count users"
    echo "✗ Errors: $error_count users"
}

# Create sample configuration file
create_user_config() {
    local config_file="/tmp/users_config.csv"
    
    cat > "$config_file" << EOF
# Format: username,fullname,password,hint,admin(true/false)
daniel,Daniel Hector,SecurePass123!,Password hint,true
jane,Jane Smith,UserPass456!,Another hint,false
alex,Alex Johnson,TempPass789!,Temporary password,false
admin,System Administrator,AdminPass000!,Admin access,true
EOF
    
    echo "Sample configuration created: $config_file"
    echo "$config_file"
}

# Usage
config_file=$(create_user_config)
batch_create_users "$config_file"

User Account Modification

#!/bin/bash

# Modify existing user accounts
modify_user_account() {
    local username="$1"
    local action="$2"
    local value="$3"
    
    # Verify user exists
    if ! id "$username" &>/dev/null; then
        echo "Error: User '$username' does not exist"
        return 1
    fi
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    case "$action" in
        "password")
            echo "Changing password for user: $username"
            if sysadminctl -resetPasswordFor "$username" -newPassword "$value"; then
                echo "✓ Password changed successfully"
            else
                echo "✗ Failed to change password"
                return 1
            fi
            ;;
        "fullname")
            echo "Changing full name for user: $username"
            if dscl . -change "/Users/$username" RealName "$(dscl . -read "/Users/$username" RealName | cut -d: -f2 | xargs)" "$value"; then
                echo "✓ Full name changed to: $value"
            else
                echo "✗ Failed to change full name"
                return 1
            fi
            ;;
        "admin")
            if [[ "$value" == "true" ]]; then
                echo "Granting admin privileges to: $username"
                if dseditgroup -o edit -a "$username" -t user admin; then
                    echo "✓ Admin privileges granted"
                else
                    echo "✗ Failed to grant admin privileges"
                    return 1
                fi
            else
                echo "Removing admin privileges from: $username"
                if dseditgroup -o edit -d "$username" -t user admin; then
                    echo "✓ Admin privileges removed"
                else
                    echo "✗ Failed to remove admin privileges"
                    return 1
                fi
            fi
            ;;
        "enable")
            echo "Enabling user account: $username"
            if dscl . -create "/Users/$username" AuthenticationAuthority; then
                echo "✓ User account enabled"
            else
                echo "✗ Failed to enable user account"
                return 1
            fi
            ;;
        "disable")
            echo "Disabling user account: $username"
            if dscl . -delete "/Users/$username" AuthenticationAuthority; then
                echo "✓ User account disabled"
            else
                echo "✗ Failed to disable user account"
                return 1
            fi
            ;;
        *)
            echo "Error: Unknown action '$action'"
            echo "Available actions: password, fullname, admin, enable, disable"
            return 1
            ;;
    esac
}

# Usage examples
modify_user_account "daniel" "password" "NewSecurePass123!"
modify_user_account "jane" "admin" "true"
modify_user_account "alex" "fullname" "Alexander Johnson"

User Account Deletion

#!/bin/bash

# Delete user accounts with options
delete_user_account() {
    local username="$1"
    local delete_home="${2:-true}"
    local backup_home="${3:-false}"
    
    # Verify user exists
    if ! id "$username" &>/dev/null; then
        echo "Error: User '$username' does not exist"
        return 1
    fi
    
    # Prevent deletion of critical system users
    local system_users=("root" "daemon" "nobody" "_www" "_mysql" "_postgresql")
    for sys_user in "${system_users[@]}"; do
        if [[ "$username" == "$sys_user" ]]; then
            echo "Error: Cannot delete system user '$username'"
            return 1
        fi
    done
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    echo "Preparing to delete user: $username"
    
    # Backup home directory if requested
    if [[ "$backup_home" == "true" ]]; then
        local backup_dir="/var/backups/deleted_users"
        local timestamp=$(date +%Y%m%d_%H%M%S)
        local backup_path="$backup_dir/${username}_${timestamp}.tar.gz"
        
        mkdir -p "$backup_dir"
        
        echo "Backing up home directory to: $backup_path"
        if tar -czf "$backup_path" -C "/Users" "$username" 2>/dev/null; then
            echo "✓ Home directory backed up"
        else
            echo "⚠ Warning: Failed to backup home directory"
        fi
    fi
    
    # Delete user account
    local delete_cmd="sysadminctl -deleteUser \"$username\""
    
    if [[ "$delete_home" == "true" ]]; then
        delete_cmd="$delete_cmd -secure"
        echo "Deleting user and home directory..."
    else
        echo "Deleting user account only..."
    fi
    
    if eval "$delete_cmd"; then
        echo "✓ User '$username' deleted successfully"
        return 0
    else
        echo "✗ Failed to delete user '$username'"
        return 1
    fi
}

# Usage examples
delete_user_account "testuser" "true" "true"  # Delete with home, backup first
delete_user_account "tempuser" "false" "false"  # Delete user only, no backup

Enterprise User Management System

#!/bin/bash

# MacFleet User Management Tool
# Comprehensive user account management for fleet devices

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_users.log"
REPORT_DIR="/etc/macfleet/reports/users"
CONFIG_DIR="/etc/macfleet/users"
BACKUP_DIR="/var/backups/macfleet_users"

# Create directories if they don't exist
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$BACKUP_DIR"

# User account categories
declare -A USER_CATEGORIES=(
    ["administrator"]="admin,full_privileges,system_access"
    ["developer"]="standard,sudo_group,development_access"
    ["standard_user"]="standard,basic_privileges,user_access"
    ["service_account"]="standard,no_login,service_access"
    ["temporary_user"]="standard,limited_time,restricted_access"
    ["guest_user"]="standard,guest_privileges,temporary_access"
    ["kiosk_user"]="standard,kiosk_mode,restricted_access"
    ["backup_operator"]="standard,backup_privileges,system_access"
    ["monitoring_user"]="standard,read_only,monitoring_access"
    ["deployment_user"]="admin,deployment_privileges,automated_access"
)

# User management policies
declare -A USER_POLICIES=(
    ["password_strength"]="minimum_8_chars,mixed_case,numbers,special_chars"
    ["password_expiry"]="90_days,180_days,365_days,never"
    ["account_lockout"]="3_attempts,5_attempts,10_attempts,disabled"
    ["session_timeout"]="15_minutes,30_minutes,60_minutes,4_hours"
    ["home_directory"]="local_only,network_shared,encrypted,no_home"
    ["shell_access"]="/bin/bash,/bin/zsh,/usr/bin/false,/sbin/nologin"
)

# Logging function
log_action() {
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $message" | tee -a "$LOG_FILE"
}

# Enhanced user creation with enterprise features
create_enterprise_user() {
    local username="$1"
    local fullname="$2"
    local password="$3"
    local category="${4:-standard_user}"
    local custom_options="$5"
    
    log_action "Creating enterprise user: $username (Category: $category)"
    
    # Validate inputs
    if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
        log_action "ERROR: Username, full name, and password are required"
        return 1
    fi
    
    # Check if user already exists
    if id "$username" &>/dev/null; then
        log_action "ERROR: User '$username' already exists"
        return 1
    fi
    
    # Validate password strength
    if ! validate_password_strength "$password"; then
        log_action "ERROR: Password does not meet strength requirements"
        return 1
    fi
    
    # Generate unique UID
    local new_uid=$(get_next_available_uid)
    
    # Create user account based on category
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    local is_admin="false"
    local shell="/bin/bash"
    local home_dir="/Users/$username"
    
    # Parse category configuration
    IFS=',' read -ra CATEGORY_PARTS <<< "${USER_CATEGORIES[$category]}"
    local user_type="${CATEGORY_PARTS[0]}"
    local privileges="${CATEGORY_PARTS[1]}"
    local access_level="${CATEGORY_PARTS[2]}"
    
    [[ "$user_type" == "admin" ]] && is_admin="true"
    [[ "$privileges" == "no_login" ]] && shell="/usr/bin/false"
    
    # Create the user account
    local create_cmd="sysadminctl -addUser \"$username\" -fullName \"$fullname\" -password \"$password\" -UID \"$new_uid\""
    
    if [[ "$is_admin" == "true" ]]; then
        create_cmd="$create_cmd -admin"
    fi
    
    if eval "$create_cmd"; then
        log_action "SUCCESS: User '$username' created with UID $new_uid"
        
        # Apply additional configurations
        configure_user_environment "$username" "$category" "$custom_options"
        
        # Generate user report
        local report_file="$REPORT_DIR/user_creation_${username}_$(date +%Y%m%d_%H%M%S).json"
        generate_user_report "$username" "$report_file"
        
        echo "$report_file"
        return 0
    else
        log_action "ERROR: Failed to create user '$username'"
        return 1
    fi
}

# Password strength validation
validate_password_strength() {
    local password="$1"
    local min_length=8
    
    # Check minimum length
    if [[ ${#password} -lt $min_length ]]; then
        echo "Password must be at least $min_length characters long"
        return 1
    fi
    
    # Check for uppercase letter
    if [[ ! "$password" =~ [A-Z] ]]; then
        echo "Password must contain at least one uppercase letter"
        return 1
    fi
    
    # Check for lowercase letter
    if [[ ! "$password" =~ [a-z] ]]; then
        echo "Password must contain at least one lowercase letter"
        return 1
    fi
    
    # Check for digit
    if [[ ! "$password" =~ [0-9] ]]; then
        echo "Password must contain at least one digit"
        return 1
    fi
    
    # Check for special character
    if [[ ! "$password" =~ [^a-zA-Z0-9] ]]; then
        echo "Password must contain at least one special character"
        return 1
    fi
    
    return 0
}

# Get next available UID
get_next_available_uid() {
    local start_uid=1000
    local max_uid=65533
    
    for ((uid=start_uid; uid<=max_uid; uid++)); do
        if ! id -u "$uid" &>/dev/null; then
            echo "$uid"
            return 0
        fi
    done
    
    echo "65534"  # Fallback UID
}

# Configure user environment based on category
configure_user_environment() {
    local username="$1"
    local category="$2"
    local custom_options="$3"
    
    log_action "Configuring environment for user: $username (Category: $category)"
    
    case "$category" in
        "developer")
            # Add to developer group
            dseditgroup -o create -q developer 2>/dev/null
            dseditgroup -o edit -a "$username" -t user developer
            
            # Grant sudo access for development
            echo "$username ALL=(ALL) NOPASSWD: /usr/bin/xcodebuild, /usr/local/bin/brew" > "/etc/sudoers.d/$username"
            ;;
        "service_account")
            # Disable login shell
            dscl . -create "/Users/$username" UserShell /usr/bin/false
            
            # Hide from login window
            dscl . -create "/Users/$username" IsHidden 1
            ;;
        "kiosk_user")
            # Set up kiosk environment
            setup_kiosk_user "$username"
            ;;
        "temporary_user")
            # Set account expiration (30 days)
            local expiry_date=$(date -v +30d +%Y-%m-%d)
            dscl . -create "/Users/$username" AccountExpires "$expiry_date"
            ;;
    esac
    
    # Apply custom options if provided
    if [[ -n "$custom_options" ]]; then
        apply_custom_user_options "$username" "$custom_options"
    fi
}

# Set up kiosk user environment
setup_kiosk_user() {
    local username="$1"
    local kiosk_dir="/Users/$username/Desktop"
    
    # Create kiosk desktop environment
    mkdir -p "$kiosk_dir"
    
    # Create launchd plist for kiosk mode
    cat > "/Library/LaunchAgents/com.macfleet.kiosk.$username.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.macfleet.kiosk.$username</string>
    <key>ProgramArguments</key>
    <array>
        <string>/System/Applications/Safari.app/Contents/MacOS/Safari</string>
        <string>--kiosk</string>
        <string>https://company-portal.example.com</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>UserName</key>
    <string>$username</string>
</dict>
</plist>
EOF
    
    chown "$username:staff" "/Library/LaunchAgents/com.macfleet.kiosk.$username.plist"
    chmod 644 "/Library/LaunchAgents/com.macfleet.kiosk.$username.plist"
}

# Generate user report
generate_user_report() {
    local username="$1"
    local report_file="$2"
    
    # Get user information
    local user_info=$(id "$username")
    local user_groups=$(groups "$username")
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d: -f2 | xargs)
    local shell=$(dscl . -read "/Users/$username" UserShell | cut -d: -f2 | xargs)
    local real_name=$(dscl . -read "/Users/$username" RealName | cut -d: -f2 | xargs)
    
    cat > "$report_file" << EOF
{
    "user_report": {
        "username": "$username",
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "script_version": "$SCRIPT_VERSION",
        "user_details": {
            "real_name": "$real_name",
            "home_directory": "$home_dir",
            "shell": "$shell",
            "user_info": "$user_info",
            "groups": "$user_groups"
        },
        "creation_status": "success",
        "security_settings": {
            "password_policy_applied": true,
            "account_restrictions": [],
            "group_memberships": []
        }
    }
}
EOF
    
    log_action "User report generated: $report_file"
}

# Fleet user management
manage_fleet_users() {
    local action="$1"
    local target_spec="$2"
    local options="$3"
    
    log_action "Fleet user management: $action"
    
    case "$action" in
        "audit")
            audit_fleet_users "$target_spec"
            ;;
        "sync")
            sync_fleet_users "$target_spec" "$options"
            ;;
        "cleanup")
            cleanup_fleet_users "$target_spec" "$options"
            ;;
        "report")
            generate_fleet_user_report
            ;;
    esac
}

# Audit all users on the system
audit_fleet_users() {
    local filter_pattern="$1"
    
    echo "=== Fleet User Audit ==="
    
    local audit_report="$REPORT_DIR/fleet_user_audit_$(date +%Y%m%d_%H%M%S).json"
    
    cat > "$audit_report" << EOF
{
    "audit_info": {
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "filter_pattern": "$filter_pattern"
    },
    "user_accounts": [],
    "security_summary": {},
    "recommendations": []
}
EOF
    
    # Get all local users
    local users=($(dscl . -list /Users | grep -v "^_" | grep -v "daemon\|nobody\|root"))
    
    for user in "${users[@]}"; do
        if [[ -z "$filter_pattern" || "$user" =~ $filter_pattern ]]; then
            # Get detailed user information
            local uid=$(id -u "$user" 2>/dev/null)
            local gid=$(id -g "$user" 2>/dev/null)
            local groups=$(groups "$user" 2>/dev/null)
            local home=$(dscl . -read "/Users/$user" NFSHomeDirectory 2>/dev/null | cut -d: -f2 | xargs)
            local shell=$(dscl . -read "/Users/$user" UserShell 2>/dev/null | cut -d: -f2 | xargs)
            local last_login=$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}')
            
            # Check if user is admin
            local is_admin="false"
            if dseditgroup -o checkmember -m "$user" admin &>/dev/null; then
                is_admin="true"
            fi
            
            # Add to report
            jq --arg user "$user" \
               --arg uid "$uid" \
               --arg gid "$gid" \
               --arg groups "$groups" \
               --arg home "$home" \
               --arg shell "$shell" \
               --arg last_login "$last_login" \
               --arg is_admin "$is_admin" \
               '.user_accounts += [{
                   "username": $user,
                   "uid": $uid,
                   "gid": $gid,
                   "groups": $groups,
                   "home_directory": $home,
                   "shell": $shell,
                   "last_login": $last_login,
                   "is_admin": ($is_admin == "true")
               }]' "$audit_report" > "${audit_report}.tmp" && mv "${audit_report}.tmp" "$audit_report"
        fi
    done
    
    # Generate security summary
    local total_users=$(echo "${users[@]}" | wc -w)
    local admin_users=$(dseditgroup -o checkmember -m "" admin 2>/dev/null | wc -l)
    local inactive_users=0
    
    # Check for inactive users (no login in 90 days)
    for user in "${users[@]}"; do
        local last_login_timestamp=$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}')
        if [[ -n "$last_login_timestamp" ]]; then
            local days_since_login=$(( ($(date +%s) - $(date -j -f "%b %d %H:%M" "$last_login_timestamp" +%s 2>/dev/null || echo 0)) / 86400 ))
            if [[ $days_since_login -gt 90 ]]; then
                ((inactive_users++))
            fi
        fi
    done
    
    jq --argjson total "$total_users" \
       --argjson admins "$admin_users" \
       --argjson inactive "$inactive_users" \
       '.security_summary = {
           "total_users": $total,
           "admin_users": $admins,
           "inactive_users": $inactive,
           "security_score": (100 - ($admins * 10) - ($inactive * 5))
       }' "$audit_report" > "${audit_report}.tmp" && mv "${audit_report}.tmp" "$audit_report"
    
    log_action "Fleet user audit completed: $audit_report"
    echo "$audit_report"
}

# Main execution function
main() {
    local action="${1:-create}"
    local username="${2:-}"
    local fullname="${3:-}"
    local password="${4:-}"
    local options="${5:-}"
    
    log_action "=== MacFleet User Management Started ==="
    log_action "Action: $action, User: $username"
    
    case "$action" in
        "create")
            if [[ -z "$username" || -z "$fullname" || -z "$password" ]]; then
                echo "Usage: $0 create <username> <fullname> <password> [category]"
                exit 1
            fi
            create_enterprise_user "$username" "$fullname" "$password" "$options"
            ;;
        "modify")
            if [[ -z "$username" || -z "$fullname" ]]; then
                echo "Usage: $0 modify <username> <action> <value>"
                exit 1
            fi
            modify_user_account "$username" "$fullname" "$password"
            ;;
        "delete")
            if [[ -z "$username" ]]; then
                echo "Usage: $0 delete <username> [delete_home] [backup_home]"
                exit 1
            fi
            delete_user_account "$username" "$fullname" "$password"
            ;;
        "audit")
            audit_fleet_users "$username"
            ;;
        "fleet")
            manage_fleet_users "$username" "$fullname" "$password"
            ;;
        "help")
            echo "Usage: $0 [action] [options...]"
            echo "Actions:"
            echo "  create <username> <fullname> <password> [category] - Create user"
            echo "  modify <username> <action> <value> - Modify user"
            echo "  delete <username> [delete_home] [backup_home] - Delete user"
            echo "  audit [pattern] - Audit users"
            echo "  fleet <action> [pattern] [options] - Fleet management"
            echo "  help - Show this help"
            echo ""
            echo "Categories: ${!USER_CATEGORIES[*]}"
            ;;
        *)
            log_action "ERROR: Unknown action: $action"
            exit 1
            ;;
    esac
    
    log_action "=== User management completed ==="
}

# Execute main function
main "$@"

Common User Management Tasks

User Information Display

#!/bin/bash

# Display comprehensive user information
show_user_info() {
    local username="$1"
    
    if ! id "$username" &>/dev/null; then
        echo "User '$username' does not exist"
        return 1
    fi
    
    echo "=== User Information: $username ==="
    
    # Basic user information
    echo "User ID Information:"
    id "$username"
    
    # Group memberships
    echo -e "\nGroup Memberships:"
    groups "$username"
    
    # Home directory information
    local home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory | cut -d: -f2 | xargs)
    echo -e "\nHome Directory: $home_dir"
    if [[ -d "$home_dir" ]]; then
        echo "Home directory size: $(du -sh "$home_dir" | cut -f1)"
    fi
    
    # Login shell
    local shell=$(dscl . -read "/Users/$username" UserShell | cut -d: -f2 | xargs)
    echo -e "\nLogin Shell: $shell"
    
    # Account status
    echo -e "\nAccount Status:"
    if dscl . -read "/Users/$username" AuthenticationAuthority &>/dev/null; then
        echo "Account: Enabled"
    else
        echo "Account: Disabled"
    fi
    
    # Admin status
    if dseditgroup -o checkmember -m "$username" admin &>/dev/null; then
        echo "Admin Privileges: Yes"
    else
        echo "Admin Privileges: No"
    fi
    
    # Last login
    echo -e "\nLast Login:"
    last -1 "$username" | head -1
}

# Usage
show_user_info "daniel"

Password Management

#!/bin/bash

# Comprehensive password management
manage_user_password() {
    local username="$1"
    local action="$2"
    local new_password="$3"
    
    if ! id "$username" &>/dev/null; then
        echo "User '$username' does not exist"
        return 1
    fi
    
    export PATH=/usr/bin:/bin:/usr/sbin:/sbin
    
    case "$action" in
        "change")
            if [[ -z "$new_password" ]]; then
                echo "New password required"
                return 1
            fi
            
            if ! validate_password_strength "$new_password"; then
                return 1
            fi
            
            if sysadminctl -resetPasswordFor "$username" -newPassword "$new_password"; then
                echo "Password changed successfully for user: $username"
                
                # Force password change on next login (optional)
                # pwpolicy -u "$username" -setpolicy "newPasswordRequired=1"
            else
                echo "Failed to change password"
                return 1
            fi
            ;;
        "expire")
            echo "Expiring password for user: $username"
            if pwpolicy -u "$username" -setpolicy "newPasswordRequired=1"; then
                echo "Password expired - user must change on next login"
            else
                echo "Failed to expire password"
                return 1
            fi
            ;;
        "unlock")
            echo "Unlocking account for user: $username"
            if pwpolicy -u "$username" -setpolicy "isDisabled=0"; then
                echo "Account unlocked successfully"
            else
                echo "Failed to unlock account"
                return 1
            fi
            ;;
        *)
            echo "Unknown password action: $action"
            echo "Available actions: change, expire, unlock"
            return 1
            ;;
    esac
}

# Usage
manage_user_password "daniel" "change" "NewSecurePassword123!"

Group Management

#!/bin/bash

# User group management
manage_user_groups() {
    local username="$1"
    local action="$2"
    local group_name="$3"
    
    if ! id "$username" &>/dev/null; then
        echo "User '$username' does not exist"
        return 1
    fi
    
    case "$action" in
        "add")
            echo "Adding user '$username' to group '$group_name'"
            if dseditgroup -o edit -a "$username" -t user "$group_name"; then
                echo "✓ User added to group successfully"
            else
                echo "✗ Failed to add user to group"
                return 1
            fi
            ;;
        "remove")
            echo "Removing user '$username' from group '$group_name'"
            if dseditgroup -o edit -d "$username" -t user "$group_name"; then
                echo "✓ User removed from group successfully"
            else
                echo "✗ Failed to remove user from group"
                return 1
            fi
            ;;
        "list")
            echo "Groups for user '$username':"
            groups "$username"
            ;;
        *)
            echo "Unknown group action: $action"
            echo "Available actions: add, remove, list"
            return 1
            ;;
    esac
}

# Usage
manage_user_groups "daniel" "add" "developers"
manage_user_groups "daniel" "list"

Important Notes

  • Admin privileges required for user creation and modification
  • Password policies should enforce strong passwords for security
  • User validation - Always verify inputs before creating accounts
  • Home directory permissions - Ensure proper ownership and permissions
  • Backup user data before deletion operations
  • Test scripts on individual accounts before fleet deployment
  • Monitor user activities for security compliance

User Account Deletion and Lifecycle Management on macOS

Manage user account lifecycle and secure deletion processes across your MacFleet devices with comprehensive user management, data retention policies, and enterprise offboarding procedures. This tutorial covers secure user deletion, data archival, and compliance-driven user lifecycle management.

Understanding User Account Deletion

User account deletion on macOS involves multiple components and security considerations:

  • Account Removal - Deleting the user account from system databases
  • Data Management - Handling user home directories and associated files
  • Security Tokens - Managing Secure Token requirements for deletion
  • Enterprise Compliance - Meeting data retention and privacy requirements

Enterprise Considerations

Proper user account deletion requires enterprise planning:

  • Data Retention Policies - Compliance with legal and regulatory requirements
  • Security Protocols - Ensuring complete data removal and access revocation
  • Audit Requirements - Maintaining deletion logs for compliance tracking
  • Recovery Procedures - Backup and recovery capabilities before deletion
  • Process Automation - Streamlined offboarding for departing employees

Basic User Account Deletion

Prerequisites and Security Requirements

#!/bin/bash

# Check prerequisites for user deletion
check_deletion_prerequisites() {
    echo "=== User Deletion Prerequisites Check ==="
    
    # Check if running with administrator privileges
    if [[ $EUID -ne 0 ]]; then
        echo "⚠️ Warning: This script requires administrator privileges"
        echo "Run with: sudo $0"
    else
        echo "✓ Administrator privileges confirmed"
    fi
    
    # Check Service app full disk access
    echo ""
    echo "--- Full Disk Access Check ---"
    local tcc_db="/Library/Application Support/com.apple.TCC/TCC.db"
    if [[ -r "$tcc_db" ]]; then
        echo "✓ TCC database accessible - Full disk access likely granted"
    else
        echo "⚠️ Warning: TCC database not accessible"
        echo "Ensure Service app has Full Disk Access in System Preferences"
    fi
    
    # Check available Secure Token holders
    echo ""
    echo "--- Secure Token Analysis ---"
    local secure_token_users=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
    echo "Secure Token holders found: $secure_token_users"
    
    if [[ $secure_token_users -lt 2 ]]; then
        echo "⚠️ Warning: Less than 2 Secure Token holders detected"
        echo "Cannot delete the only Secure Token holder"
        echo "Add another admin user with Secure Token before deletion"
    else
        echo "✓ Multiple Secure Token holders available"
    fi
}

# Usage
check_deletion_prerequisites

Safe User Account Deletion

#!/bin/bash

# Safely delete user account with validation
delete_user_account() {
    local username="$1"
    local method="${2:-sysadminctl}"  # sysadminctl or dscl
    local backup_data="${3:-true}"
    
    if [[ -z "$username" ]]; then
        echo "Usage: delete_user_account <username> [method] [backup_data]"
        echo "Methods: sysadminctl (default), dscl"
        echo "Backup data: true (default), false"
        return 1
    fi
    
    echo "=== Safe User Account Deletion ==="
    echo "Target user: $username"
    echo "Deletion method: $method"
    echo "Backup data: $backup_data"
    echo ""
    
    # Validate user exists
    if ! id "$username" >/dev/null 2>&1; then
        echo "Error: User '$username' does not exist"
        return 1
    fi
    
    # Check if user is currently logged in
    local logged_in_users=$(who | awk '{print $1}' | sort -u)
    if echo "$logged_in_users" | grep -q "^$username$"; then
        echo "⚠️ Warning: User '$username' is currently logged in"
        echo "Force logout or wait for user to log out before deletion"
        return 1
    fi
    
    # Check Secure Token status
    local token_status=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep "Enabled")
    if [[ -n "$token_status" ]]; then
        echo "User '$username' has Secure Token"
        
        # Count total Secure Token holders
        local total_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
        if [[ $total_tokens -eq 1 ]]; then
            echo "Error: Cannot delete the only Secure Token holder"
            echo "Add another admin user with Secure Token first"
            return 1
        fi
    fi
    
    # Backup user data if requested
    if [[ "$backup_data" == "true" ]]; then
        echo "Creating backup of user data..."
        backup_user_data "$username"
    fi
    
    # Perform deletion based on method
    echo ""
    echo "--- Deleting User Account ---"
    case "$method" in
        "sysadminctl")
            delete_user_sysadminctl "$username"
            ;;
        "dscl")
            delete_user_dscl "$username"
            ;;
        *)
            echo "Error: Unknown deletion method: $method"
            return 1
            ;;
    esac
}

# Delete user using sysadminctl (macOS 10.13+)
delete_user_sysadminctl() {
    local username="$1"
    
    echo "Using sysadminctl to delete user: $username"
    
    if sysadminctl -deleteUser "$username" 2>/dev/null; then
        echo "✓ User account '$username' deleted successfully using sysadminctl"
        return 0
    else
        echo "✗ Failed to delete user '$username' using sysadminctl"
        return 1
    fi
}

# Delete user using dscl (legacy method)
delete_user_dscl() {
    local username="$1"
    
    echo "Using dscl to delete user: $username"
    
    if dscl . delete "/Users/$username" 2>/dev/null; then
        echo "✓ User account '$username' deleted successfully using dscl"
        return 0
    else
        echo "✗ Failed to delete user '$username' using dscl"
        return 1
    fi
}

# Usage example (commented out for safety)
# delete_user_account "departing_employee" "sysadminctl" "true"

User Data and Directory Management

#!/bin/bash

# Comprehensive user data management
manage_user_data() {
    local username="$1"
    local action="${2:-archive}"  # archive, delete, preserve
    local backup_location="${3:-/var/backups/user_data}"
    
    if [[ -z "$username" ]]; then
        echo "Usage: manage_user_data <username> [action] [backup_location]"
        echo "Actions: archive (default), delete, preserve"
        return 1
    fi
    
    echo "=== User Data Management ==="
    echo "Username: $username"
    echo "Action: $action"
    echo "Backup location: $backup_location"
    echo ""
    
    local user_home="/Users/$username"
    
    # Check if user home directory exists
    if [[ ! -d "$user_home" ]]; then
        echo "User home directory not found: $user_home"
        return 1
    fi
    
    # Get directory size for reporting
    local dir_size=$(du -sh "$user_home" 2>/dev/null | awk '{print $1}')
    echo "User home directory size: $dir_size"
    
    case "$action" in
        "archive")
            archive_user_data "$username" "$backup_location"
            ;;
        "delete")
            delete_user_data "$username"
            ;;
        "preserve")
            preserve_user_data "$username"
            ;;
        *)
            echo "Error: Unknown action: $action"
            return 1
            ;;
    esac
}

# Archive user data before deletion
archive_user_data() {
    local username="$1"
    local backup_location="$2"
    
    echo "--- Archiving User Data ---"
    
    # Create backup directory if it doesn't exist
    mkdir -p "$backup_location"
    
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local archive_name="${username}_backup_${timestamp}.tar.gz"
    local archive_path="$backup_location/$archive_name"
    
    echo "Creating archive: $archive_path"
    
    # Create compressed archive of user home directory
    if tar -czf "$archive_path" -C "/Users" "$username" 2>/dev/null; then
        echo "✓ User data archived successfully"
        
        # Create metadata file
        local metadata_file="$backup_location/${username}_metadata_${timestamp}.json"
        cat > "$metadata_file" << EOF
{
    "backup_metadata": {
        "username": "$username",
        "backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "archive_file": "$archive_name",
        "archive_size": "$(du -sh "$archive_path" | awk '{print $1}')",
        "original_path": "/Users/$username",
        "backup_location": "$backup_location",
        "hostname": "$(hostname)",
        "created_by": "$(whoami)"
    }
}
EOF
        
        echo "✓ Metadata file created: $metadata_file"
        echo "Archive details:"
        echo "  File: $archive_path"
        echo "  Size: $(du -sh "$archive_path" | awk '{print $1}')"
        
        return 0
    else
        echo "✗ Failed to create archive"
        return 1
    fi
}

# Delete user data and directories
delete_user_data() {
    local username="$1"
    local user_home="/Users/$username"
    
    echo "--- Deleting User Data ---"
    echo "⚠️ WARNING: This will permanently delete all user data"
    echo "Target directory: $user_home"
    
    # Safety check - don't delete system directories
    case "$username" in
        "root"|"admin"|"administrator"|"Guest"|"Shared")
            echo "Error: Cannot delete system user data: $username"
            return 1
            ;;
    esac
    
    if [[ "$user_home" == "/Users/"* && ${#username} -gt 2 ]]; then
        echo "Deleting user home directory..."
        if rm -rf "$user_home" 2>/dev/null; then
            echo "✓ User data deleted successfully: $user_home"
            return 0
        else
            echo "✗ Failed to delete user data: $user_home"
            return 1
        fi
    else
        echo "Error: Invalid user home path: $user_home"
        return 1
    fi
}

# Preserve user data with ownership change
preserve_user_data() {
    local username="$1"
    local user_home="/Users/$username"
    local preserved_name="${username}_preserved_$(date +%Y%m%d)"
    local preserved_path="/Users/$preserved_name"
    
    echo "--- Preserving User Data ---"
    echo "Renaming user directory for preservation"
    echo "From: $user_home"
    echo "To: $preserved_path"
    
    if mv "$user_home" "$preserved_path" 2>/dev/null; then
        # Change ownership to admin user
        chown -R root:admin "$preserved_path" 2>/dev/null
        chmod -R 755 "$preserved_path" 2>/dev/null
        
        echo "✓ User data preserved at: $preserved_path"
        echo "✓ Ownership changed to root:admin"
        return 0
    else
        echo "✗ Failed to preserve user data"
        return 1
    fi
}

# Usage example
# manage_user_data "departing_employee" "archive" "/var/backups/user_data"

Enterprise User Lifecycle Management

#!/bin/bash

# MacFleet User Account Deletion and Lifecycle Management Tool
# Comprehensive user offboarding, data management, and compliance

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_user_lifecycle.log"
REPORT_DIR="/etc/macfleet/reports/users"
CONFIG_DIR="/etc/macfleet/user_management"
POLICY_DIR="/etc/macfleet/policies/users"
BACKUP_DIR="/var/backups/macfleet/users"
COMPLIANCE_DIR="/etc/macfleet/compliance/users"

# Create directories if they don't exist
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$POLICY_DIR" "$BACKUP_DIR" "$COMPLIANCE_DIR"

# User lifecycle policies
declare -A LIFECYCLE_POLICIES=(
    ["immediate_deletion"]="delete_account,delete_data,no_backup,audit_log"
    ["secure_archival"]="backup_data,delete_account,delete_data,compliance_report"
    ["data_preservation"]="backup_data,preserve_home,delete_account,extended_audit"
    ["legal_hold"]="preserve_all,disable_account,legal_compliance,no_deletion"
    ["healthcare_hipaa"]="encrypted_backup,secure_deletion,hipaa_compliance,audit_trail"
    ["financial_compliance"]="full_backup,sox_compliance,retention_policy,secure_deletion"
    ["education_ferpa"]="student_data_protection,ferpa_compliance,selective_backup,audit_log"
    ["government_classified"]="classified_data_handling,security_clearance_check,secure_deletion,audit_trail"
    ["contractor_offboarding"]="project_data_separation,limited_backup,quick_deletion,access_revocation"
    ["temporary_disable"]="disable_only,preserve_all,no_deletion,reactivation_ready"
)

# Data retention periods (in days)
declare -A RETENTION_PERIODS=(
    ["immediate"]="0"
    ["short_term"]="30"
    ["medium_term"]="90"
    ["long_term"]="365"
    ["legal_hold"]="indefinite"
    ["compliance_minimum"]="2555"  # 7 years
)

# Compliance frameworks
declare -A COMPLIANCE_FRAMEWORKS=(
    ["hipaa"]="healthcare_data_protection,encrypted_storage,audit_logs,secure_deletion"
    ["sox"]="financial_records_retention,change_management,access_controls,audit_trail"
    ["ferpa"]="student_privacy,educational_records,consent_management,access_restrictions"
    ["gdpr"]="data_minimization,consent_withdrawal,right_to_erasure,data_portability"
    ["pci_dss"]="payment_data_protection,secure_deletion,access_monitoring,compliance_reporting"
)

# Logging function
log_action() {
    local message="$1"
    local severity="${2:-INFO}"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$severity] $message" | tee -a "$LOG_FILE"
}

# Enhanced user account deletion with enterprise features
enterprise_user_deletion() {
    local username="$1"
    local policy="${2:-secure_archival}"
    local compliance_framework="${3:-}"
    local retention_period="${4:-medium_term}"
    local authorized_by="${5:-$(whoami)}"
    
    log_action "Starting enterprise user deletion process" "INFO"
    log_action "Username: $username, Policy: $policy, Authorized by: $authorized_by" "INFO"
    
    echo "=== Enterprise User Deletion Process ==="
    echo "Username: $username"
    echo "Policy: $policy"
    echo "Compliance Framework: $compliance_framework"
    echo "Retention Period: $retention_period"
    echo "Authorized By: $authorized_by"
    echo "Process ID: $(uuidgen)"
    echo ""
    
    # Validate user exists
    if ! id "$username" >/dev/null 2>&1; then
        log_action "ERROR: User '$username' does not exist" "ERROR"
        return 1
    fi
    
    # Pre-deletion validation
    if ! pre_deletion_validation "$username"; then
        log_action "ERROR: Pre-deletion validation failed for user: $username" "ERROR"
        return 1
    fi
    
    # Apply policy-based deletion process
    apply_deletion_policy "$username" "$policy" "$compliance_framework" "$retention_period" "$authorized_by"
    
    # Generate compliance report
    generate_deletion_compliance_report "$username" "$policy" "$compliance_framework" "$authorized_by"
    
    log_action "user deletion process completed for user: $username" "INFO"
}

# Pre-deletion validation and safety checks
pre_deletion_validation() {
    local username="$1"
    
    echo "--- Pre-Deletion Validation ---"
    
    # Check if user is system user
    local user_id=$(id -u "$username" 2>/dev/null)
    if [[ $user_id -lt 500 ]]; then
        echo "✗ Cannot delete system user (UID < 500): $username"
        return 1
    fi
    
    # Check if user is currently logged in
    if who | grep -q "^$username "; then
        echo "✗ User is currently logged in: $username"
        log_action "Deletion blocked: User $username is currently logged in" "WARNING"
        return 1
    fi
    
    # Check Secure Token requirements
    local has_secure_token=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep -c "Enabled")
    if [[ $has_secure_token -eq 1 ]]; then
        local total_secure_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
        if [[ $total_secure_tokens -eq 1 ]]; then
            echo "✗ Cannot delete the only Secure Token holder: $username"
            log_action "Deletion blocked: $username is the only Secure Token holder" "ERROR"
            return 1
        fi
    fi
    
    # Check for active processes owned by user
    local user_processes=$(ps aux | awk -v user="$username" '$1 == user {print $2}' | wc -l | tr -d ' ')
    if [[ $user_processes -gt 0 ]]; then
        echo "⚠️ Warning: User has $user_processes active processes"
        echo "Terminating user processes..."
        pkill -u "$username" 2>/dev/null
        sleep 2
    fi
    
    # Check home directory size for backup planning
    local home_dir="/Users/$username"
    if [[ -d "$home_dir" ]]; then
        local dir_size=$(du -sm "$home_dir" 2>/dev/null | awk '{print $1}')
        echo "✓ Home directory size: ${dir_size}MB"
        
        # Check available disk space for backup
        local available_space=$(df -m "$BACKUP_DIR" | tail -1 | awk '{print $4}')
        if [[ $dir_size -gt $available_space ]]; then
            echo "⚠️ Warning: Insufficient space for backup"
            echo "Required: ${dir_size}MB, Available: ${available_space}MB"
        fi
    fi
    
    echo "✓ Pre-deletion validation completed"
    return 0
}

# Apply deletion policy
apply_deletion_policy() {
    local username="$1"
    local policy="$2"
    local compliance_framework="$3"
    local retention_period="$4"
    local authorized_by="$5"
    
    echo "--- Applying Deletion Policy: $policy ---"
    
    # Get policy actions
    local policy_actions="${LIFECYCLE_POLICIES[$policy]}"
    if [[ -z "$policy_actions" ]]; then
        log_action "ERROR: Unknown deletion policy: $policy" "ERROR"
        return 1
    fi
    
    echo "Policy actions: $policy_actions"
    
    # Execute policy actions
    IFS=',' read -ra ACTIONS <<< "$policy_actions"
    for action in "${ACTIONS[@]}"; do
        case "$action" in
            "backup_data")
                echo "Executing: Backup user data"
                backup_user_data_enterprise "$username" "$compliance_framework"
                ;;
            "delete_account")
                echo "Executing: Delete user account"
                delete_user_account_enterprise "$username"
                ;;
            "delete_data")
                echo "Executing: Delete user data"
                delete_user_data_secure "$username"
                ;;
            "preserve_home")
                echo "Executing: Preserve home directory"
                preserve_user_data "$username"
                ;;
            "disable_account")
                echo "Executing: Disable user account"
                disable_user_account "$username"
                ;;
            "audit_log")
                echo "Executing: Create audit log"
                create_audit_log "$username" "$policy" "$authorized_by"
                ;;
            "compliance_report")
                echo "Executing: Generate compliance report"
                # Will be handled separately
                ;;
            *)
                echo "Unknown action: $action"
                ;;
        esac
    done
}

# Enterprise backup with encryption and compliance
backup_user_data_enterprise() {
    local username="$1"
    local compliance_framework="$2"
    
    echo "--- Enterprise Data Backup ---"
    
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_name="${username}_enterprise_backup_${timestamp}"
    local backup_path="$BACKUP_DIR/$backup_name"
    
    # Create backup with metadata
    mkdir -p "$backup_path"
    
    # Copy user data
    local user_home="/Users/$username"
    if [[ -d "$user_home" ]]; then
        echo "Backing up user home directory..."
        tar -czf "$backup_path/home_directory.tar.gz" -C "/Users" "$username" 2>/dev/null
    fi
    
    # Backup user account information
    echo "Backing up account metadata..."
    dscl . read "/Users/$username" > "$backup_path/account_metadata.txt" 2>/dev/null
    
    # Create backup manifest
    cat > "$backup_path/backup_manifest.json" << EOF
{
    "backup_manifest": {
        "username": "$username",
        "backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "backup_type": "enterprise_offboarding",
        "compliance_framework": "$compliance_framework",
        "backup_location": "$backup_path",
        "files_included": [
            "home_directory.tar.gz",
            "account_metadata.txt",
            "backup_manifest.json"
        ],
        "backup_size": "$(du -sh "$backup_path" | awk '{print $1}')",
        "hostname": "$(hostname)",
        "authorized_by": "$(whoami)",
        "backup_integrity": "$(find "$backup_path" -type f -exec md5 {} \; | md5)"
    }
}
EOF
    
    # Apply compliance-specific protections
    if [[ -n "$compliance_framework" ]]; then
        apply_compliance_protections "$backup_path" "$compliance_framework"
    fi
    
    echo "✓ Enterprise backup completed: $backup_path"
    log_action "backup created for user $username at $backup_path" "INFO"
}

# Secure deletion with compliance requirements
delete_user_data_secure() {
    local username="$1"
    local user_home="/Users/$username"
    
    echo "--- Secure Data Deletion ---"
    
    if [[ -d "$user_home" ]]; then
        echo "Performing secure deletion of user data..."
        
        # Multiple-pass secure deletion (DoD 5220.22-M standard)
        if command -v gshred >/dev/null 2>&1; then
            echo "Using gshred for secure deletion..."
            find "$user_home" -type f -exec gshred -vfz -n 3 {} \; 2>/dev/null
        elif command -v shred >/dev/null 2>&1; then
            echo "Using shred for secure deletion..."
            find "$user_home" -type f -exec shred -vfz -n 3 {} \; 2>/dev/null
        else
            echo "Secure deletion tools not available, using standard deletion..."
        fi
        
        # Remove directory structure
        rm -rf "$user_home" 2>/dev/null
        
        echo "✓ Secure deletion completed"
        log_action "Secure deletion completed for user data: $user_home" "INFO"
    else
        echo "No user home directory found: $user_home"
    fi
}

# Disable user account instead of deletion
disable_user_account() {
    local username="$1"
    
    echo "--- Disabling User Account ---"
    
    # Disable account using dscl
    if dscl . create "/Users/$username" AuthenticationAuthority ";DisabledUser;" 2>/dev/null; then
        echo "✓ User account disabled: $username"
        log_action "User account disabled: $username" "INFO"
    else
        echo "✗ Failed to disable user account: $username"
        log_action "Failed to disable user account: $username" "ERROR"
    fi
    
    # Set account shell to /usr/bin/false
    dscl . create "/Users/$username" UserShell "/usr/bin/false" 2>/dev/null
    
    # Lock home directory
    local user_home="/Users/$username"
    if [[ -d "$user_home" ]]; then
        chmod 000 "$user_home" 2>/dev/null
        echo "✓ Home directory access revoked"
    fi
}

# Generate comprehensive compliance report
generate_deletion_compliance_report() {
    local username="$1"
    local policy="$2"
    local compliance_framework="$3"
    local authorized_by="$4"
    
    local report_file="$REPORT_DIR/user_deletion_report_${username}_$(date +%Y%m%d_%H%M%S).json"
    
    cat > "$report_file" << EOF
{
    "user_deletion_compliance_report": {
        "report_metadata": {
            "report_id": "$(uuidgen)",
            "generated_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
            "report_type": "user_account_deletion",
            "compliance_framework": "$compliance_framework",
            "hostname": "$(hostname)",
            "script_version": "$SCRIPT_VERSION"
        },
        "user_information": {
            "username": "$username",
            "deletion_policy": "$policy",
            "authorized_by": "$authorized_by",
            "deletion_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
        },
        "compliance_details": {
            "framework": "$compliance_framework",
            "data_retention_requirements": "$(echo "${RETENTION_PERIODS[medium_term]}" | sed 's/indefinite/Legal hold - indefinite retention/')",
            "secure_deletion_method": "DoD 5220.22-M standard",
            "backup_location": "$BACKUP_DIR",
            "audit_trail": "$LOG_FILE"
        },
        "system_information": {
            "os_version": "$(sw_vers -productVersion)",
            "hardware_model": "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk '{print $3}')",
            "secure_token_holders": $(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
        }
    }
}
EOF
    
    echo "Compliance report generated: $report_file"
    log_action "Compliance report generated: $report_file" "INFO"
}

# Fleet user management operations
manage_fleet_users() {
    local operation="$1"
    local user_list="$2"
    local policy="${3:-secure_archival}"
    local compliance_framework="${4:-}"
    
    echo "=== Fleet User Management ==="
    echo "Operation: $operation"
    echo "Policy: $policy"
    echo "Compliance Framework: $compliance_framework"
    echo ""
    
    case "$operation" in
        "bulk_delete")
            echo "Processing bulk user deletion..."
            IFS=',' read -ra USERS <<< "$user_list"
            for username in "${USERS[@]}"; do
                echo "Processing user: $username"
                enterprise_user_deletion "$username" "$policy" "$compliance_framework"
                echo ""
            done
            ;;
        "audit_all")
            echo "Auditing all user accounts..."
            audit_all_users
            ;;
        "compliance_check")
            echo "Running compliance check..."
            compliance_check_users "$compliance_framework"
            ;;
        *)
            echo "Unknown operation: $operation"
            return 1
            ;;
    esac
}

# Main execution function
main() {
    local action="${1:-help}"
    local param1="${2:-}"
    local param2="${3:-}"
    local param3="${4:-}"
    local param4="${5:-}"
    local param5="${6:-}"
    
    log_action "=== MacFleet User Lifecycle Management Started ===" "INFO"
    log_action "Action: $action" "INFO"
    
    case "$action" in
        "delete")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 delete <username> [policy] [compliance_framework] [retention_period] [authorized_by]"
                echo "Policies: ${!LIFECYCLE_POLICIES[*]}"
                echo "Compliance: ${!COMPLIANCE_FRAMEWORKS[*]}"
                echo "Retention: ${!RETENTION_PERIODS[*]}"
                exit 1
            fi
            enterprise_user_deletion "$param1" "$param2" "$param3" "$param4" "$param5"
            ;;
        "backup")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 backup <username> [compliance_framework]"
                exit 1
            fi
            backup_user_data_enterprise "$param1" "$param2"
            ;;
        "disable")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 disable <username>"
                exit 1
            fi
            disable_user_account "$param1"
            ;;
        "fleet")
            if [[ -z "$param1" || -z "$param2" ]]; then
                echo "Usage: $0 fleet <operation> <user_list> [policy] [compliance_framework]"
                echo "Operations: bulk_delete, audit_all, compliance_check"
                exit 1
            fi
            manage_fleet_users "$param1" "$param2" "$param3" "$param4"
            ;;
        "validate")
            if [[ -z "$param1" ]]; then
                echo "Usage: $0 validate <username>"
                exit 1
            fi
            pre_deletion_validation "$param1"
            ;;
        "prereq")
            check_deletion_prerequisites
            ;;
        "help")
            echo "Usage: $0 [action] [options...]"
            echo "Actions:"
            echo "  delete <username> [policy] [compliance] [retention] [authorized_by] - Delete user with enterprise policies"
            echo "  backup <username> [compliance] - Backup user data"
            echo "  disable <username> - Disable user account"
            echo "  fleet <operation> <user_list> [policy] [compliance] - Fleet user operations"
            echo "  validate <username> - Validate deletion prerequisites"
            echo "  prereq - Check system prerequisites"
            echo "  help - Show this help"
            echo ""
            echo "Policies: ${!LIFECYCLE_POLICIES[*]}"
            echo "Compliance: ${!COMPLIANCE_FRAMEWORKS[*]}"
            echo "Retention: ${!RETENTION_PERIODS[*]}"
            ;;
        *)
            log_action "ERROR: Unknown action: $action" "ERROR"
            echo "Use '$0 help' for usage information"
            exit 1
            ;;
    esac
    
    log_action "=== User lifecycle management completed ===" "INFO"
}

# Execute main function
main "$@"

Important Security Considerations

Secure Token Requirements

#!/bin/bash

# Manage Secure Token requirements for user deletion
manage_secure_tokens() {
    echo "=== Secure Token Management ==="
    
    # List all Secure Token holders
    echo "Current Secure Token holders:"
    sysadminctl -secureTokenStatus 2>/dev/null | grep -E "(Username|Enabled)"
    
    echo ""
    echo "--- Secure Token Guidelines ---"
    echo "1. Cannot delete the only Secure Token holder"
    echo "2. Must have at least one admin with Secure Token"
    echo "3. Grant Secure Token before attempting deletion"
    echo "4. Secure Token required for FileVault and certain operations"
}

# Grant Secure Token to admin user
grant_secure_token() {
    local admin_user="$1"
    local target_user="$2"
    
    if [[ -z "$admin_user" || -z "$target_user" ]]; then
        echo "Usage: grant_secure_token <admin_user> <target_user>"
        return 1
    fi
    
    echo "Granting Secure Token to $target_user via $admin_user..."
    sysadminctl -secureTokenOn "$target_user" -password -adminUser "$admin_user"
}

# Usage
manage_secure_tokens

Data Retention and Compliance

#!/bin/bash

# Implement data retention policies
implement_retention_policy() {
    local policy_name="$1"
    local retention_days="${2:-90}"
    
    echo "=== Data Retention Policy Implementation ==="
    echo "Policy: $policy_name"
    echo "Retention Period: $retention_days days"
    
    # Find old backups for cleanup
    local old_backups=$(find "$BACKUP_DIR" -type d -mtime +$retention_days 2>/dev/null)
    
    if [[ -n "$old_backups" ]]; then
        echo "Found backups older than $retention_days days:"
        echo "$old_backups"
        
        # Archive old backups before deletion (if required by policy)
        case "$policy_name" in
            "legal_hold")
                echo "Legal hold active - no deletion performed"
                ;;
            "compliance_minimum")
                echo "Compliance minimum retention - archiving to long-term storage"
                ;;
            *)
                echo "Standard retention - marking for deletion"
                ;;
        esac
    else
        echo "No backups found older than $retention_days days"
    fi
}

# Usage
implement_retention_policy "standard" "90"

Important Notes

  • Administrator Privileges - User deletion requires administrator privileges and proper authentication
  • Secure Token Management - Cannot delete the only Secure Token holder; ensure multiple admin users exist
  • Full Disk Access - Service app requires Full Disk Access permission in System Preferences
  • Data Backup - Always backup user data before deletion if required by organizational policies
  • Compliance Requirements - Different industries have specific data retention and deletion requirements
  • Audit Trails - Maintain comprehensive logs of all user deletion activities for compliance
  • Recovery Procedures - Test backup and recovery procedures before implementing deletion policies

Time Zone Management on macOS

Manage time zones and date/time settings across your MacFleet with enterprise-grade automation, geographic compliance policies, and comprehensive monitoring capabilities.

Understanding Enterprise Time Zone Management

Enterprise time zone management requires more than basic time setting, demanding:

  • Automated geographic compliance with regional time zone policies
  • Centralized time synchronization with enterprise NTP servers
  • Policy enforcement for business hours and operational compliance
  • Real-time monitoring of time drift and synchronization status
  • Audit logging for compliance and security requirements
  • Integration capabilities with existing infrastructure and directory services

Core Time Zone Management Process

Basic Commands

  1. Set Time Zone - sudo systemsetup -settimezone <timezone>
  2. List Time Zones - sudo systemsetup -listtimezones
  3. Enable Network Time - /usr/sbin/systemsetup -setusingnetworktime on
  4. Set Time Server - /usr/sbin/systemsetup -setnetworktimeserver time.apple.com

Core Configuration Examples

# Basic time zone setting
sudo systemsetup -settimezone Pacific/Ponape

# Enable automatic time synchronization
/usr/sbin/systemsetup -setusingnetworktime on -setnetworktimeserver time.apple.com

# List available time zones
sudo systemsetup -listtimezones

Enterprise Time Zone Management System

#!/bin/bash

# MacFleet Enterprise Time Zone Management System
# Comprehensive time zone and date/time management with enterprise controls and monitoring

# Configuration
SCRIPT_NAME="MacFleet Time Zone Manager"
VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_timezone.log"
AUDIT_LOG="/var/log/macfleet_timezone_audit.log"
CONFIG_DIR="/etc/macfleet/timezone"
POLICIES_DIR="/etc/macfleet/timezone/policies"
BACKUP_DIR="/var/backups/timezone"
TEMP_DIR="/tmp/macfleet_timezone"
TIME_DRIFT_THRESHOLD=30  # seconds
SYNC_CHECK_INTERVAL=300  # 5 minutes
ORGANIZATION_NAME="MacFleet Enterprise"
DEPLOYMENT_MODE="enterprise"
ENABLE_COMPLIANCE_CHECKING=true
ENABLE_GEOGRAPHIC_POLICIES=true
AUTO_TIME_SYNC=true

# Enterprise Time Servers (in priority order)
declare -a ENTERPRISE_TIME_SERVERS=(
    "time.company.com"          # Primary enterprise NTP server
    "time2.company.com"         # Secondary enterprise NTP server
    "time.apple.com"            # Apple's time server (fallback)
    "pool.ntp.org"              # Public NTP pool (fallback)
    "time.nist.gov"             # NIST time server (fallback)
)

# Geographic Policy Mapping
declare -A GEOGRAPHIC_POLICIES=(
    ["US_EAST"]="America/New_York"
    ["US_CENTRAL"]="America/Chicago"
    ["US_MOUNTAIN"]="America/Denver"
    ["US_PACIFIC"]="America/Los_Angeles"
    ["US_ALASKA"]="America/Anchorage"
    ["US_HAWAII"]="Pacific/Honolulu"
    ["EU_LONDON"]="Europe/London"
    ["EU_PARIS"]="Europe/Paris"
    ["EU_BERLIN"]="Europe/Berlin"
    ["EU_ZURICH"]="Europe/Zurich"
    ["ASIA_TOKYO"]="Asia/Tokyo"
    ["ASIA_SINGAPORE"]="Asia/Singapore"
    ["ASIA_HONG_KONG"]="Asia/Hong_Kong"
    ["AUSTRALIA_SYDNEY"]="Australia/Sydney"
)

# Business Hours Policies
declare -A BUSINESS_HOURS_POLICIES=(
    ["standard"]="09:00-17:00"
    ["extended"]="08:00-18:00"
    ["24x7"]="00:00-23:59"
    ["custom"]="configurable"
)

# Compliance Requirements
declare -A COMPLIANCE_STANDARDS=(
    ["SOX"]="strict_time_audit"
    ["HIPAA"]="synchronized_logging"
    ["PCI_DSS"]="secure_time_sync"
    ["ISO27001"]="time_source_validation"
)

# Create necessary directories
mkdir -p "$CONFIG_DIR"
mkdir -p "$POLICIES_DIR"
mkdir -p "$BACKUP_DIR"
mkdir -p "$TEMP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"
mkdir -p "$(dirname "$AUDIT_LOG")"

# Set secure permissions
chmod 755 "$CONFIG_DIR"
chmod 750 "$POLICIES_DIR"
chmod 750 "$BACKUP_DIR"
chmod 700 "$TEMP_DIR"

# Logging functions
log_operation() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local admin_user=$(whoami)
    echo "[$timestamp] [$level] [$admin_user] $message" | tee -a "$LOG_FILE"
}

log_security_event() {
    local event_type="$1"
    local details="$2"
    local severity="$3"
    local admin_user=$(whoami)
    
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local source_ip=$(who am i | awk '{print $5}' | tr -d '()')
    echo "SECURITY|$timestamp|$event_type|$severity|$admin_user|$source_ip|$details" >> "$AUDIT_LOG"
}

# Get current time zone information
get_current_timezone() {
    local current_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
    local current_time=$(date '+%Y-%m-%d %H:%M:%S %Z')
    local utc_time=$(date -u '+%Y-%m-%d %H:%M:%S UTC')
    local time_server=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')
    local network_time_status=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')
    
    echo "=== Current Time Zone Information ==="
    echo "Time Zone: $current_tz"
    echo "Local Time: $current_time"
    echo "UTC Time: $utc_time"
    echo "Time Server: $time_server"
    echo "Network Time Sync: $network_time_status"
    echo ""
}

# List available time zones with geographic grouping
list_available_timezones() {
    local filter_region="${1:-all}"
    local format="${2:-grouped}"
    
    echo "=== Available Time Zones ==="
    echo "Filter: $filter_region"
    echo "Format: $format"
    echo ""
    
    if [[ "$format" == "grouped" ]]; then
        # Group by region
        echo "Americas:"
        systemsetup -listtimezones 2>/dev/null | grep "America/" | sort | head -20
        echo ""
        
        echo "Europe:"
        systemsetup -listtimezones 2>/dev/null | grep "Europe/" | sort | head -20
        echo ""
        
        echo "Asia:"
        systemsetup -listtimezones 2>/dev/null | grep "Asia/" | sort | head -20
        echo ""
        
        echo "Pacific:"
        systemsetup -listtimezones 2>/dev/null | grep "Pacific/" | sort | head -20
        echo ""
        
        echo "Other:"
        systemsetup -listtimezones 2>/dev/null | grep -v -E "America/|Europe/|Asia/|Pacific/" | sort | head -10
    else
        # Simple list
        case "$filter_region" in
            "americas"|"america")
                systemsetup -listtimezones 2>/dev/null | grep "America/" | sort
                ;;
            "europe")
                systemsetup -listtimezones 2>/dev/null | grep "Europe/" | sort
                ;;
            "asia")
                systemsetup -listtimezones 2>/dev/null | grep "Asia/" | sort
                ;;
            "pacific")
                systemsetup -listtimezones 2>/dev/null | grep "Pacific/" | sort
                ;;
            *)
                systemsetup -listtimezones 2>/dev/null | sort
                ;;
        esac
    fi
}

# Validate time zone
validate_timezone() {
    local timezone="$1"
    
    if [[ -z "$timezone" ]]; then
        echo "Error: Time zone cannot be empty"
        return 1
    fi
    
    # Check if timezone exists in system list
    if systemsetup -listtimezones 2>/dev/null | grep -q "^$timezone$"; then
        echo "✅ Time zone '$timezone' is valid"
        return 0
    else
        echo "❌ Time zone '$timezone' is not valid"
        echo "Use 'list-timezones' command to see available options"
        return 1
    fi
}

# Set time zone with enterprise validation
set_enterprise_timezone() {
    local timezone="$1"
    local policy="${2:-standard}"
    local force="${3:-false}"
    local admin_user=$(whoami)
    
    log_security_event "TIMEZONE_CHANGE_ATTEMPT" "timezone=$timezone,policy=$policy" "INFO"
    
    echo "=== Enterprise Time Zone Configuration ==="
    echo "Target Time Zone: $timezone"
    echo "Policy: $policy"
    echo "Administrator: $admin_user"
    echo "Force Mode: $force"
    echo ""
    
    # Validate time zone
    if ! validate_timezone "$timezone"; then
        log_operation "ERROR" "Invalid time zone specified: $timezone"
        return 1
    fi
    
    # Check current time zone
    local current_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
    
    if [[ "$current_tz" == "$timezone" && "$force" != "true" ]]; then
        echo "✅ Time zone is already set to $timezone"
        log_operation "INFO" "Time zone unchanged: $timezone"
        return 0
    fi
    
    # Backup current configuration
    local backup_file="$BACKUP_DIR/timezone_$(date +%Y%m%d_%H%M%S).conf"
    {
        echo "# MacFleet Time Zone Backup"
        echo "PREVIOUS_TIMEZONE=$current_tz"
        echo "PREVIOUS_TIME_SERVER=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')"
        echo "PREVIOUS_NETWORK_TIME=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')"
        echo "BACKUP_TIMESTAMP=$(date)"
        echo "CHANGED_BY=$admin_user"
    } > "$backup_file"
    
    log_operation "INFO" "Configuration backed up to: $backup_file"
    
    # Apply time zone change
    echo "Setting time zone to: $timezone"
    
    if sudo systemsetup -settimezone "$timezone" 2>/dev/null; then
        echo "✅ Time zone set successfully"
        log_operation "INFO" "Time zone changed from '$current_tz' to '$timezone'"
        log_security_event "TIMEZONE_CHANGED" "from=$current_tz,to=$timezone,policy=$policy" "INFO"
        
        # Configure network time synchronization
        configure_time_sync "$policy"
        
        # Verify the change
        sleep 2
        local new_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
        
        if [[ "$new_tz" == "$timezone" ]]; then
            echo "✅ Time zone verification successful"
            
            # Display updated time information
            get_current_timezone
            
            return 0
        else
            echo "❌ Time zone verification failed"
            log_operation "ERROR" "Time zone verification failed: expected '$timezone', got '$new_tz'"
            return 1
        fi
    else
        echo "❌ Failed to set time zone"
        log_operation "ERROR" "Failed to set time zone to: $timezone"
        log_security_event "TIMEZONE_CHANGE_FAILED" "timezone=$timezone,error=systemsetup_failed" "ERROR"
        return 1
    fi
}

# Configure time synchronization
configure_time_sync() {
    local policy="${1:-standard}"
    local admin_user=$(whoami)
    
    echo "=== Configuring Time Synchronization ==="
    echo "Policy: $policy"
    echo ""
    
    # Determine time server based on policy
    local time_server
    case "$policy" in
        "enterprise")
            time_server="${ENTERPRISE_TIME_SERVERS[0]}"
            ;;
        "secure")
            time_server="${ENTERPRISE_TIME_SERVERS[1]}"
            ;;
        "standard")
            time_server="time.apple.com"
            ;;
        "public")
            time_server="pool.ntp.org"
            ;;
        *)
            time_server="time.apple.com"
            ;;
    esac
    
    echo "Setting time server to: $time_server"
    
    # Enable network time and set server
    if sudo systemsetup -setusingnetworktime on -setnetworktimeserver "$time_server" 2>/dev/null; then
        echo "✅ Time synchronization configured successfully"
        log_operation "INFO" "Time sync configured: server=$time_server, policy=$policy"
        
        # Test time server connectivity
        test_time_server_connectivity "$time_server"
        
        return 0
    else
        echo "❌ Failed to configure time synchronization"
        log_operation "ERROR" "Failed to configure time sync: server=$time_server"
        
        # Try fallback servers
        echo "Attempting fallback time servers..."
        for fallback_server in "${ENTERPRISE_TIME_SERVERS[@]}"; do
            if [[ "$fallback_server" != "$time_server" ]]; then
                echo "Trying fallback server: $fallback_server"
                
                if sudo systemsetup -setusingnetworktime on -setnetworktimeserver "$fallback_server" 2>/dev/null; then
                    echo "✅ Fallback time server configured: $fallback_server"
                    log_operation "INFO" "Fallback time sync configured: $fallback_server"
                    return 0
                fi
            fi
        done
        
        echo "❌ All time server configurations failed"
        log_operation "ERROR" "All time server configurations failed"
        return 1
    fi
}

# Test time server connectivity
test_time_server_connectivity() {
    local time_server="$1"
    local timeout=10
    
    echo "Testing connectivity to time server: $time_server"
    
    # Test basic connectivity
    if timeout "$timeout" ping -c 3 "$time_server" &>/dev/null; then
        echo "✅ Time server is reachable"
        
        # Test NTP specific connectivity (if ntpdate is available)
        if command -v ntpdate &>/dev/null; then
            if timeout "$timeout" ntpdate -q "$time_server" &>/dev/null; then
                echo "✅ NTP service is responding"
                return 0
            else
                echo "⚠️  Time server reachable but NTP may not be responding"
                return 1
            fi
        else
            echo "✅ Basic connectivity confirmed (ntpdate not available for NTP test)"
            return 0
        fi
    else
        echo "❌ Time server is not reachable"
        log_operation "WARNING" "Time server connectivity failed: $time_server"
        return 1
    fi
}

# Monitor time drift and synchronization
monitor_time_sync() {
    local check_type="${1:-basic}"
    local admin_user=$(whoami)
    
    echo "=== Time Synchronization Monitoring ==="
    echo "Check Type: $check_type"
    echo "Monitor: $admin_user"
    echo ""
    
    local sync_status="HEALTHY"
    local issues=()
    
    # Check if network time is enabled
    local network_time_status=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')
    
    if [[ "$network_time_status" == "On" ]]; then
        echo "✅ Network time synchronization is enabled"
    else
        echo "❌ Network time synchronization is disabled"
        sync_status="CRITICAL"
        issues+=("Network time sync disabled")
    fi
    
    # Check time server configuration
    local time_server=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')
    echo "Time Server: $time_server"
    
    # Test time server connectivity
    if ! test_time_server_connectivity "$time_server"; then
        sync_status="WARNING"
        issues+=("Time server connectivity issues")
    fi
    
    # Check time drift (if ntpdate is available)
    if command -v ntpdate &>/dev/null; then
        echo ""
        echo "Checking time drift..."
        
        local drift_output=$(ntpdate -q "$time_server" 2>/dev/null | tail -1)
        
        if [[ -n "$drift_output" ]]; then
            # Extract drift value (simplified parsing)
            local drift_seconds=$(echo "$drift_output" | grep -o "offset [+-][0-9.]*" | awk '{print $2}' | tr -d '+')
            
            if [[ -n "$drift_seconds" ]]; then
                local drift_abs=$(echo "$drift_seconds" | tr -d '-')
                
                echo "Time drift: ${drift_seconds}s"
                
                if (( $(echo "$drift_abs > $TIME_DRIFT_THRESHOLD" | bc -l) )); then
                    echo "⚠️  Time drift exceeds threshold (${TIME_DRIFT_THRESHOLD}s)"
                    sync_status="WARNING"
                    issues+=("Time drift: ${drift_seconds}s")
                else
                    echo "✅ Time drift within acceptable range"
                fi
            fi
        fi
    else
        echo "ntpdate not available for drift checking"
    fi
    
    # Advanced checks
    if [[ "$check_type" == "comprehensive" ]]; then
        echo ""
        echo "Running comprehensive time monitoring..."
        
        # Check system clock vs hardware clock
        if command -v hwclock &>/dev/null; then
            local sys_time=$(date +%s)
            local hw_time=$(sudo hwclock --show | date -f - +%s 2>/dev/null || echo "0")
            
            if [[ "$hw_time" != "0" ]]; then
                local clock_diff=$((sys_time - hw_time))
                local clock_diff_abs=${clock_diff#-}
                
                echo "System/Hardware clock difference: ${clock_diff}s"
                
                if [[ $clock_diff_abs -gt 30 ]]; then
                    sync_status="WARNING"
                    issues+=("System/Hardware clock drift: ${clock_diff}s")
                fi
            fi
        fi
        
        # Check for chronyd or ntpd processes
        if pgrep -x "chronyd" &>/dev/null || pgrep -x "ntpd" &>/dev/null; then
            echo "✅ Time daemon is running"
        else
            echo "⚠️  No time daemon detected"
        fi
    fi
    
    # Generate monitoring report
    echo ""
    echo "=== Time Sync Status Report ==="
    echo "Overall Status: $sync_status"
    echo "Timestamp: $(date)"
    
    if [[ ${#issues[@]} -gt 0 ]]; then
        echo "Issues Found:"
        printf '  - %s\n' "${issues[@]}"
    else
        echo "✅ All time synchronization systems operational"
    fi
    
    # Log monitoring results
    log_operation "INFO" "Time sync monitoring completed: $sync_status (${#issues[@]} issues)"
    log_security_event "TIME_SYNC_CHECK" "status=$sync_status,issues=${#issues[@]}" "INFO"
    
    # Return appropriate exit code
    case "$sync_status" in
        "HEALTHY") return 0 ;;
        "WARNING") return 1 ;;
        "CRITICAL") return 2 ;;
        *) return 3 ;;
    esac
}

# Apply geographic policy
apply_geographic_policy() {
    local policy_name="$1"
    local admin_user=$(whoami)
    
    log_security_event "GEOGRAPHIC_POLICY_APPLY" "policy=$policy_name" "INFO"
    
    echo "=== Applying Geographic Policy ==="
    echo "Policy: $policy_name"
    echo "Administrator: $admin_user"
    echo ""
    
    # Check if policy exists
    if [[ -z "${GEOGRAPHIC_POLICIES[$policy_name]}" ]]; then
        echo "❌ Unknown geographic policy: $policy_name"
        echo ""
        echo "Available policies:"
        for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
            echo "  $policy -> ${GEOGRAPHIC_POLICIES[$policy]}"
        done
        return 1
    fi
    
    local target_timezone="${GEOGRAPHIC_POLICIES[$policy_name]}"
    
    echo "Target time zone: $target_timezone"
    echo "Policy mapping: $policy_name -> $target_timezone"
    echo ""
    
    # Apply the time zone change
    set_enterprise_timezone "$target_timezone" "geographic_policy"
}

# Generate time zone compliance report
generate_timezone_report() {
    local report_type="${1:-summary}"
    local admin_user=$(whoami)
    local report_file="/var/reports/timezone_report_$(date +%Y%m%d_%H%M%S).txt"
    
    mkdir -p "$(dirname "$report_file")"
    
    log_security_event "REPORT_GENERATION" "type=$report_type" "INFO"
    
    {
        echo "MacFleet Time Zone Management Report"
        echo "==================================="
        echo "Report Type: $report_type"
        echo "Generated: $(date)"
        echo "Generated By: $admin_user"
        echo "Hostname: $(hostname)"
        echo ""
        
        case "$report_type" in
            "summary")
                echo "== Time Zone Summary =="
                get_current_timezone
                
                echo "Geographic Policies Available:"
                for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
                    echo "  $policy: ${GEOGRAPHIC_POLICIES[$policy]}"
                done
                ;;
            "compliance")
                echo "== Compliance Assessment =="
                
                # Check compliance requirements
                local current_tz=$(systemsetup -gettimezone 2>/dev/null | awk -F': ' '{print $2}')
                local network_time=$(systemsetup -getusingnetworktime 2>/dev/null | awk -F': ' '{print $2}')
                local time_server=$(systemsetup -getnetworktimeserver 2>/dev/null | awk -F': ' '{print $2}')
                
                echo "Current Configuration:"
                echo "  Time Zone: $current_tz"
                echo "  Network Time Sync: $network_time"
                echo "  Time Server: $time_server"
                echo ""
                
                echo "Compliance Standards:"
                for standard in "${!COMPLIANCE_STANDARDS[@]}"; do
                    echo "  $standard: ${COMPLIANCE_STANDARDS[$standard]}"
                done
                ;;
            "audit")
                echo "== Audit Information =="
                if [[ -f "$AUDIT_LOG" ]]; then
                    echo "Recent time zone events (last 20):"
                    tail -20 "$AUDIT_LOG"
                else
                    echo "No audit log available"
                fi
                ;;
        esac
        
        echo ""
        echo "== System Time Information =="
        echo "Local Time: $(date)"
        echo "UTC Time: $(date -u)"
        echo "Uptime: $(uptime)"
        
    } > "$report_file"
    
    echo "Time zone report generated: $report_file"
    log_operation "INFO" "Time zone report generated: $report_file"
}

# Set business hours policy
set_business_hours_policy() {
    local policy_name="$1"
    local custom_hours="$2"
    
    echo "=== Business Hours Policy Configuration ==="
    echo "Policy: $policy_name"
    
    if [[ "$policy_name" == "custom" && -n "$custom_hours" ]]; then
        echo "Custom Hours: $custom_hours"
        BUSINESS_HOURS_POLICIES["custom"]="$custom_hours"
    fi
    
    local hours="${BUSINESS_HOURS_POLICIES[$policy_name]}"
    
    if [[ -z "$hours" ]]; then
        echo "❌ Unknown business hours policy: $policy_name"
        echo ""
        echo "Available policies:"
        for policy in "${!BUSINESS_HOURS_POLICIES[@]}"; do
            echo "  $policy: ${BUSINESS_HOURS_POLICIES[$policy]}"
        done
        return 1
    fi
    
    echo "Business Hours: $hours"
    
    # Save policy to configuration file
    local policy_file="$POLICIES_DIR/business_hours.conf"
    {
        echo "# MacFleet Business Hours Policy"
        echo "POLICY_NAME=$policy_name"
        echo "BUSINESS_HOURS=$hours"
        echo "CONFIGURED_BY=$(whoami)"
        echo "CONFIGURED_DATE=$(date)"
    } > "$policy_file"
    
    echo "✅ Business hours policy configured"
    log_operation "INFO" "Business hours policy set: $policy_name ($hours)"
}

# Main time zone management function
main() {
    local action="${1:-help}"
    
    case "$action" in
        "status"|"current")
            get_current_timezone
            ;;
        "list-timezones")
            local filter_region="$2"
            local format="${3:-grouped}"
            
            list_available_timezones "$filter_region" "$format"
            ;;
        "set")
            local timezone="$2"
            local policy="${3:-standard}"
            local force="$4"
            
            if [[ -z "$timezone" ]]; then
                echo "Usage: $0 set <timezone> [policy] [force]"
                echo "Example: $0 set America/New_York enterprise"
                return 1
            fi
            
            set_enterprise_timezone "$timezone" "$policy" "$force"
            ;;
        "validate")
            local timezone="$2"
            
            if [[ -z "$timezone" ]]; then
                echo "Usage: $0 validate <timezone>"
                return 1
            fi
            
            validate_timezone "$timezone"
            ;;
        "sync")
            local policy="${2:-standard}"
            
            configure_time_sync "$policy"
            ;;
        "monitor")
            local check_type="${2:-basic}"
            
            monitor_time_sync "$check_type"
            ;;
        "apply-policy")
            local policy_name="$2"
            
            if [[ -z "$policy_name" ]]; then
                echo "Usage: $0 apply-policy <policy_name>"
                echo ""
                echo "Available geographic policies:"
                for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
                    echo "  $policy"
                done
                return 1
            fi
            
            apply_geographic_policy "$policy_name"
            ;;
        "business-hours")
            local policy_name="$2"
            local custom_hours="$3"
            
            if [[ -z "$policy_name" ]]; then
                echo "Usage: $0 business-hours <policy> [custom_hours]"
                echo ""
                echo "Available policies:"
                for policy in "${!BUSINESS_HOURS_POLICIES[@]}"; do
                    echo "  $policy"
                done
                return 1
            fi
            
            set_business_hours_policy "$policy_name" "$custom_hours"
            ;;
        "report")
            local report_type="${2:-summary}"
            
            generate_timezone_report "$report_type"
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Enterprise Time Zone and Date/Time Management"
            echo ""
            echo "Usage: $0 <action> [options]"
            echo ""
            echo "Actions:"
            echo "  status                                  - Show current time zone information"
            echo "  list-timezones [region] [format]        - List available time zones"
            echo "  set <timezone> [policy] [force]         - Set time zone with policy"
            echo "  validate <timezone>                     - Validate time zone format"
            echo "  sync [policy]                           - Configure time synchronization"
            echo "  monitor [type]                          - Monitor time synchronization"
            echo "  apply-policy <policy>                   - Apply geographic policy"
            echo "  business-hours <policy> [custom]        - Configure business hours"
            echo "  report [type]                           - Generate time zone reports"
            echo "  help                                    - Show this help message"
            echo ""
            echo "Geographic Policies:"
            for policy in "${!GEOGRAPHIC_POLICIES[@]}"; do
                echo "  $policy"
            done
            echo ""
            echo "Time Sync Policies:"
            echo "  enterprise  - Use primary enterprise NTP server"
            echo "  secure      - Use secondary enterprise NTP server"
            echo "  standard    - Use Apple's time server (default)"
            echo "  public      - Use public NTP pool"
            echo ""
            echo "Business Hours Policies:"
            for policy in "${!BUSINESS_HOURS_POLICIES[@]}"; do
                echo "  $policy: ${BUSINESS_HOURS_POLICIES[$policy]}"
            done
            echo ""
            echo "Monitor Types:"
            echo "  basic       - Basic time sync status check"
            echo "  comprehensive - Extended monitoring and diagnostics"
            echo ""
            echo "Report Types:"
            echo "  summary     - Time zone overview (default)"
            echo "  compliance  - Compliance assessment"
            echo "  audit       - Audit trail and events"
            echo ""
            echo "Examples:"
            echo "  $0 set America/New_York enterprise      - Set Eastern time with enterprise policy"
            echo "  $0 apply-policy US_PACIFIC              - Apply US Pacific policy"
            echo "  $0 monitor comprehensive                - Full monitoring check"
            echo "  $0 business-hours extended              - Set extended business hours"
            echo ""
            echo "Features:"
            echo "  • Enterprise-grade time zone management"
            echo "  • Geographic policy automation"
            echo "  • Advanced time synchronization with fallback servers"
            echo "  • Real-time monitoring and drift detection"
            echo "  • Comprehensive audit logging and compliance"
            echo "  • Business hours policy enforcement"
            echo "  • Integration with MacFleet infrastructure"
            ;;
    esac
}

# Execute main function with all arguments
main "$@"

Quick Reference Commands

Basic Time Zone Operations

# Check current time zone status
./timezone_manager.sh status

# List available time zones
./timezone_manager.sh list-timezones

# Set time zone with enterprise policy
./timezone_manager.sh set America/New_York enterprise

# Validate time zone before setting
./timezone_manager.sh validate Europe/London

Geographic Policy Management

# Apply predefined geographic policies
./timezone_manager.sh apply-policy US_EAST
./timezone_manager.sh apply-policy EU_LONDON
./timezone_manager.sh apply-policy ASIA_TOKYO

# List all available geographic policies
./timezone_manager.sh apply-policy

Time Synchronization

# Configure time synchronization with different policies
./timezone_manager.sh sync enterprise    # Use enterprise NTP servers
./timezone_manager.sh sync standard      # Use Apple's time server
./timezone_manager.sh sync public        # Use public NTP pool

# Monitor time synchronization health
./timezone_manager.sh monitor basic
./timezone_manager.sh monitor comprehensive

Business Hours and Compliance

# Set business hours policies
./timezone_manager.sh business-hours standard     # 09:00-17:00
./timezone_manager.sh business-hours extended     # 08:00-18:00
./timezone_manager.sh business-hours 24x7         # 24/7 operations
./timezone_manager.sh business-hours custom "06:00-22:00"

# Generate compliance reports
./timezone_manager.sh report compliance
./timezone_manager.sh report audit

Integration Examples

JAMF Pro Integration

#!/bin/bash

# JAMF Pro script for time zone management
# Parameters: $4 = geographic_policy, $5 = sync_policy, $6 = business_hours

GEOGRAPHIC_POLICY="$4"
SYNC_POLICY="$5"
BUSINESS_HOURS="$6"

# Download time zone manager if not present
if [[ ! -f "/usr/local/bin/macfleet_timezone_manager.sh" ]]; then
    curl -o "/usr/local/bin/macfleet_timezone_manager.sh" \
         "https://scripts.macfleet.com/timezone_manager.sh"
    chmod +x "/usr/local/bin/macfleet_timezone_manager.sh"
fi

# Apply geographic policy
if [[ -n "$GEOGRAPHIC_POLICY" ]]; then
    /usr/local/bin/macfleet_timezone_manager.sh apply-policy "$GEOGRAPHIC_POLICY"
fi

# Configure time synchronization
if [[ -n "$SYNC_POLICY" ]]; then
    /usr/local/bin/macfleet_timezone_manager.sh sync "$SYNC_POLICY"
fi

# Set business hours
if [[ -n "$BUSINESS_HOURS" ]]; then
    /usr/local/bin/macfleet_timezone_manager.sh business-hours "$BUSINESS_HOURS"
fi

# Report status back to JAMF
echo "Time zone configuration completed successfully"

Automated Monitoring Script

#!/bin/bash

# Continuous time zone monitoring for enterprise compliance
monitor_timezone_continuous() {
    local monitoring_interval=300  # 5 minutes
    local alert_threshold=3
    local consecutive_failures=0
    
    while true; do
        # Run time sync monitoring
        if /usr/local/bin/macfleet_timezone_manager.sh monitor basic &>/dev/null; then
            consecutive_failures=0
            echo "$(date): Time zone monitoring passed"
        else
            consecutive_failures=$((consecutive_failures + 1))
            echo "$(date): Time zone monitoring failed ($consecutive_failures)"
            
            # Alert after consecutive failures
            if [[ $consecutive_failures -ge $alert_threshold ]]; then
                send_time_alert "Time synchronization issues detected" "CRITICAL"
                consecutive_failures=0
            fi
        fi
        
        sleep "$monitoring_interval"
    done
}

Advanced Features

Geographic Compliance Automation

# Automatic time zone detection based on IP geolocation
auto_detect_timezone() {
    local detected_country=$(curl -s "http://ip-api.com/line?fields=countryCode")
    local detected_timezone
    
    case "$detected_country" in
        "US")
            # Use more sophisticated detection for US
            detected_timezone=$(curl -s "http://ip-api.com/line?fields=timezone")
            ;;
        "GB")
            detected_timezone="Europe/London"
            ;;
        "DE")
            detected_timezone="Europe/Berlin"
            ;;
        "JP")
            detected_timezone="Asia/Tokyo"
            ;;
        *)
            detected_timezone="UTC"
            ;;
    esac
    
    echo "Detected time zone: $detected_timezone"
    
    # Apply detected time zone with validation
    if validate_timezone "$detected_timezone"; then
        set_enterprise_timezone "$detected_timezone" "auto_detected"
    fi
}

Compliance Auditing

# Enhanced compliance checking
enhanced_compliance_check() {
    local compliance_standard="$1"
    
    echo "=== Enhanced Compliance Check ==="
    echo "Standard: $compliance_standard"
    
    case "$compliance_standard" in
        "SOX")
            # Sarbanes-Oxley requires accurate time stamping
            check_time_accuracy_strict
            verify_audit_trail_integrity
            ;;
        "HIPAA")
            # HIPAA requires synchronized logging
            check_synchronized_logging
            verify_time_source_security
            ;;
        "PCI_DSS")
            # PCI DSS requires secure time synchronization
            check_secure_time_sync
            verify_ntp_security
            ;;
    esac
}

Best Practices

  1. Use enterprise NTP servers for consistent time synchronization
  2. Implement geographic policies for multi-location organizations
  3. Monitor time drift continuously with automated alerting
  4. Maintain audit trails for compliance requirements
  5. Test time server connectivity before deployment
  6. Use backup time servers for redundancy
  7. Coordinate with network teams for NTP server access
  8. Document time zone policies for business operations

This enterprise time zone management system provides comprehensive time and date control with automated geographic compliance, policy enforcement, and enterprise-grade monitoring capabilities for effective MacFleet time management.

Time Machine Backup Management on macOS

Manage and automate Time Machine backups across your MacFleet with enterprise-grade backup policies and disaster recovery capabilities. This tutorial covers advanced backup management, fleet-wide deployment, compliance monitoring, and automated recovery systems.

Understanding Enterprise Time Machine Management

Enterprise backup management requires:

  • 🔄 Automated backup policies - Consistent backup schedules across all devices
  • 🛡️ Disaster recovery planning - Fast recovery from data loss incidents
  • 📊 Compliance monitoring - Audit trails and regulatory compliance
  • ⚡ Fleet-wide management - Centralized backup control and reporting
  • 🔐 Security and encryption - Protected backup data with access controls

Basic Time Machine Operations

Set Backup Destination

#!/bin/bash

# Set Time Machine backup destination
BACKUP_DESTINATION="/Volumes/BackupDrive"

if [[ -d "$BACKUP_DESTINATION" ]]; then
    sudo tmutil setdestination "$BACKUP_DESTINATION"
    echo "✅ Backup destination set to: $BACKUP_DESTINATION"
else
    echo "❌ Backup destination not found: $BACKUP_DESTINATION"
    exit 1
fi

Enable and Start Backup

#!/bin/bash

# Enable Time Machine and start backup
sudo tmutil enable
sudo tmutil startbackup

echo "✅ Time Machine enabled and backup started"

Check Backup Status

#!/bin/bash

# Check current backup status
tmutil status

echo "📊 Current backup status displayed"

List Available Backups

#!/bin/bash

# List all available backups
tmutil listbackups

echo "📋 Available backups listed"

Advanced Backup Management

Intelligent Backup Destination Setup

#!/bin/bash

# Intelligent backup destination with validation
setup_backup_destination() {
    local destination="$1"
    local min_space_gb="${2:-100}"  # Minimum 100GB by default
    
    echo "🔍 Validating backup destination: $destination"
    
    # Check if destination exists
    if [[ ! -d "$destination" ]]; then
        echo "❌ Destination directory does not exist: $destination"
        return 1
    fi
    
    # Check available space
    local available_space=$(df -BG "$destination" | tail -1 | awk '{print $4}' | sed 's/G//')
    
    if [[ $available_space -lt $min_space_gb ]]; then
        echo "❌ Insufficient space: ${available_space}GB available, ${min_space_gb}GB required"
        return 1
    fi
    
    # Check write permissions
    if [[ ! -w "$destination" ]]; then
        echo "❌ No write permission to destination: $destination"
        return 1
    fi
    
    # Set the destination
    sudo tmutil setdestination "$destination"
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Backup destination successfully set: $destination"
        echo "📊 Available space: ${available_space}GB"
        return 0
    else
        echo "❌ Failed to set backup destination"
        return 1
    fi
}

# Usage example
setup_backup_destination "/Volumes/Enterprise_Backup" 500

Advanced Exclusion Management

#!/bin/bash

# Enterprise backup exclusion management
manage_backup_exclusions() {
    local action="$1"  # add, remove, list
    local path="$2"
    
    case "$action" in
        "add")
            if [[ -n "$path" ]]; then
                sudo tmutil addexclusion "$path"
                echo "✅ Added exclusion: $path"
                log_exclusion_change "added" "$path"
            else
                echo "❌ Path required for add operation"
                return 1
            fi
            ;;
        "remove")
            if [[ -n "$path" ]]; then
                sudo tmutil removeexclusion "$path"
                echo "✅ Removed exclusion: $path"
                log_exclusion_change "removed" "$path"
            else
                echo "❌ Path required for remove operation"
                return 1
            fi
            ;;
        "list")
            echo "📋 Current exclusions:"
            tmutil listbackups | while read -r backup; do
                if [[ -d "$backup" ]]; then
                    echo "Checking exclusions for: $backup"
                    # List exclusions would require parsing backup metadata
                fi
            done
            ;;
        "enterprise_defaults")
            apply_enterprise_exclusions
            ;;
        *)
            echo "❌ Invalid action: $action"
            echo "Available actions: add, remove, list, enterprise_defaults"
            return 1
            ;;
    esac
}

# Apply standard enterprise exclusions
apply_enterprise_exclusions() {
    echo "🏢 Applying enterprise backup exclusions..."
    
    local exclusions=(
        "/System/Library/Caches"
        "/Library/Caches"
        "~/Library/Caches"
        "/private/var/vm"
        "/cores"
        "/tmp"
        "/private/tmp"
        "~/.Trash"
        "/Applications/Xcode.app/Contents/Developer/Platforms"  # Large dev files
        "/usr/local/var/log"  # Log files
        "~/Downloads"  # Temporary downloads
    )
    
    for exclusion in "${exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
        echo "Added exclusion: $exclusion"
    done
    
    echo "✅ Enterprise exclusions applied"
}

# Log exclusion changes for audit
log_exclusion_change() {
    local action="$1"
    local path="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local log_entry="[$timestamp] Exclusion $action: $path"
    
    echo "$log_entry" >> "/var/log/macfleet_backup_exclusions.log"
}

Backup Health Monitoring

#!/bin/bash

# Comprehensive backup health assessment
assess_backup_health() {
    echo "🏥 Assessing Time Machine backup health..."
    
    local health_score=100
    local issues=()
    local warnings=()
    
    # Check if Time Machine is enabled
    local tm_enabled=$(tmutil status | grep "Running" | wc -l)
    if [[ $tm_enabled -eq 0 ]]; then
        health_score=$((health_score - 30))
        issues+=("Time Machine is not running")
    fi
    
    # Check backup destination accessibility
    local destinations=$(tmutil destinationinfo | grep "URL" | wc -l)
    if [[ $destinations -eq 0 ]]; then
        health_score=$((health_score - 25))
        issues+=("No backup destinations configured")
    else
        # Check if destinations are accessible
        tmutil destinationinfo | grep "URL" | while read -r line; do
            local dest_path=$(echo "$line" | sed 's/.*URL : //')
            if [[ ! -d "$dest_path" ]]; then
                health_score=$((health_score - 15))
                issues+=("Backup destination inaccessible: $dest_path")
            fi
        done
    fi
    
    # Check last backup time
    local last_backup=$(tmutil latestbackup 2>/dev/null)
    if [[ -n "$last_backup" ]]; then
        local last_backup_timestamp=$(stat -f %m "$last_backup" 2>/dev/null)
        local current_timestamp=$(date +%s)
        local hours_since_backup=$(( (current_timestamp - last_backup_timestamp) / 3600 ))
        
        if [[ $hours_since_backup -gt 48 ]]; then
            health_score=$((health_score - 20))
            issues+=("Last backup was $hours_since_backup hours ago")
        elif [[ $hours_since_backup -gt 24 ]]; then
            health_score=$((health_score - 10))
            warnings+=("Last backup was $hours_since_backup hours ago")
        fi
    else
        health_score=$((health_score - 25))
        issues+=("No previous backups found")
    fi
    
    # Check available disk space on backup destination
    local backup_dest=$(tmutil destinationinfo | grep "URL" | head -1 | sed 's/.*URL : //')
    if [[ -n "$backup_dest" ]] && [[ -d "$backup_dest" ]]; then
        local available_space=$(df -BG "$backup_dest" | tail -1 | awk '{print $4}' | sed 's/G//')
        if [[ $available_space -lt 10 ]]; then
            health_score=$((health_score - 15))
            issues+=("Low disk space on backup destination: ${available_space}GB")
        elif [[ $available_space -lt 50 ]]; then
            warnings+=("Backup destination space getting low: ${available_space}GB")
        fi
    fi
    
    # Generate health report
    echo "📊 Backup Health Score: $health_score/100"
    
    if [[ ${#issues[@]} -gt 0 ]]; then
        echo "🔴 Critical Issues:"
        printf '   - %s\n' "${issues[@]}"
    fi
    
    if [[ ${#warnings[@]} -gt 0 ]]; then
        echo "⚠️ Warnings:"
        printf '   - %s\n' "${warnings[@]}"
    fi
    
    if [[ $health_score -ge 90 ]]; then
        echo "✅ Backup system is healthy"
    elif [[ $health_score -ge 70 ]]; then
        echo "⚠️ Backup system has minor issues"
    else
        echo "🔴 Backup system requires immediate attention"
    fi
    
    return $health_score
}

Enterprise Backup Policies

Production Environment Policy

#!/bin/bash

# High-frequency production backup policy
apply_production_backup_policy() {
    echo "🏭 Applying production backup policy..."
    
    # Enable Time Machine
    sudo tmutil enable
    
    # Set aggressive backup schedule (every 30 minutes)
    configure_backup_intervals 1800 900 600 60
    
    # Apply minimal exclusions (keep most data)
    local minimal_exclusions=(
        "/System/Library/Caches"
        "/private/var/vm"
        "/cores"
    )
    
    for exclusion in "${minimal_exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
    done
    
    # Enable backup verification
    enable_backup_verification
    
    echo "✅ Production backup policy applied"
    log_policy_application "production"
}

Development Environment Policy

#!/bin/bash

# Development-optimized backup policy
apply_development_backup_policy() {
    echo "💻 Applying development backup policy..."
    
    # Enable Time Machine
    sudo tmutil enable
    
    # Set moderate backup schedule (every 2 hours)
    configure_backup_intervals 7200 3600 1800 300
    
    # Exclude development artifacts
    local dev_exclusions=(
        "/System/Library/Caches"
        "/Library/Caches"
        "~/Library/Caches"
        "/private/var/vm"
        "/cores"
        "~/Library/Developer/Xcode/DerivedData"
        "~/Library/Developer/CoreSimulator"
        "*/node_modules"
        "*/.git/objects"
        "*/target"
        "*/build"
        "*/.gradle"
        "*/.npm"
    )
    
    for exclusion in "${dev_exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
    done
    
    echo "✅ Development backup policy applied"
    log_policy_application "development"
}

Executive/Minimal Policy

#!/bin/bash

# Lightweight backup policy for executives
apply_executive_backup_policy() {
    echo "🏢 Applying executive backup policy..."
    
    # Enable Time Machine
    sudo tmutil enable
    
    # Set standard backup schedule (every 4 hours)
    configure_backup_intervals 14400 7200 3600 600
    
    # Exclude non-essential files
    local executive_exclusions=(
        "/System/Library/Caches"
        "/Library/Caches"
        "~/Library/Caches"
        "/private/var/vm"
        "/cores"
        "~/Downloads"
        "~/Movies"
        "/Applications/Games"
        "~/Library/Application Support/Steam"
    )
    
    for exclusion in "${executive_exclusions[@]}"; do
        sudo tmutil addexclusion "$exclusion" 2>/dev/null
    done
    
    echo "✅ Executive backup policy applied"
    log_policy_application "executive"
}

Enterprise Backup Management System

#!/bin/bash

# MacFleet Enterprise Time Machine Management System
# Comprehensive backup management with fleet deployment and compliance

# Configuration
SCRIPT_NAME="MacFleet Backup Manager"
VERSION="4.0.0"
LOG_FILE="/var/log/macfleet_backup.log"
CONFIG_DIR="/etc/macfleet/backup"
POLICY_DIR="/etc/macfleet/backup/policies"
AUDIT_DIR="/etc/macfleet/backup/audit"
RECOVERY_DIR="/etc/macfleet/backup/recovery"

# Create necessary directories
mkdir -p "$CONFIG_DIR" "$POLICY_DIR" "$AUDIT_DIR" "$RECOVERY_DIR"

# Logging function
log_action() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local message="$1"
    echo "[$timestamp] $message" | tee -a "$LOG_FILE"
}

# Policy application logging
log_policy_application() {
    local policy_type="$1"
    local user=$(whoami)
    local hostname=$(hostname)
    
    local audit_entry="{
        \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
        \"hostname\": \"$hostname\",
        \"user\": \"$user\",
        \"policy_type\": \"$policy_type\",
        \"action\": \"policy_applied\",
        \"script_version\": \"$VERSION\"
    }"
    
    echo "$audit_entry" >> "$AUDIT_DIR/policy_audit.json"
    log_action "Backup policy applied: $policy_type"
}

# Configure backup intervals (requires SIP disabled - safer alternative provided)
configure_backup_intervals() {
    local interval="$1"        # Time between backups (seconds)
    local delay="$2"          # Delay after wake (seconds)
    local grace_period="$3"   # Grace period after restart (seconds)
    local start_interval="$4" # Delay after power connect (seconds)
    
    echo "⚙️ Configuring backup intervals..."
    echo "Interval: $interval seconds, Delay: $delay seconds"
    echo "Grace Period: $grace_period seconds, Start Interval: $start_interval seconds"
    
    # Create a configuration record for enterprise tracking
    local config_record="{
        \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
        \"interval\": $interval,
        \"delay\": $delay,
        \"grace_period\": $grace_period,
        \"start_interval\": $start_interval
    }"
    
    echo "$config_record" > "$CONFIG_DIR/backup_intervals.json"
    
    # Note: Actual modification requires SIP disabled
    echo "⚠️ Interval configuration saved. Apply manually if SIP modifications are required."
    log_action "Backup intervals configured: interval=$interval, delay=$delay"
}

# Backup verification system
enable_backup_verification() {
    echo "🔍 Enabling backup verification..."
    
    # Create verification script
    cat > "$CONFIG_DIR/verify_backup.sh" << 'EOF'
#!/bin/bash
# Backup verification script

verify_latest_backup() {
    local latest_backup=$(tmutil latestbackup)
    
    if [[ -z "$latest_backup" ]]; then
        echo "❌ No backup found to verify"
        return 1
    fi
    
    echo "🔍 Verifying backup: $latest_backup"
    
    # Check backup completeness
    if tmutil compare / "$latest_backup" >/dev/null 2>&1; then
        echo "✅ Backup verification successful"
        return 0
    else
        echo "❌ Backup verification failed"
        return 1
    fi
}

verify_latest_backup
EOF
    
    chmod +x "$CONFIG_DIR/verify_backup.sh"
    echo "✅ Backup verification enabled"
}

# Disaster recovery preparation
prepare_disaster_recovery() {
    echo "🆘 Preparing disaster recovery system..."
    
    # Create recovery information
    local recovery_info="{
        \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
        \"hostname\": \"$(hostname)\",
        \"system_version\": \"$(sw_vers -productVersion)\",
        \"backup_destinations\": $(tmutil destinationinfo | grep "URL" | sed 's/.*URL : //' | jq -R . | jq -s .),
        \"latest_backup\": \"$(tmutil latestbackup)\",
        \"user_accounts\": $(dscl . list /Users | grep -v '^_' | jq -R . | jq -s .)
    }"
    
    echo "$recovery_info" > "$RECOVERY_DIR/system_recovery_info.json"
    
    # Create recovery documentation
    cat > "$RECOVERY_DIR/recovery_guide.md" << EOF
# MacFleet Disaster Recovery Guide

## System Information
- Hostname: $(hostname)
- macOS Version: $(sw_vers -productVersion)
- Last Backup: $(tmutil latestbackup)

## Recovery Steps
1. Boot from macOS Recovery (Cmd+R during startup)
2. Open Disk Utility and restore from Time Machine
3. Select latest backup from: $(tmutil latestbackup)
4. Follow Migration Assistant prompts
5. Verify system functionality
6. Run backup health check

## Critical Files Location
- User data: /Users/
- Applications: /Applications/
- System preferences: /Library/Preferences/

## Emergency Contacts
- IT Support: [Configure in enterprise setup]
- MacFleet Admin: [Configure in enterprise setup]
EOF
    
    echo "✅ Disaster recovery preparation completed"
    log_action "Disaster recovery system prepared"
}

# Fleet backup status monitoring
monitor_fleet_backup_status() {
    local fleet_hosts_file="$CONFIG_DIR/fleet_hosts.txt"
    
    if [[ ! -f "$fleet_hosts_file" ]]; then
        echo "❌ Fleet hosts file not found: $fleet_hosts_file"
        return 1
    fi
    
    echo "📊 Monitoring fleet backup status..."
    
    local total_hosts=0
    local healthy_backups=0
    local failed_backups=0
    
    while IFS= read -r host; do
        [[ "$host" =~ ^#.*$ ]] && continue
        [[ -z "$host" ]] && continue
        
        ((total_hosts++))
        echo "Checking: $host"
        
        # Check backup status via SSH
        if ssh "$host" "tmutil status | grep -q 'Running = 1'" 2>/dev/null; then
            echo "✅ $host: Backup running"
            ((healthy_backups++))
        elif ssh "$host" "tmutil latestbackup" >/dev/null 2>&1; then
            echo "⚠️ $host: Backup exists but not running"
            ((healthy_backups++))
        else
            echo "❌ $host: No backup or unreachable"
            ((failed_backups++))
        fi
        
    done < "$fleet_hosts_file"
    
    # Generate fleet status report
    local fleet_report="{
        \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
        \"total_hosts\": $total_hosts,
        \"healthy_backups\": $healthy_backups,
        \"failed_backups\": $failed_backups,
        \"success_rate\": $(echo "scale=2; $healthy_backups * 100 / $total_hosts" | bc -l)
    }"
    
    echo "$fleet_report" > "$AUDIT_DIR/fleet_status_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📈 Fleet Status: $healthy_backups/$total_hosts devices with healthy backups"
    log_action "Fleet backup monitoring completed: $healthy_backups/$total_hosts healthy"
}

# Backup compliance reporting
generate_compliance_report() {
    local report_file="$AUDIT_DIR/backup_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📋 Generating backup compliance report..."
    
    # Gather backup information
    local latest_backup=$(tmutil latestbackup)
    local backup_count=$(tmutil listbackups | wc -l)
    local tm_enabled=$(tmutil status | grep -c "Running")
    local destinations=$(tmutil destinationinfo | grep -c "URL")
    
    # Calculate compliance score
    local compliance_score=0
    [[ $tm_enabled -gt 0 ]] && compliance_score=$((compliance_score + 25))
    [[ $destinations -gt 0 ]] && compliance_score=$((compliance_score + 25))
    [[ -n "$latest_backup" ]] && compliance_score=$((compliance_score + 25))
    [[ $backup_count -gt 0 ]] && compliance_score=$((compliance_score + 25))
    
    # Generate comprehensive report
    local report="{
        \"report_metadata\": {
            \"generated_at\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
            \"hostname\": \"$(hostname)\",
            \"script_version\": \"$VERSION\",
            \"compliance_frameworks\": [\"GDPR\", \"HIPAA\", \"SOX\", \"ISO 27001\"]
        },
        \"backup_status\": {
            \"time_machine_enabled\": $([ $tm_enabled -gt 0 ] && echo "true" || echo "false"),
            \"destinations_configured\": $destinations,
            \"latest_backup\": \"$latest_backup\",
            \"total_backups\": $backup_count,
            \"backup_health_score\": $(assess_backup_health >/dev/null 2>&1; echo $?)
        },
        \"compliance_assessment\": {
            \"overall_score\": $compliance_score,
            \"data_protection_compliance\": $([ $compliance_score -ge 75 ] && echo "\"compliant\"" || echo "\"non_compliant\""),
            \"last_backup_within_24h\": $(check_backup_freshness),
            \"encryption_enabled\": $(check_backup_encryption)
        }
    }"
    
    echo "$report" > "$report_file"
    echo "📊 Compliance report saved: $report_file"
    log_action "Compliance report generated: compliance_score=$compliance_score"
}

# Check backup freshness
check_backup_freshness() {
    local latest_backup=$(tmutil latestbackup)
    
    if [[ -n "$latest_backup" ]]; then
        local last_backup_timestamp=$(stat -f %m "$latest_backup" 2>/dev/null)
        local current_timestamp=$(date +%s)
        local hours_since_backup=$(( (current_timestamp - last_backup_timestamp) / 3600 ))
        
        if [[ $hours_since_backup -le 24 ]]; then
            echo "true"
        else
            echo "false"
        fi
    else
        echo "false"
    fi
}

# Check backup encryption
check_backup_encryption() {
    # Check if FileVault is enabled (indicates system encryption)
    if fdesetup status | grep -q "FileVault is On"; then
        echo "true"
    else
        echo "false"
    fi
}

# Emergency backup initiation
emergency_backup() {
    echo "🚨 EMERGENCY BACKUP INITIATED"
    
    # Ensure Time Machine is enabled
    sudo tmutil enable
    
    # Start immediate backup
    sudo tmutil startbackup --block
    
    local backup_status=$?
    
    if [[ $backup_status -eq 0 ]]; then
        echo "✅ Emergency backup completed successfully"
        log_action "Emergency backup completed successfully"
    else
        echo "❌ Emergency backup failed"
        log_action "Emergency backup failed with status: $backup_status"
    fi
    
    # Generate emergency backup report
    emergency_backup_report
}

# Emergency backup reporting
emergency_backup_report() {
    local report_file="$AUDIT_DIR/emergency_backup_$(date +%Y%m%d_%H%M%S).json"
    
    local report="{
        \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
        \"hostname\": \"$(hostname)\",
        \"emergency_backup_status\": \"completed\",
        \"latest_backup\": \"$(tmutil latestbackup)\",
        \"backup_size\": \"$(du -sh "$(tmutil latestbackup)" 2>/dev/null | cut -f1)\",
        \"system_health\": $(assess_backup_health >/dev/null 2>&1; echo $?)
    }"
    
    echo "$report" > "$report_file"
    echo "📋 Emergency backup report saved: $report_file"
}

# Fleet deployment function
deploy_backup_policy() {
    local policy_type="$1"
    local fleet_hosts_file="$CONFIG_DIR/fleet_hosts.txt"
    
    if [[ ! -f "$fleet_hosts_file" ]]; then
        echo "❌ Fleet hosts file not found: $fleet_hosts_file"
        return 1
    fi
    
    echo "🚀 Deploying backup policy '$policy_type' to fleet..."
    
    local success_count=0
    local total_count=0
    
    while IFS= read -r host; do
        [[ "$host" =~ ^#.*$ ]] && continue
        [[ -z "$host" ]] && continue
        
        ((total_count++))
        echo "Deploying to: $host"
        
        # Deploy script and execute policy
        if scp "$0" "$host:/tmp/macfleet_backup.sh" >/dev/null 2>&1 && \
           ssh "$host" "chmod +x /tmp/macfleet_backup.sh && sudo /tmp/macfleet_backup.sh --policy '$policy_type'" >/dev/null 2>&1; then
            echo "✅ Successfully deployed to $host"
            ((success_count++))
        else
            echo "❌ Failed to deploy to $host"
        fi
        
    done < "$fleet_hosts_file"
    
    echo "📊 Fleet deployment completed: $success_count/$total_count successful"
    log_action "Fleet deployment: $success_count/$total_count hosts successful"
}

# Display current backup status
show_backup_status() {
    echo "=== MacFleet Time Machine Status ==="
    
    # Time Machine status
    local tm_status=$(tmutil status)
    echo "🔄 Time Machine Status:"
    echo "$tm_status"
    echo ""
    
    # Latest backup
    local latest_backup=$(tmutil latestbackup)
    if [[ -n "$latest_backup" ]]; then
        echo "📅 Latest Backup: $latest_backup"
        echo "📊 Backup Size: $(du -sh "$latest_backup" 2>/dev/null | cut -f1)"
    else
        echo "❌ No backups found"
    fi
    echo ""
    
    # Backup destinations
    echo "💾 Backup Destinations:"
    tmutil destinationinfo
    echo ""
    
    # Health assessment
    assess_backup_health
}

# Display usage information
show_usage() {
    cat << EOF
$SCRIPT_NAME v$VERSION

Usage: $0 [OPTION]

BACKUP MANAGEMENT:
    --policy TYPE               Apply backup policy (production|development|executive)
    --emergency                 Start emergency backup
    --status                    Show current backup status
    --health                    Perform backup health assessment

FLEET MANAGEMENT:
    --deploy-fleet POLICY       Deploy backup policy to entire fleet
    --monitor-fleet             Monitor fleet backup status
    --generate-report           Generate compliance report

CONFIGURATION:
    --set-destination PATH      Set backup destination with validation
    --exclude PATH              Add path to backup exclusions
    --include PATH              Remove path from backup exclusions
    --prepare-recovery          Prepare disaster recovery information

EXAMPLES:
    $0 --policy production
    $0 --emergency
    $0 --deploy-fleet development
    $0 --set-destination /Volumes/Backup
    $0 --health

Configuration files:
    $CONFIG_DIR/fleet_hosts.txt     - Fleet deployment hosts
    $POLICY_DIR/                    - Backup policy definitions
    
Log files:
    $LOG_FILE                       - Main log file
    $AUDIT_DIR/                     - Audit and compliance logs
EOF
}

# Main function
main() {
    case "$1" in
        --policy)
            [[ -z "$2" ]] && { echo "❌ Policy type required"; exit 1; }
            case "$2" in
                "production")
                    apply_production_backup_policy
                    ;;
                "development")
                    apply_development_backup_policy
                    ;;
                "executive")
                    apply_executive_backup_policy
                    ;;
                *)
                    echo "❌ Invalid policy type: $2"
                    echo "Available policies: production, development, executive"
                    exit 1
                    ;;
            esac
            ;;
        --emergency)
            emergency_backup
            ;;
        --status)
            show_backup_status
            ;;
        --health)
            assess_backup_health
            ;;
        --deploy-fleet)
            [[ -z "$2" ]] && { echo "❌ Policy type required for fleet deployment"; exit 1; }
            deploy_backup_policy "$2"
            ;;
        --monitor-fleet)
            monitor_fleet_backup_status
            ;;
        --generate-report)
            generate_compliance_report
            ;;
        --set-destination)
            [[ -z "$2" ]] && { echo "❌ Destination path required"; exit 1; }
            setup_backup_destination "$2"
            ;;
        --exclude)
            [[ -z "$2" ]] && { echo "❌ Path required for exclusion"; exit 1; }
            manage_backup_exclusions "add" "$2"
            ;;
        --include)
            [[ -z "$2" ]] && { echo "❌ Path required for inclusion"; exit 1; }
            manage_backup_exclusions "remove" "$2"
            ;;
        --prepare-recovery)
            prepare_disaster_recovery
            ;;
        --help|"")
            show_usage
            ;;
        *)
            echo "❌ Invalid option: $1"
            show_usage
            exit 1
            ;;
    esac
}

# Execute main function
main "$@"

Usage Examples

Apply Enterprise Backup Policies

# Production environment with aggressive backup schedule
sudo ./macfleet_backup.sh --policy production

# Development environment with optimized exclusions
sudo ./macfleet_backup.sh --policy development

# Executive environment with minimal backup footprint
sudo ./macfleet_backup.sh --policy executive

Fleet Management

# Deploy production backup policy across entire fleet
sudo ./macfleet_backup.sh --deploy-fleet production

# Monitor backup status across all devices
sudo ./macfleet_backup.sh --monitor-fleet

# Generate enterprise compliance report
sudo ./macfleet_backup.sh --generate-report

Emergency Operations

# Initiate emergency backup
sudo ./macfleet_backup.sh --emergency

# Check backup system health
sudo ./macfleet_backup.sh --health

# Prepare disaster recovery information
sudo ./macfleet_backup.sh --prepare-recovery

Configuration Management

# Set backup destination with validation
sudo ./macfleet_backup.sh --set-destination /Volumes/Enterprise_Backup

# Add exclusions for large files
sudo ./macfleet_backup.sh --exclude ~/Downloads
sudo ./macfleet_backup.sh --exclude ~/Movies

# Check current status
sudo ./macfleet_backup.sh --status

Compliance and Regulatory Framework

GDPR Compliance

  • 📋 Data Protection: Automated backup of personal data with encryption
  • 🔐 Right to Erasure: Managed exclusions for data removal requests
  • 📊 Data Processing Records: Comprehensive audit trails
  • 🛡️ Security Measures: Encrypted backup destinations and access controls

HIPAA Technical Safeguards

  • 🏥 Data Backup: Regular automated backups of health information
  • 🔐 Encryption: FileVault integration for data protection
  • 📝 Audit Controls: Complete logging of backup activities
  • 🚨 Emergency Access: Emergency backup capabilities for business continuity

SOX Compliance

  • 📋 Financial Data Protection: Automated backup of financial records
  • 🔍 Audit Trails: Comprehensive logging of all backup operations
  • 📊 Retention Policies: Configurable backup retention periods
  • 🛡️ Access Controls: Secure backup destination management

ISO 27001 Controls

  • A.12.3.1: Information backup procedures and testing
  • A.17.1.2: Business continuity planning implementation
  • A.18.1.3: Records management and retention

Advanced Features

Backup Encryption and Security

# Check backup encryption status
check_backup_encryption() {
    if fdesetup status | grep -q "FileVault is On"; then
        echo "✅ System encryption enabled (FileVault)"
        return 0
    else
        echo "⚠️ System encryption not enabled"
        return 1
    fi
}

Storage Optimization

# Optimize backup storage usage
optimize_backup_storage() {
    echo "🗂️ Optimizing backup storage..."
    
    # Remove old snapshots beyond retention policy
    local retention_days=30
    tmutil listbackups | head -n -$retention_days | while read -r old_backup; do
        if [[ -n "$old_backup" ]]; then
            sudo tmutil delete "$old_backup"
            echo "Removed old backup: $old_backup"
        fi
    done
    
    echo "✅ Storage optimization completed"
}

Business Continuity Testing

# Test backup integrity and recovery procedures
test_backup_integrity() {
    echo "🧪 Testing backup integrity..."
    
    local latest_backup=$(tmutil latestbackup)
    
    if [[ -n "$latest_backup" ]]; then
        # Verify backup can be read
        if ls "$latest_backup" >/dev/null 2>&1; then
            echo "✅ Backup is accessible"
            
            # Test random file restoration (non-destructive)
            local test_file=$(find "$latest_backup" -name "*.txt" | head -1)
            if [[ -n "$test_file" ]]; then
                echo "✅ Test file found in backup: $test_file"
            fi
        else
            echo "❌ Backup is not accessible"
            return 1
        fi
    else
        echo "❌ No backup available for testing"
        return 1
    fi
}

Important Security Notes

  • 🔐 Administrative privileges required for Time Machine management
  • 📝 All backup operations are logged for audit and compliance
  • 💾 Backup destinations should be on encrypted volumes
  • 🔄 Regular testing of backup integrity and recovery procedures recommended
  • ⚠️ SIP modifications require careful consideration of security implications
  • 🚨 Emergency procedures should be tested periodically

Troubleshooting

Common Issues

# Check Time Machine daemon status
sudo launchctl list | grep backupd

# Reset Time Machine if stuck
sudo tmutil disable
sudo tmutil enable

# Clear Time Machine cache
sudo rm -rf /Library/Preferences/com.apple.TimeMachine.plist

# Check backup destination permissions
ls -la /Volumes/BackupDrive

Recovery Procedures

# Boot into Recovery Mode: Cmd+R during startup
# Use Migration Assistant or Time Machine restore
# Follow guided recovery process

# Manual file restoration
sudo tmutil restore /path/to/source /path/to/destination