Guide

Nouvelles mises à jour et améliorations de Roundfleet.

Avis important

Les exemples de code et scripts fournis dans ces tutoriels sont uniquement à des fins éducatives. Roundfleet n'est pas responsable des problèmes, dommages ou vulnérabilités de sécurité qui pourraient survenir lors de l'utilisation, modification ou implémentation de ces exemples. Toujours vérifier et tester le code dans un environnement sécurisé avant de l'utiliser dans des systèmes de production.

Gestion de Lancement Automatique d'Applications sur macOS

Optimisez la productivité d'entreprise en lançant automatiquement les applications essentielles à la connexion utilisateur sur vos appareils Roundfleet. Ce tutoriel couvre la configuration LaunchAgent, la gestion d'applications spécifiques aux utilisateurs, la validation de sécurité et les stratégies de déploiement centralisées.

Comprendre les Mécanismes de Lancement d'Applications macOS

macOS fournit plusieurs mécanismes pour le lancement automatique d'applications :

  • LaunchAgents - Applications spécifiques à l'utilisateur qui se lancent à la connexion
  • LaunchDaemons - Services système qui démarrent au boot
  • Éléments de Connexion - Applications configurées par l'utilisateur dans Préférences Système
  • Configurations MDM - Configurations de lancement gérées par l'entreprise

Lancement Automatique d'Application Basique

Configuration Simple de Lancement d'Application

#!/bin/bash

# Configuration basique de lancement d'application pour une seule application
APP_NAME="Messages"
PLIST_NAME="com.${APP_NAME}.plist"
LAUNCH_AGENTS_DIR="/Library/LaunchAgents"

# Créer le plist LaunchAgent
cat > "${LAUNCH_AGENTS_DIR}/${PLIST_NAME}" << 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>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>${PLIST_NAME}</string>
    <key>Program</key>
    <string>/System/Applications/${APP_NAME}.app/Contents/MacOS/${APP_NAME}</string>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF

echo "LaunchAgent créé pour ${APP_NAME}"

Lancement d'Application Amélioré avec Validation

#!/bin/bash

# Lancement d'application amélioré avec validation
setup_app_launch() {
    local app_name="$1"
    local app_path="$2"
    local plist_name="com.roundfleet.${app_name}.plist"
    
    echo "Configuration du lancement automatique pour : $app_name"
    
    # Valider que l'application existe
    if [[ ! -d "$app_path" ]]; then
        echo "Erreur : Application non trouvée à $app_path"
        return 1
    fi
    
    # Valider l'exécutable
    local executable_path="${app_path}/Contents/MacOS/${app_name}"
    if [[ ! -x "$executable_path" ]]; then
        echo "Erreur : Exécutable non trouvé ou non exécutable : $executable_path"
        return 1
    fi
    
    # Créer le LaunchAgent
    cat > "/Library/LaunchAgents/${plist_name}" << 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>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>${plist_name}</string>
    <key>Program</key>
    <string>${executable_path}</string>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/var/log/roundfleet_${app_name}.error.log</string>
    <key>StandardOutPath</key>
    <string>/var/log/roundfleet_${app_name}.out.log</string>
</dict>
</plist>
EOF

    echo "LaunchAgent configuré avec succès pour $app_name"
    return 0
}

# Exemple d'utilisation
setup_app_launch "Messages" "/System/Applications/Messages.app"

Gestion de Lancement d'Applications d'Entreprise

#!/bin/bash

# Gestion de Lancement d'Applications d'Entreprise Roundfleet
# Contrôle centralisé des lancements automatiques d'applications sur les appareils de flotte

# Configuration
LOG_FILE="/var/log/roundfleet_app_launch.log"
CONFIG_DIR="/etc/roundfleet/app_launch"
LAUNCH_AGENTS_DIR="/Library/LaunchAgents"
USER_LAUNCH_AGENTS_DIR="~/Library/LaunchAgents"
BACKUP_DIR="/var/backups/launch_agents"

# Base de données de configuration d'applications
declare -A ENTERPRISE_APPS=(
    ["suite_productivite"]="Slack,Microsoft Teams,Notion,1Password 7 - Password Manager"
    ["outils_developpement"]="Xcode,Terminal,Visual Studio Code,Docker Desktop"
    ["suite_design"]="Adobe Photoshop 2023,Sketch,Figma,Adobe Illustrator 2023"
    ["communication"]="Messages,Mail,Zoom,Microsoft Outlook"
    ["outils_securite"]="Little Snitch 5,1Password 7 - Password Manager,Malwarebytes Anti-Malware"
)

