Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Aviso importante

Los ejemplos de código y scripts proporcionados en estos tutoriales son solo para propósitos educativos. Macfleet no es responsable de ningún problema, daño o vulnerabilidad de seguridad que pueda surgir del uso, modificación o implementación de estos ejemplos. Siempre revisa y prueba el código en un entorno seguro antes de usarlo en sistemas de producción.

Run Setup Assistant on macOS Devices at Next Reboot

This comprehensive guide demonstrates how to trigger macOS Setup Assistant on the next device reboot, enabling device reconfiguration, user onboarding, and enterprise deployment workflows.

Overview

The Setup Assistant is macOS's built-in configuration wizard that guides users through initial device setup. It can be triggered manually for various enterprise scenarios:

  • Device reconfiguration: Reset devices to factory-like state while preserving data
  • User onboarding: Streamline new employee device setup
  • Mass deployment: Standardize device configuration across organizations
  • Troubleshooting: Reset system configurations without full device wipe
  • Compliance: Ensure devices meet organizational setup requirements

Basic Setup Assistant Trigger

Simple Setup Assistant Script

Create a basic script to trigger Setup Assistant on next reboot:

#!/bin/bash

# Basic Setup Assistant trigger script
# Usage: ./trigger_setup_assistant.sh

trigger_setup_assistant() {
    # Check if running as root
    if [ "$(id -u)" != "0" ]; then
        echo "Error: This script must be run as root"
        exit 1
    fi
    
    # Check if .AppleSetupDone file exists
    if [ ! -f "/private/var/db/.AppleSetupDone" ]; then
        echo "Setup Assistant marker file not found. Setup Assistant may already be scheduled to run."
        exit 0
    fi
    
    # Remove .AppleSetupDone file
    sudo rm /private/var/db/.AppleSetupDone
    
    if [ $? -eq 0 ]; then
        echo "Setup Assistant will run on the next reboot."
        echo "Please restart the device to begin Setup Assistant."
    else
        echo "Error: Failed to remove Setup Assistant marker file."
        exit 1
    fi
}

# Execute function
trigger_setup_assistant

Enhanced Setup Assistant with Validation

#!/bin/bash

# Enhanced Setup Assistant trigger with validation and logging
# Usage: ./enhanced_setup_assistant.sh

enhanced_setup_assistant() {
    local log_file="/var/log/macfleet_setup_assistant.log"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    local setup_done_file="/private/var/db/.AppleSetupDone"
    local computer_name=$(scutil --get ComputerName)
    
    # Check if running as root
    if [ "$EUID" -ne 0 ]; then
        echo "Error: This script must be run as root"
        exit 1
    fi
    
    # Create log directory if it doesn't exist
    mkdir -p /var/log
    
    # Log the operation start
    echo "[$timestamp] Starting Setup Assistant trigger on $computer_name" >> "$log_file"
    
    # Check macOS version compatibility
    local os_version=$(sw_vers -productVersion)
    local major_version=$(echo "$os_version" | cut -d. -f1)
    
    if [ "$major_version" -ge 14 ]; then
        echo "[$timestamp] WARNING: macOS $os_version detected. Setup Assistant trigger may not work on macOS 14+" >> "$log_file"
        echo "Warning: This script is supported on macOS versions below 14. Current version: $os_version"
        read -p "Do you want to continue anyway? (y/N): " continue_anyway
        if [ "$continue_anyway" != "y" ] && [ "$continue_anyway" != "Y" ]; then
            echo "[$timestamp] Operation cancelled by user due to version compatibility" >> "$log_file"
            echo "Operation cancelled."
            exit 0
        fi
    fi
    
    # Check if Setup Assistant marker file exists
    if [ ! -f "$setup_done_file" ]; then
        echo "[$timestamp] Setup Assistant marker file not found at $setup_done_file" >> "$log_file"
        echo "Setup Assistant marker file not found. Setup Assistant may already be scheduled to run."
        echo "File location: $setup_done_file"
        exit 0
    fi
    
    # Get file information before removal
    local file_info=$(ls -la "$setup_done_file" 2>/dev/null)
    echo "[$timestamp] Current marker file info: $file_info" >> "$log_file"
    
    # Create backup of marker file
    local backup_dir="/var/backups/macfleet"
    mkdir -p "$backup_dir"
    cp "$setup_done_file" "$backup_dir/.AppleSetupDone.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null
    
    # Remove .AppleSetupDone file
    rm "$setup_done_file"
    
    # Verify removal
    if [ ! -f "$setup_done_file" ]; then
        echo "[$timestamp] Setup Assistant marker file removed successfully" >> "$log_file"
        echo "Setup Assistant has been configured to run on the next reboot."
        echo ""
        echo "Device Information:"
        echo "  Computer Name: $computer_name"
        echo "  macOS Version: $os_version"
        echo "  Timestamp: $timestamp"
        echo ""
        echo "Next Steps:"
        echo "  1. Restart the device to begin Setup Assistant"
        echo "  2. Follow the on-screen prompts to configure the device"
        echo "  3. Setup Assistant will guide through language, region, accounts, and other settings"
        echo ""
        echo "Note: All existing user data and applications will remain intact."
    else
        echo "[$timestamp] ERROR: Failed to remove Setup Assistant marker file" >> "$log_file"
        echo "Error: Failed to remove Setup Assistant marker file."
        echo "Please check permissions and try again."
        exit 1
    fi
}