# Configurations de profils utilisateur
declare -A USER_PROFILES=(
    ["developpeur"]="outils_developpement,communication,outils_securite"
    ["designer"]="suite_design,communication,suite_productivite"
    ["manager"]="suite_productivite,communication"
    ["securite"]="outils_securite,communication,suite_productivite"
    ["defaut"]="communication"
)

# Fonction de journalisation
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Créer les répertoires nécessaires
setup_directories() {
    for dir in "$CONFIG_DIR" "$BACKUP_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Répertoire créé : $dir"
        fi
    done
}

# Valider le chemin et l'exécutable de l'application
validate_application() {
    local app_name="$1"
    local app_path=""
    
    log_action "Validation de l'application : $app_name"
    
    # Chemins d'applications communs à vérifier
    local search_paths=(
        "/Applications"
        "/System/Applications"
        "/Applications/Utilities"
        "/System/Applications/Utilities"
    )
    
    # Trouver l'application
    for base_path in "${search_paths[@]}"; do
        local potential_path="${base_path}/${app_name}.app"
        if [[ -d "$potential_path" ]]; then
            app_path="$potential_path"
            break
        fi
    done
    
    if [[ -z "$app_path" ]]; then
        log_action "❌ Application non trouvée : $app_name"
        return 1
    fi
    
    # Valider l'exécutable
    local executable_path="${app_path}/Contents/MacOS/${app_name}"
    if [[ ! -x "$executable_path" ]]; then
        # Essayer un nom d'exécutable alternatif (certaines apps utilisent des noms différents)
        local info_plist="${app_path}/Contents/Info.plist"
        if [[ -f "$info_plist" ]]; then
            local bundle_executable
            bundle_executable=$(defaults read "$info_plist" CFBundleExecutable 2>/dev/null)
            if [[ -n "$bundle_executable" ]]; then
                executable_path="${app_path}/Contents/MacOS/${bundle_executable}"
            fi
        fi
        
        if [[ ! -x "$executable_path" ]]; then
            log_action "❌ Exécutable non trouvé ou non exécutable : $executable_path"
            return 1
        fi
    fi
    
    log_action "✅ Application validée : $app_name à $app_path"
    echo "$app_path"
    return 0
}

# Créer le plist LaunchAgent pour l'application
create_launch_agent() {
    local app_name="$1"
    local app_path="$2"
    local user_specific="${3:-false}"
    local delay="${4:-0}"
    
    local plist_name="com.roundfleet.${app_name// /_}.plist"
    local target_dir="$LAUNCH_AGENTS_DIR"
    
    if [[ "$user_specific" == "true" ]]; then
        target_dir="$USER_LAUNCH_AGENTS_DIR"
    fi
    
    log_action "Création du LaunchAgent pour : $app_name"
    
    # Obtenir le chemin de l'exécutable
    local executable_path="${app_path}/Contents/MacOS/${app_name}"
    local info_plist="${app_path}/Contents/Info.plist"
    
    if [[ -f "$info_plist" ]]; then
        local bundle_executable
        bundle_executable=$(defaults read "$info_plist" CFBundleExecutable 2>/dev/null)
        if [[ -n "$bundle_executable" ]]; then
            executable_path="${app_path}/Contents/MacOS/${bundle_executable}"
        fi
    fi
    
    # Créer le contenu du plist
    cat > "${target_dir}/${plist_name}" << 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>${plist_name}</string>
    <key>Program</key>
    <string>${executable_path}</string>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>StandardErrorPath</key>
    <string>/var/log/roundfleet_$(echo "$app_name" | tr ' ' '_').error.log</string>
    <key>StandardOutPath</key>
    <string>/var/log/roundfleet_$(echo "$app_name" | tr ' ' '_').out.log</string>
EOF

    # Ajouter un délai si spécifié
    if [[ "$delay" -gt 0 ]]; then
        cat >> "${target_dir}/${plist_name}" << EOF
    <key>StartInterval</key>
    <integer>$delay</integer>
EOF
    fi
    
    # Ajouter des variables d'environnement pour les applications d'entreprise
    cat >> "${target_dir}/${plist_name}" << EOF
    <key>EnvironmentVariables</key>
    <dict>
        <key>ROUNDFLEET_MANAGED</key>
        <string>true</string>
        <key>ENTERPRISE_MODE</key>
        <string>enabled</string>
    </dict>
</dict>
</plist>
EOF

    # Définir les permissions appropriées
    chmod 644 "${target_dir}/${plist_name}"
    
    log_action "✅ LaunchAgent créé : ${plist_name}"
    return 0
}