# Execute enhanced setup
enhanced_setup_assistant

Advanced Setup Assistant Management

Conditional Setup Assistant Trigger

#!/bin/bash

# Conditional Setup Assistant trigger with multiple scenarios
# Usage: ./conditional_setup_assistant.sh [scenario]

conditional_setup_assistant() {
    local scenario=${1:-"default"}
    local log_file="/var/log/macfleet_setup_assistant.log"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # Check if running as root
    if [ "$EUID" -ne 0 ]; then
        echo "Error: This script must be run as root"
        exit 1
    fi
    
    echo "[$timestamp] Conditional Setup Assistant trigger - Scenario: $scenario" >> "$log_file"
    
    case $scenario in
        "new_employee")
            trigger_new_employee_setup
            ;;
        "device_refresh")
            trigger_device_refresh_setup
            ;;
        "compliance_reset")
            trigger_compliance_reset
            ;;
        "troubleshooting")
            trigger_troubleshooting_setup
            ;;
        "mass_deployment")
            trigger_mass_deployment_setup
            ;;
        "default")
            trigger_default_setup
            ;;
        *)
            echo "Unknown scenario: $scenario"
            echo "Available scenarios: new_employee, device_refresh, compliance_reset, troubleshooting, mass_deployment, default"
            exit 1
            ;;
    esac
}

trigger_new_employee_setup() {
    echo "Configuring Setup Assistant for new employee onboarding..."
    
    # Remove Setup Assistant marker
    rm -f /private/var/db/.AppleSetupDone
    
    # Clear previous user data (optional)
    echo "[$timestamp] New employee setup - Setup Assistant configured" >> "$log_file"
    
    cat << 'EOF'
Setup Assistant configured for new employee onboarding.

The following will be presented to the user:
• Language and region selection
• Wi-Fi network configuration
• Apple ID sign-in
• User account creation
• Privacy and security settings
• Touch ID setup (if available)
• Desktop appearance preferences

Please restart the device and provide to the new employee.
EOF
}

trigger_device_refresh_setup() {
    echo "Configuring Setup Assistant for device refresh..."
    
    # Check if user data should be preserved
    local user_dirs=$(ls /Users | grep -v "Shared" | grep -v "Guest" | head -5)
    if [ -n "$user_dirs" ]; then
        echo "Existing user accounts detected:"
        echo "$user_dirs"
        echo ""
        read -p "Preserve existing user data? (Y/n): " preserve_data
        
        if [ "$preserve_data" = "n" ] || [ "$preserve_data" = "N" ]; then
            echo "Warning: This will remove user data during refresh."
            read -p "Are you sure? (y/N): " confirm
            if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
                echo "Operation cancelled."
                return 1
            fi
        fi
    fi
    
    rm -f /private/var/db/.AppleSetupDone
    echo "[$timestamp] Device refresh setup - Setup Assistant configured" >> "$log_file"
    
    echo "Setup Assistant configured for device refresh."
    echo "Restart the device to begin reconfiguration process."
}

trigger_compliance_reset() {
    echo "Configuring Setup Assistant for compliance reset..."
    
    # Log compliance reset
    echo "[$timestamp] Compliance reset initiated - Setup Assistant triggered" >> "$log_file"
    
    # Remove Setup Assistant marker
    rm -f /private/var/db/.AppleSetupDone
    
    # Additional compliance-related cleanup (customize as needed)
    # rm -f /Library/Preferences/com.apple.loginwindow.plist
    
    cat << 'EOF'
Setup Assistant configured for compliance reset.

This will ensure the device meets organizational compliance requirements:
• Force re-acceptance of terms and policies
• Verify user account configurations
• Confirm security settings
• Update privacy preferences
• Validate organizational settings

Restart the device to begin compliance verification.
EOF
}

trigger_troubleshooting_setup() {
    echo "Configuring Setup Assistant for troubleshooting..."
    
    # Create troubleshooting report
    local troubleshoot_report="/tmp/troubleshoot_report_$(date +%Y%m%d_%H%M%S).txt"
    
    cat > "$troubleshoot_report" << EOF
MacFleet Troubleshooting Report
Generated: $(date)
Device: $(scutil --get ComputerName)
macOS Version: $(sw_vers -productVersion)

Issues that Setup Assistant may resolve:
• User account configuration problems
• System preference corruption
• Network configuration issues
• Apple ID authentication problems
• Privacy setting inconsistencies

Setup Assistant will be triggered on next reboot.
EOF
    
    rm -f /private/var/db/.AppleSetupDone
    echo "[$timestamp] Troubleshooting setup - Setup Assistant configured" >> "$log_file"
    
    echo "Setup Assistant configured for troubleshooting."
    echo "Troubleshooting report saved to: $troubleshoot_report"
    echo "Restart the device to begin setup process."
}