# Supprimer le LaunchAgent pour l'application
remove_launch_agent() {
    local app_name="$1"
    local user_specific="${2:-false}"
    
    local plist_name="com.roundfleet.${app_name// /_}.plist"
    local target_dir="$LAUNCH_AGENTS_DIR"
    
    if [[ "$user_specific" == "true" ]]; then
        target_dir="$USER_LAUNCH_AGENTS_DIR"
    fi
    
    local plist_path="${target_dir}/${plist_name}"
    
    if [[ -f "$plist_path" ]]; then
        # Décharger si chargé
        launchctl unload "$plist_path" 2>/dev/null || true
        
        # Supprimer le fichier
        rm -f "$plist_path"
        log_action "✅ LaunchAgent supprimé : $plist_name"
        return 0
    else
        log_action "⚠️  LaunchAgent non trouvé : $plist_name"
        return 1
    fi
}

# Déployer les applications pour le profil utilisateur
deploy_user_profile() {
    local profile_name="$1"
    local username="${2:-$(whoami)}"
    
    log_action "Déploiement du profil utilisateur : $profile_name pour l'utilisateur : $username"
    
    # Obtenir la configuration du profil
    local profile_config="${USER_PROFILES[$profile_name]}"
    if [[ -z "$profile_config" ]]; then
        log_action "❌ Profil utilisateur inconnu : $profile_name"
        return 1
    fi
    
    # Sauvegarder la configuration existante
    backup_launch_agents
    
    local success_count=0
    local total_count=0
    local failed_apps=()
    
    # Traiter chaque suite d'applications dans le profil
    IFS=',' read -ra SUITES <<< "$profile_config"
    for suite in "${SUITES[@]}"; do
        local suite_apps="${ENTERPRISE_APPS[$suite]}"
        if [[ -z "$suite_apps" ]]; then
            log_action "⚠️  Suite d'applications inconnue : $suite"
            continue
        fi
        
        # Traiter chaque application dans la suite
        IFS=',' read -ra APPS <<< "$suite_apps"
        for app in "${APPS[@]}"; do
            total_count=$((total_count + 1))
            
            # Valider et déployer l'application
            local app_path
            if app_path=$(validate_application "$app"); then
                if create_launch_agent "$app" "$app_path" false 0; then
                    success_count=$((success_count + 1))
                    log_action "✅ Déployé : $app"
                else
                    failed_apps+=("$app")
                fi
            else
                failed_apps+=("$app")
            fi
        done
    done
    
    # Générer le rapport de déploiement
    generate_deployment_report "$profile_name" "$username" "$success_count" "$total_count" "${failed_apps[@]}"
    
    log_action "Déploiement de profil terminé : $success_count/$total_count réussi"
    return $((total_count - success_count))
}

# Sauvegarder les LaunchAgents existants
backup_launch_agents() {
    local backup_timestamp
    backup_timestamp=$(date '+%Y%m%d_%H%M%S')
    local backup_file="$BACKUP_DIR/launch_agents_backup_$backup_timestamp.tar.gz"
    
    log_action "Création de la sauvegarde LaunchAgents : $backup_file"
    
    if tar -czf "$backup_file" -C /Library LaunchAgents 2>/dev/null; then
        log_action "✅ Sauvegarde créée : $backup_file"
        return 0
    else
        log_action "❌ Échec de la sauvegarde"
        return 1
    fi
}

# Générer le rapport de déploiement
generate_deployment_report() {
    local profile_name="$1"
    local username="$2"
    local success_count="$3"
    local total_count="$4"
    shift 4
    local failed_apps=("$@")
    
    local report_file="$CONFIG_DIR/deployment_report_$(date '+%Y%m%d_%H%M%S').json"
    
    log_action "Génération du rapport de déploiement : $report_file"
    
    cat > "$report_file" << EOF
{
    "deployment_metadata": {
        "timestamp": "$(date -Iseconds)",
        "profile_name": "$profile_name",
        "username": "$username",
        "hostname": "$(hostname)",
        "generator": "Roundfleet App Launch Manager"
    },
    "deployment_summary": {
        "total_applications": $total_count,
        "successful_deployments": $success_count,
        "failed_deployments": $((total_count - success_count)),
        "success_rate": $(awk "BEGIN {printf \"%.2f\", ($success_count/$total_count)*100}")
    },
    "failed_applications": [
EOF

    # Ajouter les applications échouées
    local first=true
    for app in "${failed_apps[@]}"; do
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$report_file"
        fi
        echo "        \"$app\"" >> "$report_file"
    done
    
    cat >> "$report_file" << EOF
    ],
    "system_info": {
        "os_version": "$(sw_vers -productVersion)",
        "build_version": "$(sw_vers -buildVersion)",
        "serial_number": "$(system_profiler SPHardwareDataType | grep 'Serial Number' | awk '{print $4}')"
    }
}
EOF

    log_action "✅ Rapport de déploiement généré : $report_file"
    echo "$report_file"
}

# Lister tous les LaunchAgents configurés
list_configured_apps() {
    log_action "Liste des applications de lancement automatique configurées"
    
    echo "=== LaunchAgents Gérés par Roundfleet ==="
    
    local agent_count=0
    for plist_file in "$LAUNCH_AGENTS_DIR"/com.roundfleet.*.plist; do
        if [[ -f "$plist_file" ]]; then
            local label
            local program
            label=$(defaults read "$plist_file" Label 2>/dev/null || echo "Inconnu")
            program=$(defaults read "$plist_file" Program 2>/dev/null || echo "Inconnu")
            
            echo "Étiquette : $label"
            echo "Programme : $program"
            echo "Fichier : $plist_file"
            echo "---"
            
            agent_count=$((agent_count + 1))
        fi
    done
    
    echo "Total des LaunchAgents gérés : $agent_count"
}

# Valider toutes les applications configurées
validate_all_apps() {
    log_action "Validation de toutes les applications configurées"
    
    local validation_report="$CONFIG_DIR/validation_report_$(date '+%Y%m%d_%H%M%S').json"
    local valid_count=0
    local invalid_count=0
    local invalid_apps=()
    
    cat > "$validation_report" << EOF
{
    "validation_timestamp": "$(date -Iseconds)",
    "hostname": "$(hostname)",
    "validation_results": [
EOF

    local first=true
    for plist_file in "$LAUNCH_AGENTS_DIR"/com.roundfleet.*.plist; do
        if [[ -f "$plist_file" ]]; then
            if [[ "$first" == true ]]; then
                first=false
            else
                echo "," >> "$validation_report"
            fi
            
            local label
            local program
            local exists="false"
            local executable="false"
            
            label=$(defaults read "$plist_file" Label 2>/dev/null || echo "Inconnu")
            program=$(defaults read "$plist_file" Program 2>/dev/null || echo "Inconnu")
            
            if [[ -f "$program" ]]; then
                exists="true"
                if [[ -x "$program" ]]; then
                    executable="true"
                    valid_count=$((valid_count + 1))
                else
                    invalid_count=$((invalid_count + 1))
                    invalid_apps+=("$label")
                fi
            else
                invalid_count=$((invalid_count + 1))
                invalid_apps+=("$label")
            fi
            
            cat >> "$validation_report" << EOF
        {
            "label": "$label",
            "program": "$program",
            "file_exists": $exists,
            "executable": $executable,
            "valid": $([ "$exists" = "true" ] && [ "$executable" = "true" ] && echo "true" || echo "false")
        }
EOF
        fi
    done
    
    cat >> "$validation_report" << EOF
    ],
    "validation_summary": {
        "total_agents": $((valid_count + invalid_count)),
        "valid_agents": $valid_count,
        "invalid_agents": $invalid_count
    }
}
EOF

    log_action "✅ Validation terminée : $valid_count valides, $invalid_count invalides"
    log_action "Rapport de validation : $validation_report"
    
    if [[ $invalid_count -gt 0 ]]; then
        log_action "Applications invalides trouvées : ${invalid_apps[*]}"
    fi
    
    echo "$validation_report"
}