trigger_mass_deployment_setup() {
    echo "Configuring Setup Assistant for mass deployment..."
    
    # Get device serial number for tracking
    local serial_number=$(system_profiler SPHardwareDataType | grep "Serial Number" | awk '{print $4}')
    
    # Log deployment
    echo "[$timestamp] Mass deployment setup - Device: $serial_number" >> "$log_file"
    
    rm -f /private/var/db/.AppleSetupDone
    
    cat << EOF
Setup Assistant configured for mass deployment.

Device Serial: $serial_number
Deployment Date: $(date)

Standardized setup will include:
• Language: English (US)
• Region: United States
• Network: Enterprise Wi-Fi
• Account: Standard user account
• Security: Corporate security policies
• Applications: Standard corporate apps

Device is ready for deployment. Restart to begin setup.
EOF
}

trigger_default_setup() {
    echo "Configuring Setup Assistant with default settings..."
    
    rm -f /private/var/db/.AppleSetupDone
    echo "[$timestamp] Default setup - Setup Assistant configured" >> "$log_file"
    
    echo "Setup Assistant configured with default settings."
    echo "Restart the device to begin setup process."
}

# Main execution
if [ $# -eq 0 ]; then
    echo "Usage: $0 [scenario]"
    echo "Available scenarios:"
    echo "  new_employee    - Configure for new employee onboarding"
    echo "  device_refresh  - Configure for device refresh/reconfiguration"
    echo "  compliance_reset - Configure for compliance verification"
    echo "  troubleshooting - Configure for troubleshooting purposes"
    echo "  mass_deployment - Configure for mass deployment"
    echo "  default         - Configure with default settings"
    echo ""
    conditional_setup_assistant "default"
else
    conditional_setup_assistant "$1"
fi

Enterprise Setup Assistant Manager

#!/bin/bash

# Enterprise Setup Assistant Manager with configuration profiles
# Usage: ./enterprise_setup_manager.sh

enterprise_setup_manager() {
    local config_file="/etc/macfleet/setup_assistant_config.conf"
    local log_file="/var/log/macfleet_setup_assistant.log"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # Check if running as root
    if [ "$EUID" -ne 0 ]; then
        echo "Error: This script must be run as root"
        exit 1
    fi
    
    # Create configuration directory
    mkdir -p /etc/macfleet
    
    # Load or create configuration
    if [ -f "$config_file" ]; then
        source "$config_file"
    else
        create_enterprise_config
        source "$config_file"
    fi
    
    echo "[$timestamp] Enterprise Setup Assistant Manager started" >> "$log_file"
    
    # Display configuration menu
    display_enterprise_menu
}

create_enterprise_config() {
    cat > "/etc/macfleet/setup_assistant_config.conf" << 'EOF'
# MacFleet Enterprise Setup Assistant Configuration

# Organization Information
ORGANIZATION_NAME="MacFleet Organization"
IT_CONTACT_EMAIL="support@macfleet.com"
IT_CONTACT_PHONE="1-800-MACFLEET"

# Default Configuration
DEFAULT_LANGUAGE="English"
DEFAULT_REGION="United States"
REQUIRE_APPLE_ID="false"
ENABLE_LOCATION_SERVICES="false"
ENABLE_SIRI="false"
REQUIRE_TERMS_ACCEPTANCE="true"

# Security Settings
REQUIRE_STRONG_PASSWORD="true"
ENABLE_FILEVAULT="true"
REQUIRE_TOUCH_ID="true"

# Deployment Settings
DEPLOYMENT_MODE="enterprise"
SKIP_OPTIONAL_STEPS="true"
AUTO_CONFIGURE_NETWORK="true"
EOF
    
    echo "configuration created at /etc/macfleet/setup_assistant_config.conf"
}

display_enterprise_menu() {
    while true; do
        clear
        echo "======================================="
        echo "MacFleet Enterprise Setup Assistant"
        echo "======================================="
        echo ""
        echo "Organization: $ORGANIZATION_NAME"
        echo "Contact: $IT_CONTACT_EMAIL"
        echo ""
        echo "Available Actions:"
        echo "1. Trigger Setup Assistant (Single Device)"
        echo "2. Prepare Mass Deployment"
        echo "3. Configure Setup Assistant Options"
        echo "4. View Setup Assistant Status"
        echo "5. Generate Deployment Report"
        echo "6. Backup/Restore Setup State"
        echo "7. View Configuration"
        echo "8. Exit"
        echo ""
        read -p "Select an option (1-8): " choice
        
        case $choice in
            1)
                trigger_single_device_setup
                ;;
            2)
                prepare_mass_deployment
                ;;
            3)
                configure_setup_options
                ;;
            4)
                view_setup_status
                ;;
            5)
                generate_deployment_report
                ;;
            6)
                backup_restore_setup
                ;;
            7)
                view_configuration
                ;;
            8)
                echo "Exiting Enterprise Setup Assistant Manager."
                exit 0
                ;;
            *)
                echo "Invalid option. Please try again."
                ;;
        esac
        
        echo ""
        read -p "Press Enter to continue..."
    done
}

trigger_single_device_setup() {
    echo "======================================="
    echo "Trigger Setup Assistant - Single Device"
    echo "======================================="
    
    local device_name=$(scutil --get ComputerName)
    local serial_number=$(system_profiler SPHardwareDataType | grep "Serial Number" | awk '{print $4}')
    
    echo "Device: $device_name"
    echo "Serial: $serial_number"
    echo ""
    
    read -p "Confirm triggering Setup Assistant on this device? (y/N): " confirm
    if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
        # Remove Setup Assistant marker
        if rm -f /private/var/db/.AppleSetupDone; then
            echo "[$timestamp] Single device setup triggered - $device_name ($serial_number)" >> "$log_file"
            echo "Setup Assistant configured successfully."
            echo "Please restart the device to begin setup."
        else
            echo "Error: Failed to configure Setup Assistant."
        fi
    else
        echo "Operation cancelled."
    fi
}

prepare_mass_deployment() {
    echo "======================================="
    echo "Prepare Mass Deployment"
    echo "======================================="
    
    read -p "Enter number of devices for deployment: " device_count
    read -p "Enter deployment batch name: " batch_name
    
    local deployment_dir="/var/macfleet/deployments/$batch_name"
    mkdir -p "$deployment_dir"
    
    # Create deployment package
    cat > "$deployment_dir/deploy_setup_assistant.sh" << 'EOF'
#!/bin/bash
# MacFleet Mass Deployment Setup Assistant Trigger
# Auto-generated deployment script

# Check if running as root
if [ "$EUID" -ne 0 ]; then
    echo "Error: This script must be run as root"
    exit 1
fi

# Remove Setup Assistant marker
rm -f /private/var/db/.AppleSetupDone

# Log deployment
echo "$(date '+%Y-%m-%d %H:%M:%S') - Mass deployment setup triggered on $(scutil --get ComputerName)" >> /var/log/macfleet_mass_deployment.log

echo "Setup Assistant configured for mass deployment."
echo "Restart device to begin setup process."
EOF
    
    chmod +x "$deployment_dir/deploy_setup_assistant.sh"
    
    # Create deployment manifest
    cat > "$deployment_dir/deployment_manifest.txt" << EOF
MacFleet Mass Deployment Manifest
Batch Name: $batch_name
Device Count: $device_count
Created: $(date)
Organization: $ORGANIZATION_NAME

Deployment Instructions:
1. Copy deploy_setup_assistant.sh to each device
2. Run script as root on each device
3. Restart devices to begin Setup Assistant
4. Follow standard setup procedures

Contact: $IT_CONTACT_EMAIL
EOF
    
    echo "Mass deployment package created at: $deployment_dir"
    echo "Deployment script: $deployment_dir/deploy_setup_assistant.sh"
    echo "Manifest: $deployment_dir/deployment_manifest.txt"
}

configure_setup_options() {
    echo "======================================="
    echo "Configure Setup Assistant Options"
    echo "======================================="
    
    echo "Current Configuration:"
    echo "  Language: $DEFAULT_LANGUAGE"
    echo "  Region: $DEFAULT_REGION"
    echo "  Require Apple ID: $REQUIRE_APPLE_ID"
    echo "  Enable Location Services: $ENABLE_LOCATION_SERVICES"
    echo "  Enable Siri: $ENABLE_SIRI"
    echo ""
    
    read -p "Modify configuration? (y/N): " modify
    if [ "$modify" = "y" ] || [ "$modify" = "Y" ]; then
        echo "Configuration modification would require additional setup..."
        echo "Please edit: /etc/macfleet/setup_assistant_config.conf"
    fi
}

view_setup_status() {
    echo "======================================="
    echo "Setup Assistant Status"
    echo "======================================="
    
    local setup_done_file="/private/var/db/.AppleSetupDone"
    local device_name=$(scutil --get ComputerName)
    local os_version=$(sw_vers -productVersion)
    
    echo "Device: $device_name"
    echo "macOS Version: $os_version"
    echo "Timestamp: $(date)"
    echo ""
    
    if [ -f "$setup_done_file" ]; then
        echo "Status: Setup Assistant COMPLETED"
        echo "File: $setup_done_file exists"
        echo "Modified: $(stat -f "%Sm" "$setup_done_file")"
        echo ""
        echo "Setup Assistant will NOT run on next reboot."
    else
        echo "Status: Setup Assistant SCHEDULED"
        echo "File: $setup_done_file does not exist"
        echo ""
        echo "Setup Assistant WILL run on next reboot."
    fi
}