# Nettoyer les LaunchAgents invalides ou orphelins
cleanup_launch_agents() {
    log_action "Nettoyage des LaunchAgents invalides"
    
    local cleanup_count=0
    local cleanup_report="$CONFIG_DIR/cleanup_report_$(date '+%Y%m%d_%H%M%S').txt"
    
    echo "Rapport de Nettoyage LaunchAgent Roundfleet" > "$cleanup_report"
    echo "Généré : $(date)" >> "$cleanup_report"
    echo "======================================" >> "$cleanup_report"
    
    for plist_file in "$LAUNCH_AGENTS_DIR"/com.roundfleet.*.plist; do
        if [[ -f "$plist_file" ]]; then
            local program
            program=$(defaults read "$plist_file" Program 2>/dev/null || echo "")
            
            if [[ -n "$program" ]] && [[ ! -x "$program" ]]; then
                local label
                label=$(defaults read "$plist_file" Label 2>/dev/null || echo "Inconnu")
                
                log_action "Suppression du LaunchAgent invalide : $label"
                echo "Supprimé : $label ($program non trouvé/exécutable)" >> "$cleanup_report"
                
                # Décharger si chargé
                launchctl unload "$plist_file" 2>/dev/null || true
                
                # Supprimer le fichier
                rm -f "$plist_file"
                cleanup_count=$((cleanup_count + 1))
            fi
        fi
    done
    
    echo "Total nettoyé : $cleanup_count" >> "$cleanup_report"
    log_action "✅ Nettoyage terminé : $cleanup_count agents supprimés"
    echo "$cleanup_report"
}

# Tester le lancement d'application
test_app_launch() {
    local app_name="$1"
    local plist_name="com.roundfleet.${app_name// /_}.plist"
    local plist_path="$LAUNCH_AGENTS_DIR/$plist_name"
    
    if [[ ! -f "$plist_path" ]]; then
        log_action "❌ LaunchAgent non trouvé : $plist_name"
        return 1
    fi
    
    log_action "Test du lancement d'application : $app_name"
    
    # Charger le LaunchAgent
    if launchctl load "$plist_path" 2>/dev/null; then
        log_action "✅ LaunchAgent chargé avec succès"
        
        # Attendre un moment et vérifier si le processus fonctionne
        sleep 2
        if pgrep -f "$app_name" >/dev/null; then
            log_action "✅ L'application fonctionne : $app_name"
            return 0
        else
            log_action "⚠️  L'application n'a peut-être pas démarré correctement"
            return 1
        fi
    else
        log_action "❌ Échec du chargement du LaunchAgent"
        return 1
    fi
}

# Fonction d'exécution principale
main() {
    local action="${1:-list}"
    local profile_name="$2"
    local username="$3"
    
    log_action "=== Démarrage de la Gestion de Lancement d'Applications Roundfleet ==="
    log_action "Action : $action"
    log_action "Profil : ${profile_name:-N/A}"
    log_action "Utilisateur : ${username:-$(whoami)}"
    
    # Configuration
    setup_directories
    
    case "$action" in
        "deploy")
            if [[ -z "$profile_name" ]]; then
                echo "Profils disponibles :"
                for profile in "${!USER_PROFILES[@]}"; do
                    echo "  - $profile : ${USER_PROFILES[$profile]}"
                done
                echo ""
                echo "Usage : $0 deploy <nom_profil> [nom_utilisateur]"
                exit 1
            fi
            deploy_user_profile "$profile_name" "$username"
            ;;
        "list")
            list_configured_apps
            ;;
        "validate")
            validate_all_apps
            ;;
        "cleanup")
            cleanup_launch_agents
            ;;
        "test")
            if [[ -z "$profile_name" ]]; then
                echo "Usage : $0 test <nom_app>"
                exit 1
            fi
            test_app_launch "$profile_name"
            ;;
        "remove")
            if [[ -z "$profile_name" ]]; then
                echo "Usage : $0 remove <nom_app>"
                exit 1
            fi
            remove_launch_agent "$profile_name"
            ;;
        "backup")
            backup_launch_agents
            ;;
        *)
            echo "Usage : $0 {deploy|list|validate|cleanup|test|remove|backup}"
            echo "  deploy   - Déployer les applications de profil utilisateur"
            echo "  list     - Lister les LaunchAgents configurés"
            echo "  validate - Valider toutes les applications configurées"
            echo "  cleanup  - Supprimer les LaunchAgents invalides"
            echo "  test     - Tester le lancement d'application spécifique"
            echo "  remove   - Supprimer un LaunchAgent spécifique"
            echo "  backup   - Sauvegarder les LaunchAgents actuels"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion de lancement d'applications terminée ==="
}

# Exécuter la fonction principale
main "$@"

Configuration LaunchAgent Avancée

Lancement d'Application Conditionnel

#!/bin/bash

# Créer un LaunchAgent conditionnel basé sur l'état du système
create_conditional_launch_agent() {
    local app_name="$1"
    local app_path="$2"
    local condition="$3"  # network, power, time
    
    local plist_name="com.roundfleet.conditional.${app_name// /_}.plist"
    
    cat > "/Library/LaunchAgents/${plist_name}" << 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>${plist_name}</string>
    <key>Program</key>
    <string>${app_path}/Contents/MacOS/${app_name}</string>
    <key>RunAtLoad</key>
    <true/>
EOF

    case "$condition" in
        "network")
            cat >> "/Library/LaunchAgents/${plist_name}" << EOF
    <key>KeepAlive</key>
    <dict>
        <key>NetworkState</key>
        <true/>
    </dict>