generate_deployment_report() {
    echo "======================================="
    echo "Generate Deployment Report"
    echo "======================================="
    
    local report_file="/tmp/macfleet_setup_report_$(date +%Y%m%d_%H%M%S).txt"
    
    cat > "$report_file" << EOF
MacFleet Setup Assistant Deployment Report
Generated: $(date)
Organization: $ORGANIZATION_NAME

Device Information:
  Computer Name: $(scutil --get ComputerName)
  Serial Number: $(system_profiler SPHardwareDataType | grep "Serial Number" | awk '{print $4}')
  macOS Version: $(sw_vers -productVersion)
  Hardware Model: $(system_profiler SPHardwareDataType | grep "Model Name" | cut -d: -f2 | xargs)

Setup Assistant Status:
EOF
    
    if [ -f "/private/var/db/.AppleSetupDone" ]; then
        echo "  Status: Completed" >> "$report_file"
        echo "  Last Run: $(stat -f "%Sm" "/private/var/db/.AppleSetupDone")" >> "$report_file"
    else
        echo "  Status: Scheduled for next reboot" >> "$report_file"
    fi
    
    cat >> "$report_file" << EOF

Configuration:
  Default Language: $DEFAULT_LANGUAGE
  Default Region: $DEFAULT_REGION
  Deployment Mode: $DEPLOYMENT_MODE
  Contact: $IT_CONTACT_EMAIL

Recent Log Entries:
EOF
    
    if [ -f "/var/log/macfleet_setup_assistant.log" ]; then
        tail -10 "/var/log/macfleet_setup_assistant.log" >> "$report_file"
    else
        echo "  No log entries found" >> "$report_file"
    fi
    
    echo "Deployment report generated: $report_file"
}

backup_restore_setup() {
    echo "======================================="
    echo "Backup/Restore Setup State"
    echo "======================================="
    
    echo "1. Backup current Setup Assistant state"
    echo "2. Restore Setup Assistant state"
    echo ""
    read -p "Select option (1-2): " backup_option
    
    case $backup_option in
        1)
            backup_setup_state
            ;;
        2)
            restore_setup_state
            ;;
        *)
            echo "Invalid option."
            ;;
    esac
}

backup_setup_state() {
    local backup_dir="/var/backups/macfleet"
    local timestamp=$(date +%Y%m%d_%H%M%S)
    
    mkdir -p "$backup_dir"
    
    if [ -f "/private/var/db/.AppleSetupDone" ]; then
        cp "/private/var/db/.AppleSetupDone" "$backup_dir/.AppleSetupDone.backup.$timestamp"
        echo "Setup Assistant state backed up to: $backup_dir/.AppleSetupDone.backup.$timestamp"
    else
        echo "No Setup Assistant state to backup (file does not exist)."
    fi
}

restore_setup_state() {
    local backup_dir="/var/backups/macfleet"
    
    if [ -d "$backup_dir" ]; then
        echo "Available backups:"
        ls -la "$backup_dir"/.AppleSetupDone.backup.* 2>/dev/null || echo "No backups found."
        echo ""
        read -p "Enter backup filename to restore: " backup_file
        
        if [ -f "$backup_dir/$backup_file" ]; then
            cp "$backup_dir/$backup_file" "/private/var/db/.AppleSetupDone"
            echo "Setup Assistant state restored from: $backup_file"
        else
            echo "Backup file not found."
        fi
    else
        echo "No backup directory found."
    fi
}

view_configuration() {
    echo "======================================="
    echo "Current Configuration"
    echo "======================================="
    
    if [ -f "/etc/macfleet/setup_assistant_config.conf" ]; then
        cat "/etc/macfleet/setup_assistant_config.conf"
    else
        echo "No configuration file found."
    fi
}

# Execute enterprise manager
enterprise_setup_manager

Setup Assistant Automation and Monitoring

Automated Setup Assistant Deployment

#!/bin/bash

# Automated Setup Assistant deployment with scheduling
# Usage: ./automated_setup_deployment.sh

automated_setup_deployment() {
    local config_file="/etc/macfleet/automated_deployment.conf"
    local log_file="/var/log/macfleet_automated_setup.log"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    # Check if running as root
    if [ "$EUID" -ne 0 ]; then
        echo "Error: This script must be run as root"
        exit 1
    fi
    
    # Create configuration if it doesn't exist
    if [ ! -f "$config_file" ]; then
        create_automation_config
    fi
    
    source "$config_file"
    
    echo "[$timestamp] Automated Setup Assistant deployment started" >> "$log_file"
    
    # Check deployment conditions
    check_deployment_conditions
    
    # Execute deployment based on configuration
    execute_automated_deployment
}

create_automation_config() {
    mkdir -p /etc/macfleet
    
    cat > "/etc/macfleet/automated_deployment.conf" << 'EOF'
# MacFleet Automated Setup Assistant Deployment Configuration

# Deployment Schedule
ENABLE_SCHEDULED_DEPLOYMENT="false"
DEPLOYMENT_TIME="02:00"  # 24-hour format
DEPLOYMENT_DAYS="Mon,Wed,Fri"

# Deployment Conditions
CHECK_USER_ACTIVITY="true"
IDLE_TIME_THRESHOLD="3600"  # seconds
REQUIRE_AC_POWER="true"
MIN_BATTERY_LEVEL="50"

# Notification Settings
NOTIFY_USERS="true"
NOTIFICATION_LEAD_TIME="300"  # 5 minutes
ALLOW_USER_POSTPONE="true"
MAX_POSTPONE_COUNT="3"

# Deployment Scope
TARGET_DEVICES="all"  # all, specific_models, specific_serials
EXCLUDE_CRITICAL_HOURS="true"
BUSINESS_HOURS_START="09:00"
BUSINESS_HOURS_END="17:00"

# Rollback Settings
ENABLE_AUTOMATIC_ROLLBACK="true"
ROLLBACK_ON_ERROR="true"
BACKUP_BEFORE_DEPLOYMENT="true"
EOF
    
    echo "Automation configuration created at /etc/macfleet/automated_deployment.conf"
}

check_deployment_conditions() {
    local current_time=$(date +%H:%M)
    local current_day=$(date +%a)
    local battery_level=$(pmset -g batt | grep -o '[0-9]*%' | sed 's/%//')
    local ac_power=$(pmset -g batt | grep -c "AC Power")
    
    echo "[$timestamp] Checking deployment conditions" >> "$log_file"
    
    # Check if deployment is enabled
    if [ "$ENABLE_SCHEDULED_DEPLOYMENT" != "true" ]; then
        echo "[$timestamp] Scheduled deployment is disabled" >> "$log_file"
        echo "Scheduled deployment is disabled."
        return 1
    fi
    
    # Check deployment time
    if [ "$current_time" != "$DEPLOYMENT_TIME" ]; then
        echo "[$timestamp] Not deployment time (current: $current_time, scheduled: $DEPLOYMENT_TIME)" >> "$log_file"
        return 1
    fi
    
    # Check deployment day
    if [[ "$DEPLOYMENT_DAYS" != *"$current_day"* ]]; then
        echo "[$timestamp] Not deployment day (current: $current_day, scheduled: $DEPLOYMENT_DAYS)" >> "$log_file"
        return 1
    fi
    
    # Check business hours
    if [ "$EXCLUDE_CRITICAL_HOURS" = "true" ]; then
        if [[ "$current_time" > "$BUSINESS_HOURS_START" && "$current_time" < "$BUSINESS_HOURS_END" ]]; then
            echo "[$timestamp] Deployment blocked during business hours" >> "$log_file"
            return 1
        fi
    fi
    
    # Check power requirements
    if [ "$REQUIRE_AC_POWER" = "true" ] && [ "$ac_power" -eq 0 ]; then
        echo "[$timestamp] AC power required but not available" >> "$log_file"
        return 1
    fi
    
    # Check battery level
    if [ -n "$battery_level" ] && [ "$battery_level" -lt "$MIN_BATTERY_LEVEL" ]; then
        echo "[$timestamp] Battery level too low ($battery_level% < $MIN_BATTERY_LEVEL%)" >> "$log_file"
        return 1
    fi
    
    # Check user activity
    if [ "$CHECK_USER_ACTIVITY" = "true" ]; then
        local idle_time=$(ioreg -c IOHIDSystem | awk '/HIDIdleTime/ {print $3/1000000000; exit}')
        if [ "$(echo "$idle_time < $IDLE_TIME_THRESHOLD" | bc)" -eq 1 ]; then
            echo "[$timestamp] User activity detected (idle: ${idle_time}s < ${IDLE_TIME_THRESHOLD}s)" >> "$log_file"
            return 1
        fi
    fi
    
    echo "[$timestamp] All deployment conditions met" >> "$log_file"
    return 0
}

execute_automated_deployment() {
    echo "[$timestamp] Executing automated Setup Assistant deployment" >> "$log_file"
    
    # Send user notification if enabled
    if [ "$NOTIFY_USERS" = "true" ]; then
        send_user_notification
    fi
    
    # Create backup if enabled
    if [ "$BACKUP_BEFORE_DEPLOYMENT" = "true" ]; then
        create_deployment_backup
    fi
    
    # Trigger Setup Assistant
    if rm -f /private/var/db/.AppleSetupDone; then
        echo "[$timestamp] Setup Assistant triggered successfully via automation" >> "$log_file"
        
        # Schedule automatic reboot if configured
        if [ -n "$AUTO_REBOOT_DELAY" ]; then
            echo "[$timestamp] Scheduling automatic reboot in $AUTO_REBOOT_DELAY minutes" >> "$log_file"
            at "now + $AUTO_REBOOT_DELAY minutes" << 'EOF'
/sbin/reboot
EOF
        fi
        
        # Send completion notification
        send_completion_notification
        
    else
        echo "[$timestamp] ERROR: Failed to trigger Setup Assistant" >> "$log_file"
        
        # Execute rollback if enabled
        if [ "$ROLLBACK_ON_ERROR" = "true" ]; then
            execute_rollback
        fi
    fi
}