EOF
            ;;
        "power")
            cat >> "/Library/LaunchAgents/${plist_name}" << EOF
    <key>KeepAlive</key>
    <dict>
        <key>PowerManagement</key>
        <true/>
    </dict>
EOF
            ;;
        "time")
            cat >> "/Library/LaunchAgents/${plist_name}" << EOF
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>9</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
EOF
            ;;
    esac
    
    cat >> "/Library/LaunchAgents/${plist_name}" << EOF
</dict>
</plist>
EOF

    echo "LaunchAgent conditionnel créé : $plist_name"
}

Lancement d'Application Conscient des Ressources

#!/bin/bash

# Créer un LaunchAgent conscient des ressources avec limitation
create_resource_aware_agent() {
    local app_name="$1"
    local app_path="$2"
    local cpu_limit="$3"    # pourcentage
    local memory_limit="$4" # MB
    
    local plist_name="com.roundfleet.resource.${app_name// /_}.plist"
    
    cat > "/Library/LaunchAgents/${plist_name}" << 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>${plist_name}</string>
    <key>Program</key>
    <string>${app_path}/Contents/MacOS/${app_name}</string>
    <key>RunAtLoad</key>
    <true/>
    <key>ThrottleInterval</key>
    <integer>60</integer>
    <key>SoftResourceLimits</key>
    <dict>
        <key>CPU</key>
        <integer>$cpu_limit</integer>
        <key>Mem</key>
        <integer>$((memory_limit * 1024 * 1024))</integer>
    </dict>
    <key>HardResourceLimits</key>
    <dict>
        <key>CPU</key>
        <integer>$((cpu_limit + 10))</integer>
        <key>Mem</key>
        <integer>$((memory_limit * 1024 * 1024 * 2))</integer>
    </dict>
</dict>
</plist>
EOF

    echo "LaunchAgent conscient des ressources créé : $plist_name"
}

Gestion de Profils Utilisateur

Attribution Dynamique de Profil

#!/bin/bash

# Attribuer un profil basé sur les attributs utilisateur
assign_user_profile() {
    local username="$1"
    
    # Obtenir les informations utilisateur
    local user_groups
    user_groups=$(groups "$username" 2>/dev/null)
    
    # Déterminer le profil basé sur l'appartenance au groupe
    if [[ "$user_groups" =~ developer|engineering ]]; then
        echo "developpeur"
    elif [[ "$user_groups" =~ design|creative ]]; then
        echo "designer"
    elif [[ "$user_groups" =~ manager|executive ]]; then
        echo "manager"
    elif [[ "$user_groups" =~ security|admin ]]; then
        echo "securite"
    else
        echo "defaut"
    fi
}

# Auto-configurer l'utilisateur à la première connexion
auto_configure_user() {
    local username="$(whoami)"
    local assigned_profile
    assigned_profile=$(assign_user_profile "$username")
    
    echo "Auto-configuration de l'utilisateur : $username"
    echo "Profil attribué : $assigned_profile"
    
    # Déployer le profil
    deploy_user_profile "$assigned_profile" "$username"
}

Modèles de Profil

#!/bin/bash

# Créer un modèle de profil personnalisé
create_profile_template() {
    local template_name="$1"
    local template_file="$CONFIG_DIR/profiles/${template_name}.json"
    
    mkdir -p "$(dirname "$template_file")"
    
    cat > "$template_file" << EOF
{
    "profile_name": "$template_name",
    "description": "Modèle de profil personnalisé",
    "applications": [
        {
            "name": "Nom de l'Application",
            "path": "/Applications/App.app",
            "required": true,
            "delay": 0,
            "conditions": []
        }
    ],
    "settings": {
        "auto_update": true,
        "notifications": true,
        "logging": true
    }
}
EOF

    echo "Modèle de profil créé : $template_file"
}

Sécurité et Validation

Vérification de Sécurité d'Application

#!/bin/bash

# Vérifier la sécurité de l'application avant le lancement
verify_app_security() {
    local app_path="$1"
    
    echo "=== Vérification de Sécurité d'Application ==="
    
    # Vérifier la signature de code
    if codesign -v "$app_path" 2>/dev/null; then
        echo "✅ Signature de code valide"
    else
        echo "❌ Signature de code invalide ou manquante"
        return 1
    fi
    
    # Vérifier la notarisation
    if spctl -a -v "$app_path" 2>/dev/null | grep -q "accepted"; then
        echo "✅ Application notarisée"
    else
        echo "⚠️  Application non notarisée"
    fi
    
    # Vérifier les attributs de quarantaine
    if xattr -l "$app_path" | grep -q "com.apple.quarantine"; then
        echo "⚠️  L'application a des attributs de quarantaine"
    else
        echo "✅ Pas d'attributs de quarantaine"
    fi
    
    # Vérifier les caractéristiques suspectes
    local info_plist="${app_path}/Contents/Info.plist"
    if [[ -f "$info_plist" ]]; then
        local bundle_id
        bundle_id=$(defaults read "$info_plist" CFBundleIdentifier 2>/dev/null)
        echo "Bundle ID : $bundle_id"
        
        # Vérifier les identifiants de bundle suspects
        if [[ "$bundle_id" =~ (malware|hack|crack) ]]; then
            echo "❌ Identifiant de bundle suspect détecté"
            return 1
        fi
    fi
    
    echo "✅ Vérification de sécurité terminée"
    return 0
}

Vérifications de Conformité d'Entreprise

#!/bin/bash

# Vérifier les exigences de conformité d'entreprise
check_enterprise_compliance() {
    local app_path="$1"
    
    echo "=== Vérification de Conformité d'Entreprise ==="
    
    # Vérifier si l'application est dans la liste approuvée
    local approved_apps_file="/etc/roundfleet/approved_apps.txt"
    if [[ -f "$approved_apps_file" ]]; then
        local app_name
        app_name=$(basename "$app_path" .app)
        
        if grep -q "^$app_name$" "$approved_apps_file"; then
            echo "✅ L'application est dans la liste approuvée"
        else
            echo "❌ L'application n'est pas dans la liste approuvée"
            return 1
        fi
    fi
    
    # Vérifier les certificats d'entreprise
    local cert_info
    cert_info=$(codesign -dv "$app_path" 2>&1)
    
    if echo "$cert_info" | grep -q "Developer ID\|Mac App Store"; then
        echo "✅ Certificat développeur valide"
    else
        echo "⚠️  Pas de certificat développeur valide"
    fi
    
    return 0
}

Surveillance et Maintenance

Surveillance du Succès de Lancement

#!/bin/bash

# Surveiller le succès de lancement d'applications
monitor_launch_success() {
    local monitoring_log="/var/log/roundfleet_launch_monitoring.log"
    
    echo "=== Surveillance du Succès de Lancement ===" | tee -a "$monitoring_log"
    echo "Horodatage : $(date)" | tee -a "$monitoring_log"
    
    # Vérifier chaque LaunchAgent configuré
    for plist_file in "$LAUNCH_AGENTS_DIR"/com.roundfleet.*.plist; do
        if [[ -f "$plist_file" ]]; then
            local label
            local program
            label=$(defaults read "$plist_file" Label 2>/dev/null)
            program=$(defaults read "$plist_file" Program 2>/dev/null)
            
            # Vérifier si l'application fonctionne
            local app_name
            app_name=$(basename "$program")
            
            if pgrep -f "$app_name" >/dev/null; then
                echo "✅ $label : En cours d'exécution" | tee -a "$monitoring_log"
            else
                echo "❌ $label : Pas en cours d'exécution" | tee -a "$monitoring_log"
                
                # Essayer de redémarrer
                launchctl unload "$plist_file" 2>/dev/null
                launchctl load "$plist_file" 2>/dev/null
                echo "🔄 Tentative de redémarrage pour $label" | tee -a "$monitoring_log"
            fi
        fi
    done
}

Maintenance Automatisée

#!/bin/bash