send_user_notification() {
    local notification_title="MacFleet Setup Assistant"
    local notification_message="Setup Assistant will be triggered in $NOTIFICATION_LEAD_TIME seconds. Please save your work."
    
    # Use osascript to display notification
    osascript -e "display notification \"$notification_message\" with title \"$notification_title\" sound name \"Glass\""
    
    # Wait for lead time
    sleep "$NOTIFICATION_LEAD_TIME"
}

create_deployment_backup() {
    local backup_dir="/var/backups/macfleet/automated"
    local backup_timestamp=$(date +%Y%m%d_%H%M%S)
    
    mkdir -p "$backup_dir"
    
    if [ -f "/private/var/db/.AppleSetupDone" ]; then
        cp "/private/var/db/.AppleSetupDone" "$backup_dir/.AppleSetupDone.auto_backup.$backup_timestamp"
        echo "[$timestamp] Backup created: .AppleSetupDone.auto_backup.$backup_timestamp" >> "$log_file"
    fi
}

send_completion_notification() {
    local notification_title="MacFleet Setup Assistant"
    local notification_message="Setup Assistant has been configured. Device will restart shortly."
    
    osascript -e "display notification \"$notification_message\" with title \"$notification_title\" sound name \"Glass\""
}

execute_rollback() {
    echo "[$timestamp] Executing rollback due to deployment error" >> "$log_file"
    
    local latest_backup=$(ls -t /var/backups/macfleet/automated/.AppleSetupDone.auto_backup.* 2>/dev/null | head -1)
    
    if [ -n "$latest_backup" ]; then
        cp "$latest_backup" "/private/var/db/.AppleSetupDone"
        echo "[$timestamp] Rollback completed using backup: $(basename "$latest_backup")" >> "$log_file"
    else
        echo "[$timestamp] No backup available for rollback" >> "$log_file"
    fi
}

# Execute automated deployment
automated_setup_deployment

Troubleshooting and Best Practices

Common Issues and Solutions

1. macOS Version Compatibility

# Check macOS version before execution
os_version=$(sw_vers -productVersion)
major_version=$(echo "$os_version" | cut -d. -f1)

if [ "$major_version" -ge 14 ]; then
    echo "Warning: This script may not work on macOS 14 or later"
    echo "Current version: $os_version"
fi

2. Permission Issues

# Ensure script runs with proper privileges
if [ "$EUID" -ne 0 ]; then
    echo "Error: This script must be run as root"
    echo "Please use: sudo $0"
    exit 1
fi

3. File System Protection

# Check if System Integrity Protection affects operation
csrutil status | grep -q "enabled"
if [ $? -eq 0 ]; then
    echo "Note: SIP is enabled. This may affect script operation."
fi

Best Practices for Setup Assistant Management

  1. Version Compatibility: Always check macOS version compatibility before deployment
  2. User Communication: Notify users before triggering Setup Assistant
  3. Data Backup: Create backups before major configuration changes
  4. Testing: Test scripts in controlled environments before mass deployment
  5. Logging: Maintain detailed logs of all Setup Assistant operations
  6. Rollback Plans: Prepare rollback procedures for deployment failures

Enterprise Deployment Considerations

  • Scheduling: Plan deployments during maintenance windows
  • User Impact: Consider user workflows and minimize disruption
  • Network Requirements: Ensure adequate network connectivity for Apple services
  • Security: Implement appropriate security measures for automated deployments
  • Compliance: Ensure deployments meet organizational compliance requirements

Conclusion

Setup Assistant management is a powerful tool for macOS device administration. These scripts provide comprehensive solutions for triggering, managing, and automating Setup Assistant across Mac fleets. From simple single-device triggers to complex enterprise automation, these tools enable efficient device management while maintaining user experience and organizational compliance.

Remember to test all scripts thoroughly in controlled environments before production deployment, and always maintain proper backups of system configurations. Regular monitoring and logging ensure successful Setup Assistant deployments and help identify potential issues before they impact users.

Tutorial

Nuevas actualizaciones y mejoras para Macfleet.

Configurando un Runner de GitHub Actions en un Mac Mini (Apple Silicon)

Runner de GitHub Actions

GitHub Actions es una plataforma poderosa de CI/CD que te permite automatizar tus flujos de trabajo de desarrollo de software. Aunque GitHub ofrece runners hospedados, los runners auto-hospedados proporcionan mayor control y personalización para tu configuración de CI/CD. Este tutorial te guía a través de la configuración y conexión de un runner auto-hospedado en un Mac mini para ejecutar pipelines de macOS.

Prerrequisitos

Antes de comenzar, asegúrate de tener:

  • Un Mac mini (regístrate en Macfleet)
  • Un repositorio de GitHub con derechos de administrador
  • Un gestor de paquetes instalado (preferiblemente Homebrew)
  • Git instalado en tu sistema

Paso 1: Crear una Cuenta de Usuario Dedicada

Primero, crea una cuenta de usuario dedicada para el runner de GitHub Actions:

# Crear la cuenta de usuario 'gh-runner'
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Establecer la contraseña para el usuario
sudo dscl . -passwd /Users/gh-runner tu_contraseña

# Agregar 'gh-runner' al grupo 'admin'
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Cambia a la nueva cuenta de usuario:

su gh-runner

Paso 2: Instalar Software Requerido

Instala Git y Rosetta 2 (si usas Apple Silicon):

# Instalar Git si no está ya instalado
brew install git

# Instalar Rosetta 2 para Macs Apple Silicon
softwareupdate --install-rosetta

Paso 3: Configurar el Runner de GitHub Actions

  1. Ve a tu repositorio de GitHub
  2. Navega a Configuración > Actions > Runners

Runner de GitHub Actions

  1. Haz clic en "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Selecciona macOS como imagen del runner y ARM64 como arquitectura
  3. Sigue los comandos proporcionados para descargar y configurar el runner

Runner de GitHub Actions

Crea un archivo .env en el directorio _work del runner:

# archivo _work/.env
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Ejecuta el script run.sh en tu directorio del runner para completar la configuración.
  2. Verifica que el runner esté activo y escuchando trabajos en la terminal y revisa la configuración del repositorio de GitHub para la asociación del runner y el estado Idle.

Runner de GitHub Actions

Paso 4: Configurar Sudoers (Opcional)

Si tus acciones requieren privilegios de root, configura el archivo sudoers:

sudo visudo

Agrega la siguiente línea:

gh-runner ALL=(ALL) NOPASSWD: ALL

Paso 5: Usar el Runner en Flujos de Trabajo

Configura tu flujo de trabajo de GitHub Actions para usar el runner auto-hospedado:

name: Flujo de trabajo de muestra

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: Instalar NodeJS
        run: brew install node

El runner está autenticado en tu repositorio y etiquetado con self-hosted, macOS, y ARM64. Úsalo en tus flujos de trabajo especificando estas etiquetas en el campo runs-on:

runs-on: [self-hosted, macOS, ARM64]

Mejores Prácticas

  • Mantén tu software del runner actualizado
  • Monitorea regularmente los logs del runner para problemas
  • Usa etiquetas específicas para diferentes tipos de runners
  • Implementa medidas de seguridad apropiadas
  • Considera usar múltiples runners para balanceo de carga

Solución de Problemas

Problemas comunes y soluciones:

  1. Runner no conectando:

    • Verifica conectividad de red
    • Verifica validez del token de GitHub
    • Asegúrate de permisos apropiados
  2. Fallas de construcción:

    • Verifica instalación de Xcode
    • Verifica dependencias requeridas
    • Revisa logs del flujo de trabajo
  3. Problemas de permisos:

    • Verifica permisos de usuario
    • Verifica configuración de sudoers
    • Revisa permisos del sistema de archivos

Conclusión

Ahora tienes un runner auto-hospedado de GitHub Actions configurado en tu Mac mini. Esta configuración te proporciona más control sobre tu entorno de CI/CD y te permite ejecutar flujos de trabajo específicos de macOS de manera eficiente.

Recuerda mantener regularmente tu runner y mantenerlo actualizado con los últimos parches de seguridad y versiones de software.

Aplicación Nativa

Aplicación nativa de Macfleet

Guía de Instalación de Macfleet

Macfleet es una solución poderosa de gestión de flota diseñada específicamente para entornos de Mac Mini alojados en la nube. Como proveedor de hosting en la nube de Mac Mini, puedes usar Macfleet para monitorear, gestionar y optimizar toda tu flota de instancias Mac virtualizadas.

Esta guía de instalación te llevará a través de la configuración del monitoreo de Macfleet en sistemas macOS, Windows y Linux para asegurar una supervisión integral de tu infraestructura en la nube.

🍎 macOS

  • Descarga el archivo .dmg para Mac aquí
  • Haz doble clic en el archivo .dmg descargado
  • Arrastra la aplicación Macfleet a la carpeta Aplicaciones
  • Expulsa el archivo .dmg
  • Abre Preferencias del Sistema > Seguridad y Privacidad
    • Pestaña Privacidad > Accesibilidad
    • Marca Macfleet para permitir el monitoreo
  • Inicia Macfleet desde Aplicaciones
  • El seguimiento comienza automáticamente

🪟 Windows

  • Descarga el archivo .exe para Windows aquí
  • Haz clic derecho en el archivo .exe > "Ejecutar como administrador"
  • Sigue el asistente de instalación
  • Acepta los términos y condiciones
  • Permite en Windows Defender si se solicita
  • Concede permisos de monitoreo de aplicaciones
  • Inicia Macfleet desde el Menú Inicio
  • La aplicación comienza el seguimiento automáticamente

🐧 Linux

  • Descarga el paquete .deb (Ubuntu/Debian) o .rpm (CentOS/RHEL) aquí
  • Instala usando tu gestor de paquetes
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Permite permisos de acceso X11 si se solicita
  • Agrega el usuario a los grupos apropiados si es necesario
  • Inicia Macfleet desde el menú de Aplicaciones
  • La aplicación comienza el seguimiento automáticamente

Nota: Después de la instalación en todos los sistemas, inicia sesión con tus credenciales de Macfleet para sincronizar datos con tu panel de control.