# Configurer la planification de maintenance automatisée
setup_maintenance_schedule() {
    local maintenance_script="/usr/local/bin/roundfleet_app_maintenance.sh"
    local launchd_plist="/Library/LaunchDaemons/com.roundfleet.app.maintenance.plist"
    
    # Créer le script de maintenance
    cat > "$maintenance_script" << 'EOF'
#!/bin/bash
LOG_FILE="/var/log/roundfleet_app_maintenance.log"
exec > >(tee -a "$LOG_FILE") 2>&1

echo "$(date): Démarrage de la maintenance d'applications"

# Valider toutes les applications
/usr/local/bin/roundfleet_app_manager.sh validate

# Surveiller le succès de lancement
monitor_launch_success

# Nettoyer les agents invalides
/usr/local/bin/roundfleet_app_manager.sh cleanup

echo "$(date): Maintenance d'applications terminée"
EOF

    chmod +x "$maintenance_script"
    
    # Créer le LaunchDaemon pour la maintenance programmée
    cat > "$launchd_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.roundfleet.app.maintenance</string>
    <key>ProgramArguments</key>
    <array>
        <string>$maintenance_script</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>2</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>
EOF

    # Charger le LaunchDaemon
    sudo launchctl load "$launchd_plist"
    
    echo "Maintenance automatisée configurée"
    echo "Script : $maintenance_script"
    echo "Planification : Quotidien à 2h00"
}

Meilleures Pratiques

🚀 Optimisation des Performances

  • Échelonnez les lancements d'applications pour éviter la contention de ressources
  • Utilisez des limites de ressources pour éviter la surcharge du système
  • Surveillez le succès de lancement et implémentez le redémarrage automatique
  • Validez les applications avant le déploiement

🔐 Directives de Sécurité

  • Vérifiez les signatures de code avant d'autoriser le lancement automatique
  • Maintenez des listes d'applications approuvées pour la conformité d'entreprise
  • Utilisez des chemins sécurisés et évitez les emplacements accessibles en écriture par l'utilisateur
  • Audits de sécurité réguliers des applications configurées

📋 Meilleures Pratiques de Gestion

  • Déploiement basé sur les profils pour différents types d'utilisateurs
  • Gestion de configuration centralisée
  • Sauvegarde régulière des configurations LaunchAgent
  • Surveillance et maintenance automatisées

🔍 Conseils de Dépannage

  • Vérifiez les chemins d'applications et les exécutables
  • Vérifiez la syntaxe LaunchAgent en utilisant plutil
  • Surveillez les journaux système pour les erreurs de lancement
  • Testez les configurations avant le déploiement de flotte

Notes Importantes

  • Les LaunchAgents fonctionnent par utilisateur tandis que les LaunchDaemons fonctionnent à l'échelle du système
  • Les applications doivent être correctement signées pour le déploiement d'entreprise
  • Les limites de ressources aident à prévenir les problèmes de performance du système
  • La validation régulière assure le fonctionnement continu
  • Sauvegardez les configurations avant de faire des changements

Related Tutorials

Gestion Entreprise du Lancement d'Applications pour macOS

Gérez le lancement d'applications macOS sur les appareils Roundfleet avec le déploiement automatisé d'apps, la validation de sécurité, l'exécution à distance et la gestion complète du cycle de vie des applications pour les opérations d'entreprise.

7 juil. 2025

Gestion Navigateur Safari sur macOS

Apprenez à configurer la page d'accueil Safari, paramètres navigateur, politiques sécurité et déployer la gestion navigateur entreprise sur vos appareils Roundfleet avec gestion utilisateur complète et fonctionnalités conformité.

7 juil. 2025

Gestion Rosetta 2 et Compatibilité Apple Silicon sur macOS

Apprenez à installer, gérer et surveiller la couche traduction Rosetta 2 sur Mac Apple Silicon avec gestion compatibilité niveau entreprise, surveillance applications et capacités déploiement flotte.

7 juil. 2025

Gestion de Paquets d'Entreprise avec Homebrew sur macOS

Déployez, gérez et maintenez les paquets logiciels sur les appareils macOS en utilisant Homebrew avec une gestion de configuration d'entreprise, un suivi de conformité et des flux de déploiement automatisés.

7 juil. 2025

Gérer les extensions de noyau sur macOS

Apprenez à afficher, charger, décharger et surveiller les extensions de noyau (kexts) sur les appareils macOS via des scripts en ligne de commande pour une gestion système et sécurité améliorées.

7 juil. 2025

Désactiver les Mises à Jour Automatiques de macOS

Apprenez à désactiver le téléchargement et l'installation automatiques des mises à jour macOS avec des scripts shell pour les environnements d'entreprise.

7 juil. 2025

Vérifier la Signature de Code d'App sur macOS

Vérifiez les signatures de code des applications sur Mac pour s'assurer de l'authenticité et détecter les altérations en utilisant les commandes codesign.

7 juil. 2025

Afficher l'heure de dernière ouverture des applications et fichiers sur macOS

Apprenez à suivre quand les applications et fichiers ont été accédés pour la dernière fois sur les appareils macOS en utilisant des scripts shell avancés pour une surveillance complète du parc.

7 juil. 2025