Guide

Nouvelles mises à jour et améliorations de Macfleet.

Sécurité de Verrouillage d'Écran d'Entreprise sur macOS

Implémentez des politiques de sécurité de verrouillage d'écran complètes sur vos appareils MacFleet en utilisant l'automatisation AppleScript et des configurations de sécurité avancées. Ce tutoriel couvre l'application de mots de passe, la gestion de la sécurité de veille et les mécanismes de verrouillage de niveau entreprise.

Comprendre la Sécurité de Verrouillage d'Écran macOS

macOS fournit plusieurs couches de sécurité de verrouillage d'écran :

  • Mot de passe d'économiseur d'écran - Exige un mot de passe lors du retour de l'économiseur d'écran
  • Mot de passe de veille - Exige un mot de passe lors du réveil du mode veille
  • Verrouillage immédiat - Définit le délai d'exigence de mot de passe sur immédiat
  • Préférences de sécurité - Gestion de la configuration de sécurité au niveau système

Configuration de Base du Verrouillage d'Écran

Activer le Mot de Passe pour le Verrouillage d'Écran

#!/bin/bash

# Activation de base du mot de passe de verrouillage d'écran
enable_screen_lock_password() {
    echo "=== Activation du Mot de Passe de Verrouillage d'Écran ==="
    
    # Activer l'exigence de mot de passe pour le verrouillage d'écran avec AppleScript
    if osascript -e 'tell application "System Events" to set require password to wake of security preferences to true'; then
        echo "✅ Mot de passe de verrouillage d'écran activé avec succès"
        
        # Vérifier le paramètre
        local current_setting=$(osascript -e 'tell application "System Events" to get require password to wake of security preferences')
        if [[ "$current_setting" == "true" ]]; then
            echo "✅ Exigence de mot de passe vérifiée : activée"
        else
            echo "⚠️  Échec de vérification de l'exigence de mot de passe"
        fi
    else
        echo "❌ Échec d'activation du mot de passe de verrouillage d'écran"
        return 1
    fi
}

enable_screen_lock_password

Vérifier le Statut Actuel du Verrouillage d'Écran

#!/bin/bash

# Vérifier le statut actuel du mot de passe de verrouillage d'écran
check_screen_lock_status() {
    echo "=== Vérification du Statut de Verrouillage d'Écran ==="
    
    # Obtenir le statut actuel d'exigence de mot de passe
    local password_required=$(osascript -e 'tell application "System Events" to get require password to wake of security preferences' 2>/dev/null)
    
    if [[ "$password_required" == "true" ]]; then
        echo "✅ Mot de passe de verrouillage d'écran : ACTIVÉ"
    elif [[ "$password_required" == "false" ]]; then
        echo "❌ Mot de passe de verrouillage d'écran : DÉSACTIVÉ"
    else
        echo "⚠️  Statut du mot de passe de verrouillage d'écran : INCONNU"
    fi
    
    # Obtenir les paramètres de délai d'économiseur d'écran
    local saver_timeout=$(defaults read com.apple.screensaver idleTime 2>/dev/null || echo "Inconnu")
    echo "Délai d'économiseur d'écran : $saver_timeout secondes"
    
    # Obtenir le délai de veille d'affichage
    local display_sleep=$(pmset -g | grep displaysleep | awk '{print $2}')
    echo "Délai de veille d'affichage : $display_sleep minutes"
    
    # Obtenir le délai de veille système
    local system_sleep=$(pmset -g | grep sleep | grep -v displaysleep | awk '{print $2}')
    echo "Délai de veille système : $system_sleep minutes"
}

check_screen_lock_status

Configuration de Sécurité Avancée

Configuration Complète de Verrouillage d'Écran

#!/bin/bash

# Configuration de sécurité de verrouillage d'écran avancée
configure_advanced_screen_lock() {
    local timeout_minutes="${1:-5}"
    local grace_period="${2:-0}"
    
    echo "=== Configuration Avancée de Verrouillage d'Écran ==="
    echo "Délai : $timeout_minutes minutes"
    echo "Période de grâce : $grace_period secondes"
    
    # Activer l'exigence de mot de passe pour le verrouillage d'écran
    echo "Activation de l'exigence de mot de passe..."
    if osascript -e 'tell application "System Events" to set require password to wake of security preferences to true'; then
        echo "✅ Exigence de mot de passe activée"
    else
        echo "❌ Échec d'activation de l'exigence de mot de passe"
        return 1
    fi
    
    # Définir le délai de mot de passe (période de grâce)
    echo "Définition du délai de mot de passe..."
    if osascript -e "tell application \"System Events\" to set delay interval of security preferences to $grace_period"; then
        echo "✅ Délai de mot de passe défini à $grace_period secondes"
    else
        echo "⚠️  Le paramétrage du délai de mot de passe peut avoir échoué"
    fi
    
    # Configurer le délai d'économiseur d'écran
    echo "Configuration du délai d'économiseur d'écran..."
    local timeout_seconds=$((timeout_minutes * 60))
    defaults write com.apple.screensaver idleTime -int $timeout_seconds
    
    # Activer le mot de passe d'économiseur d'écran immédiatement
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int $grace_period
    
    # Configurer les paramètres de veille système
    echo "Configuration de la gestion d'énergie..."
    sudo pmset -a displaysleep $timeout_minutes
    sudo pmset -a sleep $((timeout_minutes + 5))
    
    # Appliquer les coins actifs pour le verrouillage immédiat (optionnel)
    configure_hot_corners
    
    echo "✅ Configuration avancée de verrouillage d'écran terminée"
}

# Configurer les coins actifs pour la sécurité
configure_hot_corners() {
    echo "Configuration des coins actifs de sécurité..."
    
    # Coin inférieur droit : Démarrer l'économiseur d'écran
    defaults write com.apple.dock wvous-br-corner -int 5
    defaults write com.apple.dock wvous-br-modifier -int 0
    
    # Coin supérieur droit : Mettre l'affichage en veille
    defaults write com.apple.dock wvous-tr-corner -int 10
    defaults write com.apple.dock wvous-tr-modifier -int 0
    
    # Redémarrer le Dock pour appliquer les changements
    killall Dock
    
    echo "✅ Coins actifs configurés pour une sécurité renforcée"
}

# Usage : configure_advanced_screen_lock 3 0
configure_advanced_screen_lock

Application des Politiques de Sécurité

#!/bin/bash

# Appliquer les politiques de sécurité d'entreprise
enforce_security_policies() {
    echo "=== Application des Politiques de Sécurité ==="
    
    # Désactiver la connexion automatique
    echo "Désactivation de la connexion automatique..."
    sudo defaults delete /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null || true
    
    # Activer le menu de commutation utilisateur rapide
    echo "Configuration de la commutation utilisateur..."
    sudo defaults write /Library/Preferences/.GlobalPreferences MultipleSessionEnabled -bool YES
    defaults write .GlobalPreferences userMenuExtraStyle -int 2
    
    # Désactiver le compte invité
    echo "Désactivation du compte invité..."
    sudo defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled -bool NO
    
    # Définir la fenêtre de connexion pour afficher les champs nom et mot de passe
    sudo defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME -bool YES
    
    # Masquer les utilisateurs administrateurs de la fenêtre de connexion
    sudo defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool YES
    
    # Désactiver les indices de mot de passe
    sudo defaults write /Library/Preferences/com.apple.loginwindow RetriesUntilHint -int 0
    
    # Activer la mémoire virtuelle sécurisée
    sudo defaults write /Library/Preferences/com.apple.virtualMemory UseEncryptedSwap -bool YES
    
    echo "✅ Politiques de sécurité appliquées"
}

enforce_security_policies

Gestion de l'Économiseur d'Écran et du Verrouillage

Configuration de l'Économiseur d'Écran

#!/bin/bash

# Configurer l'économiseur d'écran avec les paramètres de sécurité
configure_secure_screensaver() {
    local module_name="${1:-Flurry}"
    local timeout_minutes="${2:-5}"
    
    echo "=== Configuration d'Économiseur d'Écran Sécurisé ==="
    echo "Module : $module_name"
    echo "Délai : $timeout_minutes minutes"
    
    # Définir le module d'économiseur d'écran
    defaults -currentHost write com.apple.screensaver moduleDict -dict \
        moduleName "$module_name" \
        path "/System/Library/Screen Savers/$module_name.saver" \
        type 0
    
    # Définir le délai
    local timeout_seconds=$((timeout_minutes * 60))
    defaults write com.apple.screensaver idleTime -int $timeout_seconds
    
    # Activer le mot de passe immédiatement
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int 0
    
    # Désactiver l'aperçu de l'économiseur d'écran
    defaults write com.apple.screensaver showClock -bool NO
    
    # Définir un message sur l'écran de verrouillage (optionnel)
    set_lock_screen_message
    
    echo "✅ Économiseur d'écran sécurisé configuré"
}

# Définir un message d'écran de verrouillage personnalisé
set_lock_screen_message() {
    local message="${1:-Cet appareil est géré par MacFleet. L'accès non autorisé est interdit.}"
    
    echo "Définition du message d'écran de verrouillage..."
    defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$message"
    
    echo "✅ Message d'écran de verrouillage défini"
}

# Usage : configure_secure_screensaver "Flurry" 3
configure_secure_screensaver

Mécanismes de Verrouillage Manuel

#!/bin/bash

# Mécanismes de verrouillage immédiat
immediate_lock_functions() {
    echo "=== Mécanismes de Verrouillage Immédiat ==="
    
    # Méthode 1 : Utiliser pmset pour mettre l'affichage en veille
    lock_display_pmset() {
        echo "Verrouillage de l'affichage avec pmset..."
        pmset displaysleepnow
    }
    
    # Méthode 2 : Utiliser osascript pour activer l'économiseur d'écran
    lock_screensaver() {
        echo "Activation du verrouillage d'économiseur d'écran..."
        osascript -e 'tell application "System Events" to start current screen saver'
    }
    
    # Méthode 3 : Utiliser CGSession pour la commutation utilisateur rapide
    lock_fast_user_switch() {
        echo "Basculement vers la fenêtre de connexion..."
        /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend
    }
    
    # Méthode 4 : Utiliser la commande open avec l'économiseur d'écran
    lock_open_screensaver() {
        echo "Ouverture du module d'économiseur d'écran..."
        open -a ScreenSaverEngine
    }
    
    # Méthode de verrouillage par défaut
    lock_display_pmset
}

immediate_lock_functions

Système de Gestion de Verrouillage d'Entreprise

#!/bin/bash

# Système de Gestion de Verrouillage d'Écran d'Entreprise MacFleet
# Application et surveillance complètes des politiques de sécurité

# Configuration
SECURITY_CONFIG_FILE="/etc/macfleet/screen_lock_config.conf"
LOG_FILE="/var/log/macfleet_screen_lock.log"
STATUS_FILE="/var/log/macfleet_security_status.json"

# Paramètres de sécurité par défaut
DEFAULT_SCREEN_TIMEOUT=300    # 5 minutes
DEFAULT_GRACE_PERIOD=0        # Immédiat
DEFAULT_DISPLAY_SLEEP=5       # 5 minutes
DEFAULT_SYSTEM_SLEEP=10       # 10 minutes

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

# Charger la configuration de sécurité
load_security_config() {
    if [[ -f "$SECURITY_CONFIG_FILE" ]]; then
        source "$SECURITY_CONFIG_FILE"
        log_action "Configuration de sécurité chargée depuis $SECURITY_CONFIG_FILE"
    else
        log_action "Utilisation de la configuration de sécurité par défaut"
    fi
}

# Appliquer les politiques de verrouillage d'écran d'entreprise
apply_enterprise_policies() {
    log_action "Application des politiques de verrouillage d'écran d'entreprise"
    
    # Activer l'exigence de mot de passe pour le verrouillage d'écran
    log_action "Activation de l'exigence de mot de passe de verrouillage d'écran"
    if osascript -e 'tell application "System Events" to set require password to wake of security preferences to true'; then
        log_action "✅ Exigence de mot de passe de verrouillage d'écran activée"
    else
        log_action "❌ Échec d'activation de l'exigence de mot de passe de verrouillage d'écran"
        return 1
    fi
    
    # Définir le délai de mot de passe
    local grace_period="${GRACE_PERIOD:-$DEFAULT_GRACE_PERIOD}"
    log_action "Définition de la période de grâce de mot de passe à $grace_period secondes"
    osascript -e "tell application \"System Events\" to set delay interval of security preferences to $grace_period" 2>/dev/null
    
    # Configurer les paramètres d'économiseur d'écran
    local screen_timeout="${SCREEN_TIMEOUT:-$DEFAULT_SCREEN_TIMEOUT}"
    log_action "Définition du délai d'économiseur d'écran à $screen_timeout secondes"
    defaults write com.apple.screensaver idleTime -int $screen_timeout
    defaults write com.apple.screensaver askForPassword -int 1
    defaults write com.apple.screensaver askForPasswordDelay -int $grace_period
    
    # Configurer la gestion d'énergie
    local display_sleep="${DISPLAY_SLEEP:-$DEFAULT_DISPLAY_SLEEP}"
    local system_sleep="${SYSTEM_SLEEP:-$DEFAULT_SYSTEM_SLEEP}"
    
    log_action "Configuration de la gestion d'énergie : affichage=$display_sleep min, système=$system_sleep min"
    sudo pmset -a displaysleep $display_sleep
    sudo pmset -a sleep $system_sleep
    sudo pmset -a halfdim 1
    
    # Appliquer des paramètres de sécurité supplémentaires
    apply_additional_security_settings
    
    log_action "Politiques de verrouillage d'écran d'entreprise appliquées avec succès"
}

# Appliquer des paramètres de sécurité supplémentaires
apply_additional_security_settings() {
    log_action "Application de paramètres de sécurité supplémentaires"
    
    # Désactiver la connexion automatique
    sudo defaults delete /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null || true
    
    # Désactiver le compte invité
    sudo defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled -bool NO
    
    # Définir la fenêtre de connexion pour afficher les champs nom et mot de passe
    sudo defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME -bool YES
    
    # Masquer les utilisateurs administrateurs de la fenêtre de connexion
    sudo defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool YES
    
    # Désactiver les indices de mot de passe
    sudo defaults write /Library/Preferences/com.apple.loginwindow RetriesUntilHint -int 0
    
    # Activer la mémoire virtuelle sécurisée
    sudo defaults write /Library/Preferences/com.apple.virtualMemory UseEncryptedSwap -bool YES
    
    # Définir le message d'écran de verrouillage si configuré
    if [[ -n "${LOCK_SCREEN_MESSAGE}" ]]; then
        defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$LOCK_SCREEN_MESSAGE"
        log_action "Message d'écran de verrouillage défini"
    fi
    
    log_action "Paramètres de sécurité supplémentaires appliqués"
}

# Surveiller la conformité du verrouillage d'écran
monitor_screen_lock_compliance() {
    log_action "Surveillance de la conformité du verrouillage d'écran"
    
    local compliance_issues=0
    local timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
    
    # Vérifier l'exigence de mot de passe
    local password_required=$(osascript -e 'tell application "System Events" to get require password to wake of security preferences' 2>/dev/null)
    local password_compliant=false
    
    if [[ "$password_required" == "true" ]]; then
        password_compliant=true
        log_action "✅ Exigence de mot de passe : conforme"
    else
        ((compliance_issues++))
        log_action "❌ Exigence de mot de passe : non conforme"
    fi
    
    # Vérifier le délai d'économiseur d'écran
    local current_timeout=$(defaults read com.apple.screensaver idleTime 2>/dev/null || echo "0")
    local timeout_compliant=false
    local max_allowed_timeout="${MAX_SCREEN_TIMEOUT:-600}"  # 10 minutes par défaut
    
    if [[ "$current_timeout" -le "$max_allowed_timeout" && "$current_timeout" -gt 0 ]]; then
        timeout_compliant=true
        log_action "✅ Délai d'économiseur d'écran : conforme ($current_timeout secondes)"
    else
        ((compliance_issues++))
        log_action "❌ Délai d'économiseur d'écran : non conforme ($current_timeout secondes)"
    fi
    
    # Vérifier le délai de mot de passe
    local password_delay=$(defaults read com.apple.screensaver askForPasswordDelay 2>/dev/null || echo "300")
    local delay_compliant=false
    local max_allowed_delay="${MAX_PASSWORD_DELAY:-60}"  # 1 minute par défaut
    
    if [[ "$password_delay" -le "$max_allowed_delay" ]]; then
        delay_compliant=true
        log_action "✅ Délai de mot de passe : conforme ($password_delay secondes)"
    else
        ((compliance_issues++))
        log_action "❌ Délai de mot de passe : non conforme ($password_delay secondes)"
    fi
    
    # Vérifier le statut du compte invité
    local guest_enabled=$(sudo defaults read /Library/Preferences/com.apple.loginwindow GuestEnabled 2>/dev/null || echo "true")
    local guest_compliant=false
    
    if [[ "$guest_enabled" == "0" || "$guest_enabled" == "false" ]]; then
        guest_compliant=true
        log_action "✅ Compte invité : désactivé (conforme)"
    else
        ((compliance_issues++))
        log_action "❌ Compte invité : activé (non conforme)"
    fi
    
    # Générer le rapport de conformité
    local compliance_status='{
        "timestamp": "'$timestamp'",
        "device_id": "'$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')'",
        "hostname": "'$(hostname)'",
        "compliance_score": '$((4 - compliance_issues))'/4,
        "total_issues": '$compliance_issues',
        "checks": {
            "password_required": '$password_compliant',
            "timeout_compliant": '$timeout_compliant',
            "delay_compliant": '$delay_compliant',
            "guest_disabled": '$guest_compliant'
        },
        "settings": {
            "current_timeout": '$current_timeout',
            "current_delay": '$password_delay',
            "guest_account": "'$guest_enabled'"
        }
    }'
    
    # Sauvegarder le statut de conformité
    echo "$compliance_status" | jq . > "$STATUS_FILE"
    
    if [[ $compliance_issues -eq 0 ]]; then
        log_action "✅ Vérification de conformité du verrouillage d'écran réussie (4/4)"
    else
        log_action "⚠️  Problèmes de conformité du verrouillage d'écran trouvés : $compliance_issues/4"
    fi
    
    return $compliance_issues
}

# Remédiation automatique des problèmes de conformité
auto_remediate_compliance() {
    log_action "Démarrage de la remédiation automatique pour les problèmes de conformité"
    
    # Vérifier la conformité actuelle
    monitor_screen_lock_compliance
    local issues=$?
    
    if [[ $issues -eq 0 ]]; then
        log_action "Aucun problème de conformité trouvé, saut de la remédiation"
        return 0
    fi
    
    log_action "Trouvé $issues problèmes de conformité, tentative de remédiation"
    
    # Réappliquer les politiques d'entreprise
    apply_enterprise_policies
    
    # Attendre et revérifier la conformité
    sleep 5
    monitor_screen_lock_compliance
    local remaining_issues=$?
    
    if [[ $remaining_issues -lt $issues ]]; then
        log_action "✅ Remédiation réussie : réduction des problèmes de $issues à $remaining_issues"
    else
        log_action "⚠️  Remédiation incomplète : $remaining_issues problèmes restent"
    fi
    
    return $remaining_issues
}

# Générer un rapport de sécurité
generate_security_report() {
    log_action "Génération d'un rapport de sécurité complet"
    
    local report_file="/var/log/macfleet_security_report_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport de Sécurité de Verrouillage d'Écran MacFleet"
        echo "Généré : $(date)"
        echo "Appareil : $(hostname)"
        echo "UUID Matériel : $(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')"
        echo "Version macOS : $(sw_vers -productVersion)"
        echo "====================================="
        echo ""
        
        echo "Configuration de Verrouillage d'Écran :"
        echo "Mot de Passe Requis : $(osascript -e 'tell application "System Events" to get require password to wake of security preferences' 2>/dev/null || echo 'Inconnu')"
        echo "Délai d'Économiseur d'Écran : $(defaults read com.apple.screensaver idleTime 2>/dev/null || echo 'Non défini') secondes"
        echo "Délai de Mot de Passe : $(defaults read com.apple.screensaver askForPasswordDelay 2>/dev/null || echo 'Non défini') secondes"
        echo ""
        
        echo "Paramètres de Gestion d'Énergie :"
        pmset -g | grep -E "(sleep|displaysleep|halfdim)"
        echo ""
        
        echo "Sécurité de la Fenêtre de Connexion :"
        echo "Compte Invité : $(sudo defaults read /Library/Preferences/com.apple.loginwindow GuestEnabled 2>/dev/null || echo 'Inconnu')"
        echo "Afficher Nom Complet : $(sudo defaults read /Library/Preferences/com.apple.loginwindow SHOWFULLNAME 2>/dev/null || echo 'Inconnu')"
        echo "Masquer Utilisateurs Admin : $(sudo defaults read /Library/Preferences/com.apple.loginwindow Hide500Users 2>/dev/null || echo 'Inconnu')"
        echo ""
        
        echo "Statut de Conformité de Sécurité :"
        if [[ -f "$STATUS_FILE" ]]; then
            cat "$STATUS_FILE"
        else
            echo "Aucune donnée de conformité disponible"
        fi
        
    } > "$report_file"
    
    log_action "Rapport de sécurité sauvegardé dans : $report_file"
}

# Fonction de verrouillage d'urgence
emergency_lock() {
    log_action "Verrouillage d'urgence initié"
    
    # Méthode 1 : Veille immédiate de l'affichage
    pmset displaysleepnow
    
    # Méthode 2 : Activer l'économiseur d'écran
    osascript -e 'tell application "System Events" to start current screen saver' 2>/dev/null
    
    # Méthode 3 : Basculer vers la fenêtre de connexion
    /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend 2>/dev/null
    
    log_action "Verrouillage d'urgence terminé"
}

# Fonction principale de gestion du verrouillage d'écran
main() {
    local action="${1:-apply}"
    
    log_action "=== Gestion de Verrouillage d'Écran MacFleet Démarrée ==="
    
    case "$action" in
        "apply")
            load_security_config
            apply_enterprise_policies
            ;;
        "monitor")
            monitor_screen_lock_compliance
            ;;
        "remediate")
            auto_remediate_compliance
            ;;
        "report")
            generate_security_report
            ;;
        "lock")
            emergency_lock
            ;;
        "status")
            monitor_screen_lock_compliance
            ;;
        *)
            echo "Usage : $0 [apply|monitor|remediate|report|lock|status]"
            echo "  apply     - Appliquer les politiques de verrouillage d'écran d'entreprise (défaut)"
            echo "  monitor   - Surveiller le statut de conformité"
            echo "  remediate - Remédiation automatique des problèmes de conformité"
            echo "  report    - Générer un rapport de sécurité complet"
            echo "  lock      - Verrouillage d'urgence de l'appareil immédiatement"
            echo "  status    - Vérifier le statut de conformité actuel"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion de Verrouillage d'Écran MacFleet Terminée ==="
}

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

Fichier de Configuration de Sécurité

Créer un fichier de configuration pour les politiques de sécurité d'entreprise :

#!/bin/bash

# Créer un fichier de configuration de sécurité de verrouillage d'écran
create_security_config() {
    local config_dir="/etc/macfleet"
    local config_file="$config_dir/screen_lock_config.conf"
    
    # Créer le répertoire s'il n'existe pas
    sudo mkdir -p "$config_dir"
    
    # Créer le fichier de configuration
    sudo tee "$config_file" > /dev/null << 'EOF'
# Configuration de Sécurité de Verrouillage d'Écran MacFleet
# Toutes les valeurs de délai sont en secondes sauf indication contraire

# Délai d'économiseur d'écran (défaut : 300 secondes = 5 minutes)
SCREEN_TIMEOUT=300

# Période de grâce de mot de passe après verrouillage d'écran (défaut : 0 = immédiat)
GRACE_PERIOD=0

# Délai de veille d'affichage en minutes (défaut : 5 minutes)
DISPLAY_SLEEP=5

# Délai de veille système en minutes (défaut : 10 minutes)
SYSTEM_SLEEP=10

# Délai d'écran maximum autorisé pour la conformité (défaut : 600 secondes = 10 minutes)
MAX_SCREEN_TIMEOUT=600

# Délai de mot de passe maximum autorisé pour la conformité (défaut : 60 secondes)
MAX_PASSWORD_DELAY=60

# Message d'écran de verrouillage (optionnel)
LOCK_SCREEN_MESSAGE="Cet appareil est géré par MacFleet. L'accès non autorisé est interdit."

# Configuration des coins actifs (optionnel)
ENABLE_HOT_CORNERS=true
HOT_CORNER_BR=5    # Coin inférieur droit : Démarrer l'économiseur d'écran
HOT_CORNER_TR=10   # Coin supérieur droit : Mettre l'affichage en veille

# Options d'application de sécurité
DISABLE_GUEST_ACCOUNT=true
DISABLE_AUTO_LOGIN=true
HIDE_ADMIN_USERS=true
DISABLE_PASSWORD_HINTS=true
ENABLE_SECURE_VM=true

# Paramètres de surveillance
COMPLIANCE_CHECK_INTERVAL=3600  # 1 heure
AUTO_REMEDIATION=true
GENERATE_REPORTS=true
EOF

    echo "Configuration de sécurité de verrouillage d'écran créée dans : $config_file"
    echo "Veuillez réviser et modifier les paramètres selon vos politiques de sécurité"
}

create_security_config

Intégration avec la Gestion MacFleet

#!/bin/bash

# Intégration de sécurité de verrouillage d'écran MacFleet
macfleet_security_integration() {
    echo "=== Intégration de Sécurité de Verrouillage d'Écran MacFleet ==="
    
    # Informations de l'appareil
    local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
    local hostname=$(hostname)
    local macos_version=$(sw_vers -productVersion)
    
    # Obtenir le statut de sécurité actuel
    local password_required=$(osascript -e 'tell application "System Events" to get require password to wake of security preferences' 2>/dev/null || echo "inconnu")
    local screen_timeout=$(defaults read com.apple.screensaver idleTime 2>/dev/null || echo "0")
    local password_delay=$(defaults read com.apple.screensaver askForPasswordDelay 2>/dev/null || echo "inconnu")
    
    # Évaluation de la conformité de sécurité
    local compliance_score=0
    local total_checks=4
    
    [[ "$password_required" == "true" ]] && ((compliance_score++))
    [[ "$screen_timeout" -le 600 && "$screen_timeout" -gt 0 ]] && ((compliance_score++))
    [[ "$password_delay" -le 60 ]] && ((compliance_score++))
    
    local guest_disabled=$(sudo defaults read /Library/Preferences/com.apple.loginwindow GuestEnabled 2>/dev/null || echo "true")
    [[ "$guest_disabled" == "0" || "$guest_disabled" == "false" ]] && ((compliance_score++))
    
    # Rapporter à l'API MacFleet
    local api_data='{
        "device_id": "'$device_id'",
        "hostname": "'$hostname'",
        "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
        "macos_version": "'$macos_version'",
        "screen_lock_security": {
            "password_required": "'$password_required'",
            "screen_timeout": '$screen_timeout',
            "password_delay": "'$password_delay'",
            "guest_account_disabled": "'$guest_disabled'",
            "compliance_score": '$compliance_score'/'$total_checks'
        },
        "security_management_status": "actif"
    }'
    
    echo "Statut de sécurité de verrouillage d'écran rapporté au système de gestion MacFleet"
    echo "ID Appareil : $device_id"
    echo "Score de Conformité : $compliance_score/$total_checks"
    echo "Mot de Passe Requis : $password_required"
    echo "Délai d'Écran : $screen_timeout secondes"
}

macfleet_security_integration

Compatibilité des Versions macOS

Considérations Spécifiques aux Versions

#!/bin/bash

# Vérifier la compatibilité des versions macOS
check_macos_compatibility() {
    local macos_version=$(sw_vers -productVersion)
    local major_version=$(echo "$macos_version" | cut -d. -f1)
    local minor_version=$(echo "$macos_version" | cut -d. -f2)
    
    echo "=== Vérification de Compatibilité macOS ==="
    echo "Version macOS actuelle : $macos_version"
    
    # Vérifier si la version est prise en charge (10.12 à 12.7)
    if [[ $major_version -eq 10 && $minor_version -ge 12 ]] || [[ $major_version -ge 11 && $major_version -le 12 ]]; then
        echo "✅ Version macOS prise en charge"
        return 0
    elif [[ $major_version -ge 13 ]]; then
        echo "⚠️  Version macOS peut avoir un support limité (test recommandé)"
        return 1
    else
        echo "❌ Version macOS non prise en charge"
        return 2
    fi
}

check_macos_compatibility

Notes de Sécurité Importantes

Bonnes Pratiques

  • Tester sur des appareils pilotes avant le déploiement à l'échelle de la flotte
  • Surveillance régulière de la conformité pour assurer l'adhésion aux politiques
  • Sauvegarder les paramètres actuels avant d'appliquer de nouvelles politiques
  • Documenter les changements de politique pour l'audit et le dépannage

Considérations de Sécurité

  • Exigence de mot de passe immédiat fournit la sécurité la plus forte
  • Délai d'économiseur d'écran doit équilibrer sécurité et utilisabilité
  • Compte invité désactivé empêche l'accès non autorisé
  • Messages d'écran de verrouillage fournissent des informations de contact et des avis légaux

Dépannage

  • Actualisation des Préférences Système peut être nécessaire pour que les changements apparaissent
  • Privilèges administrateur nécessaires pour les paramètres de sécurité au niveau système
  • Redémarrage peut être requis pour certains changements de gestion d'énergie
  • Tester les commandes AppleScript individuellement en cas de problèmes

Gestion d'Entreprise des Redémarrages Programmés sur macOS

Gérez et automatisez les redémarrages système de votre MacFleet avec des capacités de planification de niveau entreprise. Ce tutoriel couvre la planification avancée des redémarrages, les fenêtres de maintenance, les notifications utilisateur et le déploiement à l'échelle de la flotte avec surveillance de conformité.

Comprendre la Gestion des Redémarrages macOS

Les redémarrages programmés sont essentiels pour :

  • 🔄 Maintenance système - Effacer la mémoire, appliquer les mises à jour, réinitialiser l'état système
  • 🛡️ Conformité sécuritaire - S'assurer que les correctifs de sécurité sont actifs après installation
  • ⚡ Optimisation performance - Réinitialiser l'utilisation des ressources et éliminer les fuites mémoire
  • 🏢 Planification d'entreprise - Coordonner la maintenance sur des flottes entières

Planification de Base des Redémarrages

Redémarrage Programmé par Heure

#!/bin/bash

# Programmer un redémarrage à une heure spécifique (format 24h)
# Remplacer 0300 par l'heure de redémarrage désirée (03:00 AM)
sudo shutdown -r 0300

echo "✅ Redémarrage programmé pour 03:00"

Redémarrage Immédiat avec Délai

#!/bin/bash

# Programmer un redémarrage dans X minutes
MINUTES=30
sudo shutdown -r +$MINUTES

echo "✅ Redémarrage programmé dans $MINUTES minutes"

Annuler un Redémarrage Programmé

#!/bin/bash

# Annuler tout redémarrage en attente
sudo shutdown -c

echo "✅ Redémarrage programmé annulé"

Options de Planification Avancées

Redémarrage Conditionnel avec Vérifications Système

#!/bin/bash

# Redémarrer seulement si le système remplit des conditions spécifiques
perform_system_checks() {
    echo "🔍 Exécution des vérifications système pré-redémarrage..."
    
    # Vérifier la charge système
    local load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
    local load_threshold=2.0
    
    if (( $(echo "$load_avg > $load_threshold" | bc -l) )); then
        echo "⚠️ Charge système trop élevée ($load_avg) - report du redémarrage"
        return 1
    fi
    
    # Vérifier les processus critiques
    local critical_processes=("backup" "sync" "deploy")
    for process in "${critical_processes[@]}"; do
        if pgrep -f "$process" > /dev/null; then
            echo "⚠️ Processus critique '$process' en cours - report du redémarrage"
            return 1
        fi
    done
    
    # Vérifier l'espace disque disponible
    local available_space=$(df / | tail -1 | awk '{print $4}')
    local min_space=1048576  # 1GB en KB
    
    if [[ $available_space -lt $min_space ]]; then
        echo "⚠️ Espace disque insuffisant - report du redémarrage"
        return 1
    fi
    
    echo "✅ Toutes les vérifications système réussies"
    return 0
}

# Programmer le redémarrage seulement si les conditions sont remplies
if perform_system_checks; then
    sudo shutdown -r +5
    echo "✅ Redémarrage programmé dans 5 minutes"
else
    echo "❌ Redémarrage reporté en raison des conditions système"
fi

Redémarrage Convivial avec Notifications

#!/bin/bash

# Redémarrage amélioré avec notifications utilisateur et période de grâce
graceful_restart() {
    local delay_minutes="${1:-15}"
    local restart_time="${2:-$(date -d "+$delay_minutes minutes" "+%H:%M")}"
    
    echo "🔔 Programmation d'un redémarrage gracieux dans $delay_minutes minutes"
    
    # Envoyer notification aux utilisateurs connectés
    local logged_users=$(who | awk '{print $1}' | sort -u)
    
    for user in $logged_users; do
        sudo -u "$user" osascript -e "display notification \"Redémarrage système programmé pour $restart_time. Veuillez sauvegarder votre travail.\" with title \"Maintenance MacFleet\" sound name \"Glass\""
    done
    
    # Programmer le redémarrage
    sudo shutdown -r "+$delay_minutes"
    
    echo "✅ Redémarrage programmé pour $restart_time avec notifications utilisateur envoyées"
}

# Exécuter le redémarrage gracieux
graceful_restart 15

Fenêtres de Maintenance d'Entreprise

Planning de Maintenance Hebdomadaire

#!/bin/bash

# Programmer un redémarrage pendant la fenêtre de maintenance
schedule_maintenance_restart() {
    local day_of_week=$(date +%u)  # 1=Lundi, 7=Dimanche
    local current_hour=$(date +%H)
    local maintenance_day=7        # Dimanche
    local maintenance_hour=03      # 3h du matin
    
    # Calculer le temps jusqu'à la prochaine fenêtre de maintenance
    local days_until_maintenance=$(( (maintenance_day - day_of_week) % 7 ))
    if [[ $days_until_maintenance -eq 0 ]] && [[ $current_hour -ge $maintenance_hour ]]; then
        days_until_maintenance=7  # Semaine prochaine si on a dépassé la fenêtre d'aujourd'hui
    fi
    
    local restart_date=$(date -d "+$days_until_maintenance days $maintenance_hour:00" "+%Y-%m-%d %H:%M")
    local restart_timestamp=$(date -d "$restart_date" "+%m%d%H%M")
    
    echo "📅 Programmation du redémarrage pour la prochaine fenêtre de maintenance : $restart_date"
    
    # Utiliser la commande at pour une planification précise
    echo "sudo shutdown -r now" | at "$restart_timestamp" 2>/dev/null
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Redémarrage programmé pour la fenêtre de maintenance : $restart_date"
    else
        # Solution de repli si 'at' n'est pas disponible
        echo "⚠️ Commande 'at' non disponible, utilisation de la planification immédiate"
        sudo shutdown -r 0300  # 3h aujourd'hui/demain
    fi
}

schedule_maintenance_restart

Protection des Heures de Bureau

#!/bin/bash

# Empêcher les redémarrages pendant les heures de bureau
business_hours_restart() {
    local current_hour=$(date +%H)
    local current_day=$(date +%u)  # 1=Lundi, 7=Dimanche
    local business_start=9
    local business_end=17
    
    # Vérifier si c'est un jour de semaine pendant les heures de bureau
    if [[ $current_day -le 5 ]] && [[ $current_hour -ge $business_start ]] && [[ $current_hour -lt $business_end ]]; then
        echo "🏢 Heures de bureau détectées - programmation du redémarrage après les heures de bureau"
        
        if [[ $current_hour -lt 12 ]]; then
            # Matin - programmer pour le soir
            sudo shutdown -r 1800  # 18h
            echo "✅ Redémarrage programmé pour 18:00 (après les heures de bureau)"
        else
            # Après-midi - programmer pour le lendemain tôt le matin
            sudo shutdown -r 0600  # 6h le lendemain
            echo "✅ Redémarrage programmé pour 06:00 demain (avant les heures de bureau)"
        fi
    else
        echo "✅ En dehors des heures de bureau - redémarrage sûr"
        sudo shutdown -r +5
        echo "✅ Redémarrage programmé dans 5 minutes"
    fi
}

business_hours_restart

Script de Gestion d'Entreprise de Flotte

#!/bin/bash

# Système de Gestion des Redémarrages d'Entreprise MacFleet
# Planification avancée, surveillance et déploiement de flotte

# Configuration
SCRIPT_NAME="MacFleet Restart Manager"
VERSION="3.0.0"
LOG_FILE="/var/log/macfleet_restart.log"
CONFIG_DIR="/etc/macfleet/restart"
SCHEDULE_DIR="/etc/macfleet/restart/schedules"
POLICY_DIR="/etc/macfleet/restart/policies"
AUDIT_DIR="/etc/macfleet/restart/audit"

# Créer les répertoires nécessaires
mkdir -p "$CONFIG_DIR" "$SCHEDULE_DIR" "$POLICY_DIR" "$AUDIT_DIR"

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

# Journalisation d'audit pour la conformité
log_restart_action() {
    local action="$1"
    local schedule_type="$2"
    local restart_time="$3"
    local user=$(whoami)
    local hostname=$(hostname)
    
    local audit_entry="{
        \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
        \"hostname\": \"$hostname\",
        \"user\": \"$user\",
        \"action\": \"$action\",
        \"schedule_type\": \"$schedule_type\",
        \"restart_time\": \"$restart_time\",
        \"script_version\": \"$VERSION\"
    }"
    
    echo "$audit_entry" >> "$AUDIT_DIR/restart_audit.json"
    log_action "Action de redémarrage : $action - $schedule_type à $restart_time"
}

# Évaluation de la santé système
assess_system_health() {
    echo "🏥 Évaluation de la santé système pour la préparation au redémarrage..."
    
    local health_score=100
    local issues=()
    
    # Vérifier la charge système
    local load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
    if (( $(echo "$load_avg > 3.0" | bc -l) )); then
        health_score=$((health_score - 20))
        issues+=("Charge système élevée : $load_avg")
    fi
    
    # Vérifier l'utilisation mémoire
    local memory_pressure=$(memory_pressure | grep "System-wide memory free percentage" | awk '{print $5}' | sed 's/%//')
    if [[ $memory_pressure -lt 10 ]]; then
        health_score=$((health_score - 15))
        issues+=("Mémoire faible : ${memory_pressure}% libre")
    fi
    
    # Vérifier l'espace disque
    local disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
    if [[ $disk_usage -gt 90 ]]; then
        health_score=$((health_score - 10))
        issues+=("Utilisation disque élevée : ${disk_usage}%")
    fi
    
    # Vérifier les processus critiques
    local critical_procs=$(pgrep -f "(backup|sync|deploy|update)" | wc -l)
    if [[ $critical_procs -gt 0 ]]; then
        health_score=$((health_score - 25))
        issues+=("Processus critiques en cours : $critical_procs")
    fi
    
    # Vérifier la connectivité réseau
    if ! ping -c 1 -W 5 8.8.8.8 >/dev/null 2>&1; then
        health_score=$((health_score - 5))
        issues+=("Problème de connectivité réseau")
    fi
    
    # Générer le rapport de santé
    local health_report="{
        \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
        \"hostname\": \"$(hostname)\",
        \"health_score\": $health_score,
        \"issues\": [$(printf '\"%s\",' "${issues[@]}" | sed 's/,$//')]
    }"
    
    echo "$health_report" > "$AUDIT_DIR/health_assessment_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📊 Score de santé système : $health_score/100"
    if [[ ${#issues[@]} -gt 0 ]]; then
        echo "⚠️ Problèmes détectés :"
        printf '   - %s\n' "${issues[@]}"
    fi
    
    # Retourner le score de santé (0 = échec, 1 = succès)
    [[ $health_score -ge 70 ]]
}

# Système de notification avancé
send_restart_notifications() {
    local restart_time="$1"
    local minutes_until="$2"
    local notification_type="${3:-standard}"
    
    echo "🔔 Envoi des notifications de redémarrage..."
    
    # Obtenir les utilisateurs connectés
    local logged_users=$(who | awk '{print $1}' | sort -u)
    
    # Messages de notification basés sur le type
    case "$notification_type" in
        "emergency")
            local title="URGENCE : Redémarrage Système Requis"
            local message="Mise à jour de sécurité critique nécessite un redémarrage immédiat à $restart_time"
            local sound="Basso"
            ;;
        "maintenance")
            local title="Maintenance Programmée"
            local message="Redémarrage système programmé pour $restart_time dans le cadre de la maintenance de routine"
            local sound="Glass"
            ;;
        *)
            local title="Notification de Redémarrage Système"
            local message="Redémarrage système programmé pour $restart_time. Veuillez sauvegarder votre travail."
            local sound="Blow"
            ;;
    esac
    
    # Envoyer notifications à chaque utilisateur
    for user in $logged_users; do
        if [[ -n "$user" ]]; then
            sudo -u "$user" osascript -e "display notification \"$message\" with title \"$title\" sound name \"$sound\"" 2>/dev/null
            
            # Envoyer aussi un message terminal si l'utilisateur a un terminal ouvert
            sudo -u "$user" wall "Avis MacFleet : $message" 2>/dev/null
        fi
    done
    
    log_action "Notifications envoyées aux utilisateurs : $(echo $logged_users | tr '\n' ' ')"
}

# Planification intelligente de redémarrage
intelligent_restart() {
    local schedule_type="$1"
    local target_time="$2"
    local force="${3:-false}"
    
    echo "🧠 Initiation de la planification intelligente de redémarrage..."
    
    # Évaluer la santé système sauf si forcé
    if [[ "$force" != "true" ]]; then
        if ! assess_system_health; then
            echo "❌ Vérification de santé système échouée - redémarrage reporté"
            log_restart_action "postponed" "$schedule_type" "$target_time"
            return 1
        fi
    fi
    
    case "$schedule_type" in
        "immediate")
            echo "⚡ Programmation d'un redémarrage immédiat..."
            send_restart_notifications "dans 2 minutes" "2" "emergency"
            sudo shutdown -r +2
            ;;
        "maintenance")
            echo "🔧 Programmation d'un redémarrage de maintenance..."
            local delay_minutes=15
            local restart_time=$(date -d "+$delay_minutes minutes" "+%H:%M")
            send_restart_notifications "$restart_time" "$delay_minutes" "maintenance"
            sudo shutdown -r "+$delay_minutes"
            ;;
        "business_safe")
            schedule_business_safe_restart
            ;;
        "weekly")
            schedule_weekly_maintenance
            ;;
        "custom")
            if [[ -n "$target_time" ]]; then
                echo "🎯 Programmation d'un redémarrage personnalisé pour $target_time..."
                send_restart_notifications "$target_time" "personnalisé" "standard"
                sudo shutdown -r "$target_time"
            else
                echo "❌ Le redémarrage personnalisé nécessite une heure cible"
                return 1
            fi
            ;;
        *)
            echo "❌ Type de planification invalide : $schedule_type"
            echo "Types disponibles : immediate, maintenance, business_safe, weekly, custom"
            return 1
            ;;
    esac
    
    log_restart_action "scheduled" "$schedule_type" "${target_time:-auto}"
    echo "✅ Redémarrage programmé avec succès"
}

# Planification de redémarrage sûre pour les affaires
schedule_business_safe_restart() {
    local current_hour=$(date +%H)
    local current_day=$(date +%u)
    
    if [[ $current_day -le 5 ]] && [[ $current_hour -ge 9 ]] && [[ $current_hour -lt 17 ]]; then
        echo "🏢 Heures de bureau détectées - programmation après les heures de bureau"
        if [[ $current_hour -lt 12 ]]; then
            sudo shutdown -r 1800  # 18h
            send_restart_notifications "18:00" "après les heures de bureau" "maintenance"
        else
            sudo shutdown -r 0600  # 6h le lendemain
            send_restart_notifications "06:00 demain" "tôt le matin" "maintenance"
        fi
    else
        echo "✅ En dehors des heures de bureau - redémarrage sûr"
        send_restart_notifications "dans 10 minutes" "10" "maintenance"
        sudo shutdown -r +10
    fi
}

# Planification de maintenance hebdomadaire
schedule_weekly_maintenance() {
    local day_of_week=$(date +%u)
    local maintenance_day=7  # Dimanche
    local maintenance_hour=03
    
    local days_until=$(( (maintenance_day - day_of_week) % 7 ))
    if [[ $days_until -eq 0 ]] && [[ $(date +%H) -ge $maintenance_hour ]]; then
        days_until=7
    fi
    
    local restart_date=$(date -d "+$days_until days $maintenance_hour:00" "+%Y-%m-%d %H:%M")
    
    echo "📅 Programmation pour la prochaine fenêtre de maintenance : $restart_date"
    
    # Utiliser launchd pour une planification précise (plus fiable que 'at')
    create_maintenance_schedule "$restart_date"
}

# Créer un job launchd pour la planification de maintenance
create_maintenance_schedule() {
    local restart_datetime="$1"
    local plist_name="com.macfleet.maintenance.restart"
    local plist_path="/Library/LaunchDaemons/${plist_name}.plist"
    
    # Calculer l'intervalle de démarrage depuis l'époque
    local start_time=$(date -j -f "%Y-%m-%d %H:%M" "$restart_datetime" "+%s" 2>/dev/null)
    
    if [[ -n "$start_time" ]]; then
        cat > "$plist_path" << 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>ProgramArguments</key>
    <array>
        <string>/usr/sbin/shutdown</string>
        <string>-r</string>
        <string>now</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>3</integer>
        <key>Minute</key>
        <integer>0</integer>
        <key>Weekday</key>
        <integer>0</integer>
    </dict>
    <key>RunAtLoad</key>
    <false/>
</dict>
</plist>
EOF
        
        # Charger le job
        launchctl load "$plist_path"
        echo "✅ Planning de maintenance créé et chargé"
    else
        echo "❌ Échec de l'analyse de la date/heure de redémarrage : $restart_datetime"
        return 1
    fi
}

# Déploiement de flotte
deploy_restart_schedule() {
    local schedule_type="$1"
    local target_time="$2"
    local fleet_file="$CONFIG_DIR/fleet_hosts.txt"
    
    if [[ ! -f "$fleet_file" ]]; then
        echo "❌ Fichier des hôtes de flotte non trouvé : $fleet_file"
        return 1
    fi
    
    echo "🚀 Déploiement du planning de redémarrage sur la flotte..."
    echo "Type de Planning : $schedule_type"
    echo "Heure Cible : ${target_time:-auto}"
    
    local success_count=0
    local total_count=0
    
    while IFS= read -r host; do
        [[ "$host" =~ ^#.*$ ]] && continue
        [[ -z "$host" ]] && continue
        
        ((total_count++))
        echo "Déploiement vers : $host"
        
        # Déployer et exécuter
        if scp "$0" "$host:/tmp/macfleet_restart.sh" >/dev/null 2>&1 && \
           ssh "$host" "chmod +x /tmp/macfleet_restart.sh && sudo /tmp/macfleet_restart.sh --schedule '$schedule_type' ${target_time:+--time '$target_time'}" >/dev/null 2>&1; then
            echo "✅ Déployé avec succès vers $host"
            ((success_count++))
        else
            echo "❌ Échec du déploiement vers $host"
        fi
        
    done < "$fleet_file"
    
    echo "📊 Déploiement de flotte terminé : $success_count/$total_count réussi"
    log_action "Déploiement de flotte : $success_count/$total_count hôtes réussis"
}

# Générer un rapport de conformité de redémarrage
generate_restart_report() {
    local report_file="$AUDIT_DIR/restart_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📊 Génération du rapport de conformité de redémarrage..."
    
    # Rassembler les informations système
    local uptime_days=$(uptime | awk '{print $3}' | sed 's/,//')
    local last_restart=$(last reboot | head -1 | awk '{print $3, $4, $5, $6}')
    local pending_restart=$(sudo shutdown -q 2>&1 | grep -o "shutdown.*" || echo "aucun")
    
    # Vérifier les mises à jour en attente
    local pending_updates=$(softwareupdate -l 2>/dev/null | grep -c "recommended" || echo "0")
    
    # Générer le rapport
    local report="{
        \"report_metadata\": {
            \"generated_at\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
            \"hostname\": \"$(hostname)\",
            \"script_version\": \"$VERSION\",
            \"compliance_frameworks\": [\"NIST\", \"ISO 27001\", \"SOX\", \"HIPAA\"]
        },
        \"system_status\": {
            \"uptime_days\": \"$uptime_days\",
            \"last_restart\": \"$last_restart\",
            \"pending_restart\": \"$pending_restart\",
            \"pending_updates\": $pending_updates
        },
        \"restart_history\": $(tail -10 "$LOG_FILE" 2>/dev/null | jq -R . | jq -s . || echo "[]"),
        \"compliance_score\": $(calculate_restart_compliance_score "$uptime_days" "$pending_updates")
    }"
    
    echo "$report" > "$report_file"
    echo "📋 Rapport de conformité sauvegardé : $report_file"
    log_action "Rapport de conformité généré : $report_file"
}

# Calculer le score de conformité de redémarrage
calculate_restart_compliance_score() {
    local uptime_days="$1"
    local pending_updates="$2"
    local score=100
    
    # Déduire des points pour un temps de fonctionnement prolongé
    if [[ "$uptime_days" =~ ^[0-9]+$ ]]; then
        if [[ $uptime_days -gt 30 ]]; then
            score=$((score - 30))
        elif [[ $uptime_days -gt 14 ]]; then
            score=$((score - 15))
        elif [[ $uptime_days -gt 7 ]]; then
            score=$((score - 5))
        fi
    fi
    
    # Déduire des points pour les mises à jour en attente
    if [[ "$pending_updates" =~ ^[0-9]+$ ]] && [[ $pending_updates -gt 0 ]]; then
        score=$((score - (pending_updates * 10)))
    fi
    
    # S'assurer que le score est entre 0 et 100
    [[ $score -lt 0 ]] && score=0
    [[ $score -gt 100 ]] && score=100
    
    echo "$score"
}

# Capacité de redémarrage d'urgence
emergency_restart() {
    echo "🚨 REDÉMARRAGE D'URGENCE INITIÉ"
    
    # Envoyer des notifications immédiates
    send_restart_notifications "dans 60 secondes" "1" "emergency"
    
    # Créer une entrée de journal d'urgence
    log_restart_action "emergency" "immediate" "60 secondes"
    
    # Forcer le redémarrage avec un délai minimal
    sudo shutdown -r +1
    
    echo "⚠️ REDÉMARRAGE D'URGENCE DANS 60 SECONDES"
}

# Vérification de statut
check_restart_status() {
    echo "=== Statut de Redémarrage MacFleet ==="
    
    # Temps de fonctionnement système
    echo "🕐 Temps de Fonctionnement Système : $(uptime | awk '{print $3, $4}' | sed 's/,//')"
    
    # Dernier redémarrage
    echo "📅 Dernier Redémarrage : $(last reboot | head -1 | awk '{print $3, $4, $5, $6}')"
    
    # Redémarrage en attente
    local pending=$(sudo shutdown -q 2>&1 | grep -o "shutdown.*" || echo "aucun")
    echo "⏰ Redémarrage en Attente : $pending"
    
    # Santé système
    if assess_system_health >/dev/null 2>&1; then
        echo "🟢 Santé Système : Bonne"
    else
        echo "🔴 Santé Système : Problèmes détectés"
    fi
    
    # Mises à jour en attente
    local updates=$(softwareupdate -l 2>/dev/null | grep -c "recommended" || echo "0")
    echo "📦 Mises à Jour en Attente : $updates"
}

# Afficher l'utilisation
show_usage() {
    cat << EOF
$SCRIPT_NAME v$VERSION

Utilisation : $0 [OPTION]

PLANIFICATION DE REDÉMARRAGE :
    --schedule TYPE [TIME]      Programmer un redémarrage (immediate|maintenance|business_safe|weekly|custom)
    --emergency                 Redémarrage d'urgence (avertissement 60 secondes)
    --cancel                    Annuler le redémarrage en attente
    --status                    Afficher le statut de redémarrage actuel

GESTION DE FLOTTE :
    --deploy-fleet TYPE [TIME]  Déployer le planning de redémarrage sur toute la flotte
    --generate-report           Générer un rapport de conformité

EXEMPLES :
    $0 --schedule immediate
    $0 --schedule maintenance
    $0 --schedule custom 0300
    $0 --deploy-fleet weekly
    $0 --emergency
    $0 --status

Configuration :
    $CONFIG_DIR/fleet_hosts.txt  - Hôtes de déploiement de flotte
    
Journaux :
    $LOG_FILE                    - Fichier de journal principal
    $AUDIT_DIR/                  - Journaux d'audit et de conformité
EOF
}

# Fonction principale
main() {
    case "$1" in
        --schedule)
            [[ -z "$2" ]] && { echo "❌ Type de planification requis"; exit 1; }
            intelligent_restart "$2" "$3"
            ;;
        --emergency)
            emergency_restart
            ;;
        --cancel)
            sudo shutdown -c 2>/dev/null && echo "✅ Redémarrage annulé" || echo "❌ Aucun redémarrage à annuler"
            ;;
        --status)
            check_restart_status
            ;;
        --deploy-fleet)
            [[ -z "$2" ]] && { echo "❌ Type de planification requis pour le déploiement de flotte"; exit 1; }
            deploy_restart_schedule "$2" "$3"
            ;;
        --generate-report)
            generate_restart_report
            ;;
        --help|"")
            show_usage
            ;;
        *)
            echo "❌ Option invalide : $1"
            show_usage
            exit 1
            ;;
    esac
}

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

Politiques de Planification de Redémarrage

Politique d'Environnement de Production

#!/bin/bash

# Politique de redémarrage de production haute disponibilité
production_restart_policy() {
    echo "🏭 Application de la politique de redémarrage de production..."
    
    # Autoriser les redémarrages seulement pendant les fenêtres de maintenance désignées
    local current_hour=$(date +%H)
    local current_day=$(date +%u)
    
    # Fenêtres de maintenance : Dimanches 2-4h, Jours de semaine 2-3h
    local maintenance_allowed=false
    
    if [[ $current_day -eq 7 ]] && [[ $current_hour -ge 2 ]] && [[ $current_hour -lt 4 ]]; then
        maintenance_allowed=true
    elif [[ $current_day -le 5 ]] && [[ $current_hour -ge 2 ]] && [[ $current_hour -lt 3 ]]; then
        maintenance_allowed=true
    fi
    
    if [[ "$maintenance_allowed" == "true" ]]; then
        echo "✅ Dans la fenêtre de maintenance - redémarrage autorisé"
        return 0
    else
        echo "⛔ En dehors de la fenêtre de maintenance - redémarrage bloqué"
        return 1
    fi
}

Politique d'Environnement de Développement

#!/bin/bash

# Politique de redémarrage de développement flexible
development_restart_policy() {
    echo "💻 Application de la politique de redémarrage de développement..."
    
    # Planification plus flexible pour le développement
    local current_hour=$(date +%H)
    
    # Bloquer les redémarrages seulement pendant les heures de développement de pointe (9h-18h)
    if [[ $current_hour -ge 9 ]] && [[ $current_hour -lt 18 ]]; then
        echo "⚠️ Heures de développement de pointe - demande de confirmation"
        
        # Dans une implémentation réelle, ceci pourrait déclencher un workflow d'approbation
        echo "Le redémarrage sera programmé après les heures de pointe (18h)"
        sudo shutdown -r 1800
        return 0
    else
        echo "✅ En dehors des heures de pointe - redémarrage autorisé"
        return 0
    fi
}

Exemples d'Utilisation

Programmer un Redémarrage de Maintenance Immédiat

# Redémarrage d'urgence avec notifications utilisateur
sudo ./macfleet_restart.sh --schedule immediate

# Redémarrage de maintenance avec période de grâce de 15 minutes
sudo ./macfleet_restart.sh --schedule maintenance

Planification Sûre pour les Affaires

# Éviter automatiquement les heures de bureau
sudo ./macfleet_restart.sh --schedule business_safe

# Fenêtre de maintenance hebdomadaire
sudo ./macfleet_restart.sh --schedule weekly

Déploiement de Flotte

# Déployer un redémarrage immédiat sur toute la flotte
sudo ./macfleet_restart.sh --deploy-fleet immediate

# Déployer un planning de maintenance hebdomadaire
sudo ./macfleet_restart.sh --deploy-fleet weekly

Planification Personnalisée

# Programmer un redémarrage pour 3h du matin
sudo ./macfleet_restart.sh --schedule custom 0300

# Programmer un redémarrage pour 18h
sudo ./macfleet_restart.sh --schedule custom 1800

Conformité et Surveillance

Cadres de Conformité de Redémarrage

Cadre de Cybersécurité NIST

  • 🛡️ Identifier : Suivre le temps de fonctionnement système et les exigences de redémarrage
  • 🔒 Protéger : S'assurer que les mises à jour de sécurité sont appliquées via les redémarrages
  • 🔍 Détecter : Surveiller les fenêtres de maintenance manquées
  • 🚨 Réagir : Planification et application automatisées de redémarrage
  • ♻️ Récupérer : Capacités de redémarrage d'urgence pour la réponse aux incidents

Conformité SOX

  • 📋 Pistes d'audit pour toutes les activités de redémarrage
  • 🔐 Contrôles d'accès pour la planification de redémarrage
  • 📊 Rapports de conformité avec suivi du temps de fonctionnement système

Protections Techniques HIPAA

  • 🏥 Maintenance système s'assurant que les correctifs de sécurité sont actifs
  • 📝 Contrôles d'audit avec journalisation complète des redémarrages

Métriques de Surveillance

# Métriques clés suivies automatiquement :
# - Durée du temps de fonctionnement système
# - Horodatage du dernier redémarrage
# - Mises à jour logicielles en attente
# - Score de conformité de redémarrage
# - Tentatives de redémarrage échouées
# - Adhérence aux fenêtres de maintenance

Notes de Sécurité Importantes

  • 🔐 Nécessite des privilèges administratifs pour la planification de redémarrage
  • 📝 Toutes les activités de redémarrage sont auditées et journalisées pour la conformité
  • 🔔 Les notifications utilisateur fournissent des périodes de grâce pour la sauvegarde du travail
  • 🏥 Les vérifications de santé système empêchent les redémarrages pendant les opérations critiques
  • ⏰ Protection des heures de bureau empêche la perturbation de la productivité
  • 🚨 Override d'urgence disponible pour les incidents de sécurité critiques

Dépannage

Problèmes Courants

# Vérifier si un redémarrage est déjà programmé
sudo shutdown -q

# Annuler un redémarrage en attente
sudo shutdown -c

# Vérifier les journaux système pour les problèmes de redémarrage
log show --predicate 'eventMessage contains "shutdown"' --last 1d

# Vérifier les jobs launchd
launchctl list | grep macfleet

Échecs de Redémarrage

# Vérifier les processus empêchant le redémarrage
lsof +c 15 | grep COMMAND

# Forcer le redémarrage si le système ne répond pas
sudo shutdown -r now

# Vérifier la santé système avant une nouvelle tentative
./macfleet_restart.sh --status

Gestion Navigateur Safari sur macOS

Gérez les configurations et politiques navigateur Safari sur vos appareils MacFleet avec déploiement paramètres niveau entreprise. Ce tutoriel couvre configuration page d'accueil, paramètres sécurité, gestion utilisateur et application complète politiques navigateur.

Comprendre la Gestion Navigateur Safari

La gestion navigateur Safari sur macOS implique configurer paramètres navigateur, politiques sécurité et préférences utilisateur sur appareils entreprise :

Composants Principaux

  • Configuration Page d'Accueil - Définir pages d'atterrissage par défaut pour utilisateurs
  • Paramètres Sécurité - Gérer politiques confidentialité, sécurité et contenu
  • Préférences Utilisateur - Contrôler comportement et fonctionnalités navigateur
  • Application Politiques - Déployer et maintenir paramètres navigateur cohérents
  • Gestion Flotte - Configuration masse sur appareils multiples

Avantages Entreprise

  • Navigation Standardisée - Expérience utilisateur cohérente sur appareils
  • Conformité Sécurité - Appliquer politiques et restrictions sécurité
  • Contrôle Productivité - Gérer accès sites et fonctionnalités
  • Déploiement Politiques - Gestion configuration navigateur centralisée
  • Capacités Audit - Suivre et surveiller modèles utilisation navigateur

Configuration Basique Page d'Accueil Safari

Configuration Page d'Accueil Simple

#!/bin/bash

# Configuration page d'accueil Safari améliorée
configure_safari_homepage() {
    local homepage_url="${1:-https://macfleet.io}"
    local apply_to_all_users="${2:-true}"
    
    echo "🌐 Configuration Page d'Accueil Safari"
    echo "====================================="
    echo "URL page d'accueil : $homepage_url"
    echo "Appliquer à tous utilisateurs : $apply_to_all_users"
    echo ""
    
    # Valider format URL
    if ! [[ "$homepage_url" =~ ^https?:// ]]; then
        echo "⚠️ Ajout https:// à l'URL : $homepage_url"
        homepage_url="https://$homepage_url"
    fi
    
    echo "URL page d'accueil finale : $homepage_url"
    echo ""
    
    # Tuer processus Safari pour assurer prise effet paramètres
    echo "Terminaison processus Safari..."
    sudo killall -9 Safari 2>/dev/null || echo "Aucun processus Safari en cours"
    sleep 2
    
    if [[ "$apply_to_all_users" == "true" ]]; then
        configure_all_users_safari "$homepage_url"
    else
        configure_current_user_safari "$homepage_url"
    fi
}

# Configurer Safari pour tous utilisateurs
configure_all_users_safari() {
    local homepage="$1"
    local users_configured=0
    local users_failed=0
    
    echo "Configuration Safari pour tous utilisateurs..."
    echo ""
    
    # Boucler chaque utilisateur pour définir préférences page d'accueil
    for user in $(ls /Users | grep -v Shared | grep -v npsparcc | grep -v ".localized" | grep -v "Guest"); do
        echo "Traitement utilisateur : $user"
        
        # Vérifier si répertoire utilisateur existe
        if [[ ! -d "/Users/$user" ]]; then
            echo "⚠️ Répertoire utilisateur non trouvé, ignorer : $user"
            continue
        fi
        
        # Configurer paramètres Safari
        if configure_user_safari_settings "$user" "$homepage"; then
            echo "✅ Safari configuré avec succès pour utilisateur : $user"
            ((users_configured++))
        else
            echo "❌ Échec configuration Safari pour utilisateur : $user"
            ((users_failed++))
        fi
        echo ""
    done
    
    echo "=== Résumé Configuration ==="
    echo "Utilisateurs configurés : $users_configured"
    echo "Utilisateurs échoués : $users_failed"
    echo "Total traité : $((users_configured + users_failed))"
}

# Configurer paramètres Safari pour utilisateur spécifique
configure_user_safari_settings() {
    local user="$1"
    local homepage="$2"
    
    # Définir page d'accueil Safari
    if su - "$user" -c "defaults write com.apple.Safari HomePage '$homepage'" 2>/dev/null; then
        # Définir comportement nouvelle fenêtre (0 = page d'accueil)
        su - "$user" -c "defaults write com.apple.Safari NewWindowBehavior -int 0" 2>/dev/null
        
        # Définir comportement nouvel onglet (0 = page d'accueil)
        su - "$user" -c "defaults write com.apple.Safari NewTabBehavior -int 0" 2>/dev/null
        
        # Vérifier paramètres
        local current_homepage
        current_homepage=$(su - "$user" -c "defaults read com.apple.Safari HomePage" 2>/dev/null)
        
        if [[ "$current_homepage" == "$homepage" ]]; then
            echo "  Page d'accueil définie : $current_homepage"
            echo "  Comportement nouvelle fenêtre : Page d'accueil"
            echo "  Comportement nouvel onglet : Page d'accueil"
            return 0
        else
            echo "  ⚠️ Vérification échouée"
            return 1
        fi
    else
        echo "  ❌ Échec écriture préférences Safari"
        return 1
    fi
}

# Configurer utilisateur actuel uniquement
configure_current_user_safari() {
    local homepage="$1"
    local current_user=$(whoami)
    
    echo "Configuration Safari pour utilisateur actuel : $current_user"
    
    if configure_user_safari_settings "$current_user" "$homepage"; then
        echo "✅ Safari configuré avec succès pour utilisateur actuel"
    else
        echo "❌ Échec configuration Safari pour utilisateur actuel"
        return 1
    fi
}

# Exécuter configuration page d'accueil basique
echo "Configuration Page d'Accueil Safari Basique :"
echo "============================================="
configure_safari_homepage "https://macfleet.io" true

Système Gestion Safari Entreprise

Gestionnaire Configuration Navigateur Complet

#!/bin/bash

# Système gestion Safari entreprise
enterprise_safari_manager() {
    local operation="${1:-configure}"
    local config_profile="${2:-standard}"
    local target_users="${3:-all}"
    
    echo "🏢 Gestionnaire Safari Entreprise MacFleet"
    echo "=========================================="
    echo "Opération : $operation"
    echo "Profil : $config_profile"
    echo "Utilisateurs cibles : $target_users"
    echo ""
    
    # Profils configuration
    declare -A config_profiles
    config_profiles[standard]="https://macfleet.io:true:true:false"
    config_profiles[securise]="https://macfleet.io:true:true:true"
    config_profiles[education]="https://education.macfleet.io:true:false:true"
    config_profiles[kiosque]="https://kiosque.macfleet.io:false:false:true"
    
    case "$operation" in
        "configure")
            deploy_safari_configuration "$config_profile" "$target_users"
            ;;
        "securite")
            apply_security_settings "$config_profile" "$target_users"
            ;;
        "audit")
            audit_safari_settings "$target_users"
            ;;
        "sauvegarde")
            backup_safari_settings "$target_users"
            ;;
        "restaurer")
            restore_safari_settings "$target_users"
            ;;
        *)
            echo "❌ Opération inconnue : $operation"
            echo "Opérations disponibles : configure, securite, audit, sauvegarde, restaurer"
            return 1
            ;;
    esac
}

# Déployer configuration Safari complète
deploy_safari_configuration() {
    local profile="$1"
    local target_users="$2"
    
    echo "📋 Déploiement Configuration Safari"
    echo "==================================="
    
    # Analyser profil configuration
    local config_string="${config_profiles[$profile]:-${config_profiles[standard]}}"
    IFS=':' read -r homepage block_popups auto_fill restrict_sites <<< "$config_string"
    
    echo "Profil Configuration : $profile"
    echo "Page d'accueil : $homepage"
    echo "Bloquer popups : $block_popups"
    echo "Remplissage auto : $auto_fill" 
    echo "Restreindre sites : $restrict_sites"
    echo ""
    
    # Obtenir liste utilisateurs cibles
    local users_list=()
    if [[ "$target_users" == "all" ]]; then
        readarray -t users_list < <(ls /Users | grep -v Shared | grep -v npsparcc | grep -v ".localized" | grep -v "Guest")
    else
        IFS=',' read -ra users_list <<< "$target_users"
    fi
    
    local configured=0
    local failed=0
    
    # Tuer processus Safari d'abord
    echo "Terminaison tous processus Safari..."
    sudo killall -9 Safari 2>/dev/null || echo "Aucun processus Safari en cours"
    sleep 3
    
    # Configurer chaque utilisateur
    for user in "${users_list[@]}"; do
        if [[ -n "$user" && -d "/Users/$user" ]]; then
            echo "Configuration utilisateur : $user"
            
            if apply_user_safari_config "$user" "$homepage" "$block_popups" "$auto_fill" "$restrict_sites"; then
                echo "✅ Configuration appliquée avec succès"
                ((configured++))
            else
                echo "❌ Configuration échouée"
                ((failed++))
            fi
            echo ""
        fi
    done
    
    # Générer rapport déploiement
    cat > "/tmp/safari_deployment_$(date +%Y%m%d_%H%M%S).log" << EOF
Rapport Déploiement Configuration Safari
=======================================
Date : $(date)
Profil : $profile
Cible : $target_users

Détails Configuration :
- Page d'accueil : $homepage
- Bloquer popups : $block_popups
- Remplissage auto : $auto_fill
- Restreindre sites : $restrict_sites

Résultats :
- Configurés avec succès : $configured utilisateurs
- Configurations échouées : $failed utilisateurs
- Total traité : $((configured + failed)) utilisateurs

Statut Déploiement : $([[ "$failed" -eq 0 ]] && echo "SUCCÈS" || echo "PARTIEL")
EOF
    
    echo "=== Résumé Déploiement ==="
    echo "Configurés avec succès : $configured utilisateurs"
    echo "Configurations échouées : $failed utilisateurs"
    echo "Total traité : $((configured + failed)) utilisateurs"
    
    if [[ "$failed" -eq 0 ]]; then
        echo "🎉 Déploiement terminé avec succès !"
    else
        echo "⚠️ Déploiement terminé avec quelques échecs"
    fi
}

# Appliquer paramètres Safari complets pour utilisateur
apply_user_safari_config() {
    local user="$1"
    local homepage="$2"
    local block_popups="$3"
    local auto_fill="$4"
    local restrict_sites="$5"
    
    local settings_applied=0
    
    # Définir page d'accueil et comportement fenêtre/onglet
    if su - "$user" -c "defaults write com.apple.Safari HomePage '$homepage'" 2>/dev/null; then
        su - "$user" -c "defaults write com.apple.Safari NewWindowBehavior -int 0" 2>/dev/null
        su - "$user" -c "defaults write com.apple.Safari NewTabBehavior -int 0" 2>/dev/null
        ((settings_applied++))
    fi
    
    # Configurer blocage popup
    if [[ "$block_popups" == "true" ]]; then
        su - "$user" -c "defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically -bool false" 2>/dev/null
        su - "$user" -c "defaults write com.apple.Safari com.apple.Safari.ContentPageGroupIdentifier.WebKit2JavaScriptCanOpenWindowsAutomatically -bool false" 2>/dev/null
        ((settings_applied++))
    fi
    
    # Configurer paramètres remplissage automatique
    if [[ "$auto_fill" == "true" ]]; then
        su - "$user" -c "defaults write com.apple.Safari AutoFillFormData -bool true" 2>/dev/null
        su - "$user" -c "defaults write com.apple.Safari AutoFillPasswords -bool true" 2>/dev/null
    else
        su - "$user" -c "defaults write com.apple.Safari AutoFillFormData -bool false" 2>/dev/null
        su - "$user" -c "defaults write com.apple.Safari AutoFillPasswords -bool false" 2>/dev/null
    fi
    ((settings_applied++))
    
    # Configurer paramètres sécurité
    if [[ "$restrict_sites" == "true" ]]; then
        # Activer contrôles parentaux et restrictions
        su - "$user" -c "defaults write com.apple.Safari WebKitDeveloperExtrasEnabled -bool false" 2>/dev/null
        su - "$user" -c "defaults write com.apple.Safari IncludeDevelopMenu -bool false" 2>/dev/null
        su - "$user" -c "defaults write com.apple.Safari WebKitJavaEnabled -bool false" 2>/dev/null
        ((settings_applied++))
    fi
    
    # Paramètres sécurité additionnels
    su - "$user" -c "defaults write com.apple.Safari SendDoNotTrackHTTPHeader -bool true" 2>/dev/null
    su - "$user" -c "defaults write com.apple.Safari InstallExtensionUpdatesAutomatically -bool true" 2>/dev/null
    
    return $([[ "$settings_applied" -ge 3 ]] && echo 0 || echo 1)
}

# Configuration Safari axée sécurité
apply_security_settings() {
    local profile="$1"
    local target_users="$2"
    
    echo "🔒 Application Paramètres Sécurité"
    echo "=================================="
    echo ""
    
    # Obtenir liste utilisateurs
    local users_list=()
    if [[ "$target_users" == "all" ]]; then
        readarray -t users_list < <(ls /Users | grep -v Shared | grep -v npsparcc | grep -v ".localized" | grep -v "Guest")
    else
        IFS=',' read -ra users_list <<< "$target_users"
    fi
    
    for user in "${users_list[@]}"; do
        if [[ -n "$user" && -d "/Users/$user" ]]; then
            echo "Application paramètres sécurité pour utilisateur : $user"
            
            # Paramètres sécurité améliorés
            su - "$user" -c "defaults write com.apple.Safari WebKitJavaScriptEnabled -bool false" 2>/dev/null
            su - "$user" -c "defaults write com.apple.Safari WebKitJavaEnabled -bool false" 2>/dev/null
            su - "$user" -c "defaults write com.apple.Safari WebKitPluginsEnabled -bool false" 2>/dev/null
            su - "$user" -c "defaults write com.apple.Safari SendDoNotTrackHTTPHeader -bool true" 2>/dev/null
            su - "$user" -c "defaults write com.apple.Safari WarnAboutFraudulentWebsites -bool true" 2>/dev/null
            su - "$user" -c "defaults write com.apple.Safari BlockStoragePolicy -int 2" 2>/dev/null
            
            echo "✅ Paramètres sécurité appliqués"
        fi
    done
}

# Auditer paramètres Safari actuels
audit_safari_settings() {
    local target_users="$1"
    local audit_file="/tmp/safari_audit_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📊 Audit Paramètres Safari"
    echo "=========================="
    echo ""
    
    {
        echo "{"
        echo "  \"rapport_audit\": {"
        echo "    \"genere\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\","
        echo "    \"nom_hote\": \"$(hostname)\","
        echo "    \"utilisateurs\": ["
        
        local first_user=true
        local total_users=0
        local compliant_users=0
        
        # Obtenir liste utilisateurs
        local users_list=()
        if [[ "$target_users" == "all" ]]; then
            readarray -t users_list < <(ls /Users | grep -v Shared | grep -v npsparcc | grep -v ".localized" | grep -v "Guest")
        else
            IFS=',' read -ra users_list <<< "$target_users"
        fi
        
        for user in "${users_list[@]}"; do
            if [[ -n "$user" && -d "/Users/$user" ]]; then
                if [[ "$first_user" == "false" ]]; then
                    echo ","
                fi
                
                local homepage=$(su - "$user" -c "defaults read com.apple.Safari HomePage" 2>/dev/null || echo "Non défini")
                local popup_blocking=$(su - "$user" -c "defaults read com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically" 2>/dev/null || echo "true")
                local do_not_track=$(su - "$user" -c "defaults read com.apple.Safari SendDoNotTrackHTTPHeader" 2>/dev/null || echo "false")
                
                local is_compliant="false"
                if [[ "$homepage" =~ macfleet ]] && [[ "$popup_blocking" == "false" ]] && [[ "$do_not_track" == "true" ]]; then
                    is_compliant="true"
                    ((compliant_users++))
                fi
                
                echo "      {"
                echo "        \"nom_utilisateur\": \"$user\","
                echo "        \"page_accueil\": \"$homepage\","
                echo "        \"blocage_popup\": $([[ "$popup_blocking" == "false" ]] && echo "true" || echo "false"),"
                echo "        \"ne_pas_suivre\": $([[ "$do_not_track" == "true" ]] && echo "true" || echo "false"),"
                echo "        \"conforme\": $is_compliant"
                echo -n "      }"
                
                first_user=false
                ((total_users++))
            fi
        done
        
        echo ""
        echo "    ],"
        echo "    \"resume\": {"
        echo "      \"total_utilisateurs\": $total_users,"
        echo "      \"utilisateurs_conformes\": $compliant_users,"
        echo "      \"taux_conformite\": \"$(echo "scale=1; ($compliant_users * 100) / $total_users" | bc 2>/dev/null || echo "0")%\""
        echo "    }"
        echo "  }"
        echo "}"
    } > "$audit_file"
    
    echo "✅ Audit terminé : $audit_file"
    echo ""
    echo "=== Résumé Audit ==="
    echo "Total utilisateurs : $total_users"
    echo "Utilisateurs conformes : $compliant_users"
    
    if [[ "$total_users" -gt 0 ]]; then
        local compliance_rate=$(echo "scale=1; ($compliant_users * 100) / $total_users" | bc 2>/dev/null || echo "0")
        echo "Taux conformité : ${compliance_rate}%"
    fi
}

# Exemples utilisation
echo "Exemples Gestionnaire Safari Entreprise :"
echo "=========================================="
echo ""

echo "1. Déployer configuration standard :"
enterprise_safari_manager "configure" "standard" "all"
echo ""

echo "2. Appliquer paramètres sécurité :"
enterprise_safari_manager "securite" "securise" "all"
echo ""

echo "3. Auditer paramètres actuels :"
enterprise_safari_manager "audit" "all"

Notes Importantes

Fonctionnalités Entreprise

  • Configuration Basée Profils - Paramètres prédéfinis pour différents cas usage
  • Gestion Utilisateur Masse - Déployer paramètres sur tous utilisateurs système
  • Application Politique Sécurité - Contrôles sécurité et confidentialité avancés
  • Audit et Conformité - Suivre conformité configuration sur flotte
  • Sauvegarde et Restauration - Préserver et restaurer configurations navigateur

Profils Configuration

  • Standard - Paramètres entreprise basiques avec page d'accueil MacFleet
  • Sécurisé - Sécurité renforcée avec fonctionnalités restreintes
  • Éducation - Optimisations environnement éducatif
  • Kiosque - Configuration verrouillée pour accès public

Fonctionnalités Sécurité

  • Blocage Popup - Empêcher fenêtres popup indésirables
  • Contrôle JavaScript - Gérer permissions exécution scripts
  • Ne Pas Suivre - Protection confidentialité renforcée
  • Gestion Remplissage Auto - Contrôler auto-complétion formulaires et mots de passe
  • Outils Développeur - Restreindre accès outils débogage

Exemples d'Utilisation

# Configuration page d'accueil basique
homepage="https://macfleet.io"
sudo killall -9 Safari
for user in $(ls /Users | grep -v Shared | grep -v npsparcc | grep -v ".localized"); do
    su - "$user" -c "defaults write com.apple.Safari HomePage $homepage"
    su - "$user" -c "defaults write com.apple.Safari NewWindowBehavior -int 0"
    su - "$user" -c "defaults write com.apple.Safari NewTabBehavior -int 0"
    echo "Page d'accueil Safari définie à $homepage pour $user."
done

# Configuration MacFleet améliorée
configure_safari_homepage "https://macfleet.io" true

# Déploiement entreprise
enterprise_safari_manager "configure" "securise" "all"

# Audit sécurité
enterprise_safari_manager "audit" "all"

Gestion Rosetta 2 et Compatibilité Apple Silicon sur macOS

Gérez la couche traduction Rosetta 2 et compatibilité Apple Silicon sur vos appareils MacFleet avec outils déploiement et surveillance niveau entreprise. Ce tutoriel couvre installation Rosetta, suivi compatibilité applications, surveillance performance et gestion flotte complète.

Comprendre Rosetta 2 et Apple Silicon

Rosetta 2 est le processus traduction d'Apple qui permet aux applications Intel de fonctionner sur Mac Apple Silicon :

Composants Principaux

  • Couche Traduction - Conversion temps réel instructions Intel x86_64 vers ARM64
  • Pont Compatibilité - Exécution transparente applications héritées
  • Optimisation Performance - Traduction efficace avec impact performance minimal
  • Gestion Applications - Contrôler quelles apps utilisent traduction Rosetta
  • Intégration Système - Intégration macOS profonde pour fonctionnement transparent

Avantages Entreprise

  • Support Applications Héritées - Continuer utiliser applications business Intel
  • Migration Transparente - Transition fluide Mac Intel vers Apple Silicon
  • Gestion Performance - Surveiller et optimiser performance applications traduites
  • Compatibilité Flotte - Assurer disponibilité applications cohérente sur appareils
  • Efficacité Coût - Étendre cycle vie investissements logiciels existants

Installation Basique Rosetta 2

Installation Rosetta Simple

#!/bin/bash

# Installation Rosetta 2 améliorée
install_rosetta_basic() {
    echo "🔧 Installation Rosetta 2 Basique"
    echo "================================="
    echo ""
    
    # Déterminer architecture appareil macOS
    local processor_brand=$(/usr/sbin/sysctl -n machdep.cpu.brand_string)
    echo "Processeur : $processor_brand"
    
    if [[ "${processor_brand}" = *"Apple"* ]]; then
        echo "✅ Processeur Apple Silicon détecté"
        echo "Installation Rosetta 2 requise pour compatibilité apps Intel"
    else
        echo "ℹ️ Processeur Intel détecté"
        echo "Rosetta 2 non requis sur Mac Intel"
        exit 0
    fi
    
    echo ""
    
    # Vérifier si Rosetta déjà installé
    local check_rosetta_status=$(/bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper")
    local rosetta_folder="/Library/Apple/usr/share/rosetta"
    
    echo "Vérification statut installation Rosetta 2..."
    echo "Dossier Rosetta : $rosetta_folder"
    echo "Service Rosetta : $([[ -n "$check_rosetta_status" ]] && echo "En cours" || echo "Arrêté")"
    
    if [[ -e "${rosetta_folder}" && "${check_rosetta_status}" != "" ]]; then
        echo "✅ Rosetta 2 déjà installé et en cours d'exécution"
        echo "Installation non requise"
        exit 0
    else
        echo "⚠️ Rosetta 2 non installé ou non en cours"
        echo "Procédure avec installation..."
    fi
    
    echo ""
    
    # Installer Rosetta
    echo "Installation Rosetta 2..."
    echo "Ceci peut prendre quelques minutes..."
    
    if /usr/sbin/softwareupdate --install-rosetta --agree-to-license; then
        echo "✅ Rosetta 2 installé avec succès"
        
        # Vérifier installation
        sleep 3
        local verify_service=$(/bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper")
        if [[ -n "$verify_service" ]]; then
            echo "✅ Service Rosetta 2 en cours d'exécution"
            echo "Applications Intel peuvent maintenant fonctionner sur ce Mac Apple Silicon"
        else
            echo "⚠️ Rosetta 2 installé mais vérification service échouée"
        fi
    else
        echo "❌ Installation Rosetta 2 échouée"
        echo "Veuillez vérifier connectivité réseau et réessayer"
        exit 1
    fi
}

# Exécuter installation basique
install_rosetta_basic

Gestion Rosetta Améliorée

#!/bin/bash

# Système gestion Rosetta 2 amélioré
enhanced_rosetta_manager() {
    local operation="${1:-install}"
    local force_install="${2:-false}"
    local log_file="/var/log/macfleet_rosetta.log"
    
    echo "🍎 Gestionnaire Rosetta 2 Amélioré"
    echo "=================================="
    echo "Opération : $operation"
    echo "Installation forcée : $force_install"
    echo "Fichier log : $log_file"
    echo ""
    
    # Fonction journalisation
    log_action() {
        echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$log_file"
    }
    
    case "$operation" in
        "install")
            install_rosetta_enhanced "$force_install"
            ;;
        "verify")
            verify_rosetta_status
            ;;
        "monitor")
            monitor_rosetta_usage
            ;;
        "report")
            generate_compatibility_report
            ;;
        *)
            echo "❌ Opération inconnue : $operation"
            echo "Opérations disponibles : install, verify, monitor, report"
            return 1
            ;;
    esac
}

# Installation Rosetta améliorée avec vérifications complètes
install_rosetta_enhanced() {
    local force_install="$1"
    
    log_action "Démarrage processus installation Rosetta 2"
    
    # Informations système complètes
    echo "=== Informations Système ==="
    local mac_model=$(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}')
    local mac_chip=$(system_profiler SPHardwareDataType | grep "Chip" | awk -F': ' '{print $2}')
    local macos_version=$(sw_vers -productVersion)
    local build_version=$(sw_vers -buildVersion)
    
    echo "Modèle Mac : $mac_model"
    echo "Puce : $mac_chip"
    echo "Version macOS : $macos_version"
    echo "Build : $build_version"
    echo ""
    
    # Détection architecture avec validation améliorée
    local processor_brand=$(/usr/sbin/sysctl -n machdep.cpu.brand_string)
    local cpu_arch=$(uname -m)
    
    echo "=== Analyse Processeur ==="
    echo "Marque CPU : $processor_brand"
    echo "Architecture : $cpu_arch"
    
    # Déterminer si Apple Silicon
    local is_apple_silicon=false
    if [[ "${processor_brand}" = *"Apple"* ]] || [[ "$cpu_arch" == "arm64" ]]; then
        is_apple_silicon=true
        echo "✅ Apple Silicon détecté"
        log_action "Mac Apple Silicon détecté : $processor_brand"
    else
        echo "ℹ️ Processeur Intel détecté"
        log_action "Mac Intel détecté : $processor_brand - Rosetta non requis"
        echo "Rosetta 2 non requis sur Mac Intel"
        return 0
    fi
    
    echo ""
    
    # Vérifier compatibilité macOS
    echo "=== Vérification Compatibilité macOS ==="
    local macos_major=$(echo "$macos_version" | cut -d. -f1)
    local macos_minor=$(echo "$macos_version" | cut -d. -f2)
    
    if [[ "$macos_major" -lt 11 ]] || [[ "$macos_major" -eq 11 && "$macos_minor" -lt 0 ]]; then
        echo "❌ Version macOS $macos_version ne supporte pas Rosetta 2"
        echo "Rosetta 2 nécessite macOS Big Sur 11.0 ou ultérieur"
        log_action "Version macOS incompatible : $macos_version"
        return 1
    else
        echo "✅ macOS $macos_version supporte Rosetta 2"
    fi
    
    echo ""
    
    # Vérification statut Rosetta améliorée
    echo "=== Vérification Statut Rosetta 2 ==="
    local check_rosetta_status=$(/bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper" || echo "")
    local rosetta_folder="/Library/Apple/usr/share/rosetta"
    local rosetta_binary="/Library/Apple/usr/libexec/oah/RosettaLinux/rosetta"
    
    echo "Vérification composants Rosetta :"
    echo "- Statut service : $([[ -n "$check_rosetta_status" ]] && echo "✅ En cours" || echo "❌ Arrêté")"
    echo "- Dossier Rosetta : $([[ -e "$rosetta_folder" ]] && echo "✅ Présent" || echo "❌ Manquant")"
    echo "- Binaire Rosetta : $([[ -e "$rosetta_binary" ]] && echo "✅ Présent" || echo "❌ Manquant")"
    
    # Vérifier si déjà installé et fonctionnel
    if [[ -e "${rosetta_folder}" && -n "${check_rosetta_status}" && "$force_install" != "true" ]]; then
        echo "✅ Rosetta 2 déjà installé et opérationnel"
        log_action "Rosetta 2 déjà installé et en cours"
        
        # Tester fonctionnalité Rosetta
        echo ""
        echo "Test fonctionnalité Rosetta..."
        if test_rosetta_functionality; then
            echo "✅ Rosetta 2 fonctionne correctement"
            log_action "Test fonctionnalité Rosetta 2 réussi"
        else
            echo "⚠️ Rosetta 2 installé mais test fonctionnalité échoué"
            log_action "Test fonctionnalité Rosetta 2 échoué"
        fi
        
        return 0
    fi
    
    echo ""
    
    # Vérifications pré-installation
    echo "=== Vérifications Pré-Installation ==="
    
    # Vérifier espace disque disponible
    local available_space=$(df -h / | tail -1 | awk '{print $4}' | sed 's/G//')
    echo "Espace disque disponible : ${available_space}Go"
    
    if [[ "${available_space%.*}" -lt 1 ]]; then
        echo "⚠️ Espace disque faible détecté (${available_space}Go disponible)"
        echo "Rosetta 2 nécessite au moins 1Go d'espace libre"
        log_action "Avertissement installation : Espace disque faible (${available_space}Go)"
    fi
    
    # Vérifier connectivité réseau
    echo "Vérification connectivité réseau..."
    if ping -c 1 swscan.apple.com >/dev/null 2>&1; then
        echo "✅ Connectivité réseau vers serveurs Apple vérifiée"
    else
        echo "⚠️ Problème connectivité réseau détecté"
        echo "Installation Rosetta 2 nécessite connexion internet"
        log_action "Avertissement installation : Problème connectivité réseau"
    fi
    
    echo ""
    
    # Installer Rosetta 2
    echo "=== Installation Rosetta 2 ==="
    log_action "Démarrage installation Rosetta 2"
    echo "Installation couche traduction Rosetta 2..."
    echo "Ce processus peut prendre plusieurs minutes selon vitesse réseau..."
    
    local install_start=$(date +%s)
    
    if /usr/sbin/softwareupdate --install-rosetta --agree-to-license; then
        local install_end=$(date +%s)
        local install_duration=$((install_end - install_start))
        
        echo "✅ Installation Rosetta 2 terminée avec succès"
        echo "Temps installation : ${install_duration} secondes"
        log_action "Installation Rosetta 2 réussie (${install_duration}s)"
        
        # Vérification post-installation
        echo ""
        echo "=== Vérification Post-Installation ==="
        sleep 5  # Permettre démarrage services
        
        # Vérifier service
        local verify_service=$(/bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper" || echo "")
        if [[ -n "$verify_service" ]]; then
            echo "✅ Service Rosetta 2 en cours d'exécution"
        else
            echo "⚠️ Service Rosetta 2 non détecté"
            log_action "Avertissement post-installation : Service Rosetta non en cours"
        fi
        
        # Vérifier structure dossier
        if [[ -e "$rosetta_folder" ]]; then
            local folder_size=$(du -sh "$rosetta_folder" | cut -f1)
            echo "✅ Dossier Rosetta 2 créé (Taille : $folder_size)"
        else
            echo "❌ Dossier Rosetta 2 non trouvé"
            log_action "Erreur post-installation : Dossier Rosetta non trouvé"
        fi
        
        # Tester fonctionnalité
        echo ""
        echo "Test fonctionnalité Rosetta 2..."
        if test_rosetta_functionality; then
            echo "✅ Rosetta 2 fonctionne correctement"
            echo "Applications Intel peuvent maintenant fonctionner sur ce Mac Apple Silicon"
            log_action "Installation et test Rosetta 2 réussis"
        else
            echo "⚠️ Rosetta 2 installé mais test fonctionnalité échoué"
            log_action "Rosetta 2 installé mais test fonctionnalité échoué"
        fi
        
    else
        echo "❌ Installation Rosetta 2 échouée"
        echo "Veuillez vérifier :"
        echo "- Connectivité réseau vers serveurs Apple"
        echo "- Espace disque disponible (minimum 1Go requis)"
        echo "- Compatibilité version macOS"
        log_action "Installation Rosetta 2 échouée"
        return 1
    fi
}

# Tester fonctionnalité Rosetta
test_rosetta_functionality() {
    # Essayer exécuter test binaire x86_64 simple
    if command -v arch >/dev/null 2>&1; then
        if arch -x86_64 /usr/bin/true >/dev/null 2>&1; then
            return 0
        fi
    fi
    
    # Test alternatif - vérifier si on peut exécuter architecture x86_64
    if /usr/bin/arch -x86_64 /bin/echo "Test Rosetta" >/dev/null 2>&1; then
        return 0
    fi
    
    return 1
}

# Exécuter installation améliorée
echo "Installation Rosetta 2 Améliorée :"
echo "=================================="
enhanced_rosetta_manager "install" false

Système Gestion Rosetta Entreprise

Gestionnaire Compatibilité Complet

#!/bin/bash

# Système gestion Rosetta et compatibilité entreprise
enterprise_compatibility_manager() {
    local operation="${1:-status}"
    local scope="${2:-system}"
    local output_format="${3:-json}"
    
    echo "🏢 Gestionnaire Compatibilité Entreprise MacFleet"
    echo "================================================"
    echo "Opération : $operation"
    echo "Portée : $scope"
    echo "Format sortie : $output_format"
    echo ""
    
    case "$operation" in
        "deploy")
            deploy_fleet_rosetta "$scope"
            ;;
        "audit")
            audit_compatibility_status "$scope" "$output_format"
            ;;
        "monitor")
            monitor_application_compatibility
            ;;
        "optimize")
            optimize_rosetta_performance
            ;;
        "report")
            generate_enterprise_report "$output_format"
            ;;
        *)
            echo "❌ Opération inconnue : $operation"
            echo "Opérations disponibles : deploy, audit, monitor, optimize, report"
            return 1
            ;;
    esac
}

# Déployer Rosetta sur flotte
deploy_fleet_rosetta() {
    local scope="$1"
    
    echo "🚀 Déploiement Rosetta Flotte"
    echo "============================="
    echo ""
    
    local deployment_id=$(openssl rand -hex 8)
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local log_file="/var/log/macfleet_rosetta_deployment_${timestamp}.log"
    
    echo "ID Déploiement : $deployment_id"
    echo "Portée : $scope"
    echo "Fichier log : $log_file"
    echo ""
    
    # Évaluation compatibilité système
    echo "=== Évaluation Compatibilité Système ==="
    
    local mac_model=$(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}')
    local mac_chip=$(system_profiler SPHardwareDataType | grep "Chip" | awk -F': ' '{print $2}')
    local macos_version=$(sw_vers -productVersion)
    local cpu_arch=$(uname -m)
    
    echo "Informations Système :"
    echo "- Modèle : $mac_model"
    echo "- Puce : $mac_chip"
    echo "- macOS : $macos_version"
    echo "- Architecture : $cpu_arch"
    echo ""
    
    # Vérifications pré-déploiement
    echo "=== Vérifications Pré-Déploiement ==="
    
    local checks_passed=0
    local checks_total=0
    
    # Vérification 1 : Détection Apple Silicon
    ((checks_total++))
    if [[ "$cpu_arch" == "arm64" ]]; then
        echo "✅ Apple Silicon détecté - Déploiement Rosetta applicable"
        ((checks_passed++))
    else
        echo "ℹ️ Mac Intel détecté - Déploiement Rosetta non requis"
        echo "Déploiement ignoré pour Mac Intel"
        return 0
    fi
    
    # Vérification 2 : Compatibilité version macOS
    ((checks_total++))
    local macos_major=$(echo "$macos_version" | cut -d. -f1)
    if [[ "$macos_major" -ge 11 ]]; then
        echo "✅ Version macOS compatible avec Rosetta 2"
        ((checks_passed++))
    else
        echo "❌ Version macOS $macos_version non compatible avec Rosetta 2"
        echo "Exigence minimum : macOS Big Sur 11.0"
        return 1
    fi
    
    # Vérification 3 : Espace disque
    ((checks_total++))
    local available_space=$(df -h / | tail -1 | awk '{print $4}' | sed 's/G//')
    if [[ "${available_space%.*}" -ge 2 ]]; then
        echo "✅ Espace disque suffisant disponible (${available_space}Go)"
        ((checks_passed++))
    else
        echo "⚠️ Espace disque limité (${available_space}Go) - déploiement peut échouer"
    fi
    
    # Vérification 4 : Connectivité réseau
    ((checks_total++))
    if ping -c 1 swscan.apple.com >/dev/null 2>&1; then
        echo "✅ Connectivité réseau vers serveurs Apple vérifiée"
        ((checks_passed++))
    else
        echo "⚠️ Problème connectivité réseau - déploiement peut échouer"
    fi
    
    echo ""
    echo "Résultats vérifications pré-déploiement : $checks_passed/$checks_total réussies"
    echo ""
    
    # Exécution déploiement
    echo "=== Exécution Déploiement ==="
    
    local deployment_start=$(date +%s)
    
    {
        echo "Journal Déploiement Rosetta MacFleet"
        echo "===================================="
        echo "ID Déploiement : $deployment_id"
        echo "Horodatage : $(date)"
        echo "Nom hôte : $(hostname)"
        echo "Utilisateur : $(whoami)"
        echo ""
        echo "Informations Système :"
        echo "- Modèle : $mac_model"
        echo "- Puce : $mac_chip"
        echo "- macOS : $macos_version"
        echo "- Architecture : $cpu_arch"
        echo ""
    } > "$log_file"
    
    # Exécuter installation améliorée
    if enhanced_rosetta_manager "install" false >> "$log_file" 2>&1; then
        local deployment_end=$(date +%s)
        local deployment_duration=$((deployment_end - deployment_start))
        
        echo "✅ Déploiement Rosetta 2 terminé avec succès"
        echo "Temps déploiement : ${deployment_duration} secondes"
        echo "Fichier log : $log_file"
        
        # Validation post-déploiement
        echo ""
        echo "=== Validation Post-Déploiement ==="
        validate_rosetta_deployment "$deployment_id"
        
    else
        echo "❌ Déploiement Rosetta 2 échoué"
        echo "Consulter fichier log pour détails : $log_file"
        return 1
    fi
}

# Valider déploiement Rosetta
validate_rosetta_deployment() {
    local deployment_id="$1"
    
    local validation_tests=0
    local validation_passed=0
    
    # Test 1 : Service en cours
    ((validation_tests++))
    if /bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper" >/dev/null; then
        echo "✅ Service Rosetta en cours d'exécution"
        ((validation_passed++))
    else
        echo "❌ Service Rosetta non en cours"
    fi
    
    # Test 2 : Structure dossier
    ((validation_tests++))
    if [[ -e "/Library/Apple/usr/share/rosetta" ]]; then
        echo "✅ Structure dossier Rosetta existe"
        ((validation_passed++))
    else
        echo "❌ Structure dossier Rosetta manquante"
    fi
    
    # Test 3 : Test fonctionnalité
    ((validation_tests++))
    if test_rosetta_functionality; then
        echo "✅ Test fonctionnalité Rosetta réussi"
        ((validation_passed++))
    else
        echo "❌ Test fonctionnalité Rosetta échoué"
    fi
    
    echo ""
    echo "Résultats validation : $validation_passed/$validation_tests tests réussis"
    
    if [[ "$validation_passed" -eq "$validation_tests" ]]; then
        echo "🎉 Validation déploiement réussie"
        return 0
    else
        echo "⚠️ Validation déploiement incomplète"
        return 1
    fi
}

# Surveiller compatibilité applications
monitor_application_compatibility() {
    echo "📊 Moniteur Compatibilité Applications"
    echo "======================================"
    echo ""
    
    # Obtenir liste applications installées
    local apps_dir="/Applications"
    local user_apps_dir="$HOME/Applications"
    
    echo "=== Analyse Applications Installées ==="
    
    local total_apps=0
    local intel_apps=0
    local universal_apps=0
    local arm_apps=0
    
    # Fonction vérifier architecture app
    check_app_architecture() {
        local app_path="$1"
        local app_name=$(basename "$app_path")
        
        if [[ -d "$app_path" ]]; then
            local executable_path="$app_path/Contents/MacOS"
            if [[ -d "$executable_path" ]]; then
                local executable=$(find "$executable_path" -type f -perm +111 | head -1)
                if [[ -n "$executable" ]]; then
                    local arch_info=$(file "$executable" 2>/dev/null | head -1)
                    
                    ((total_apps++))
                    
                    if [[ "$arch_info" =~ "x86_64" && "$arch_info" =~ "arm64" ]]; then
                        echo "🔄 $app_name - Universelle (Intel + Apple Silicon)"
                        ((universal_apps++))
                    elif [[ "$arch_info" =~ "x86_64" ]]; then
                        echo "🔧 $app_name - Intel seulement (nécessite Rosetta)"
                        ((intel_apps++))
                    elif [[ "$arch_info" =~ "arm64" ]]; then
                        echo "⚡ $app_name - Apple Silicon natif"
                        ((arm_apps++))
                    else
                        echo "❓ $app_name - Architecture inconnue"
                    fi
                fi
            fi
        fi
    }
    
    # Analyser applications système
    echo "Analyse applications système..."
    for app in "$apps_dir"/*.app; do
        check_app_architecture "$app"
    done
    
    # Analyser applications utilisateur
    if [[ -d "$user_apps_dir" ]]; then
        echo ""
        echo "Analyse applications utilisateur..."
        for app in "$user_apps_dir"/*.app; do
            check_app_architecture "$app"
        done
    fi
    
    echo ""
    echo "=== Résumé Compatibilité Applications ==="
    echo "Total applications : $total_apps"
    echo "Apple Silicon natif : $arm_apps"
    echo "Universelle (deux architectures) : $universal_apps"
    echo "Intel seulement (nécessitent Rosetta) : $intel_apps"
    
    if [[ "$intel_apps" -gt 0 ]]; then
        echo ""
        echo "⚠️ $intel_apps applications Intel seulement trouvées"
        echo "Rosetta 2 requis pour compatibilité optimale"
        
        # Vérifier si Rosetta installé
        if /bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper" >/dev/null; then
            echo "✅ Rosetta 2 installé et prêt"
        else
            echo "❌ Rosetta 2 non installé - apps Intel peuvent ne pas fonctionner"
        fi
    else
        echo "✅ Toutes applications compatibles Apple Silicon"
    fi
}

# Générer rapport compatibilité entreprise
generate_enterprise_report() {
    local output_format="$1"
    local report_file="/tmp/macfleet_compatibility_$(date +%Y%m%d_%H%M%S).$output_format"
    
    echo "📊 Génération Rapport Compatibilité Entreprise"
    echo "==============================================="
    echo ""
    
    # Collecter informations système
    local hostname=$(hostname)
    local mac_model=$(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}')
    local mac_chip=$(system_profiler SPHardwareDataType | grep "Chip" | awk -F': ' '{print $2}')
    local macos_version=$(sw_vers -productVersion)
    local cpu_arch=$(uname -m)
    
    # Vérifier statut Rosetta
    local rosetta_installed=false
    local rosetta_running=false
    
    if [[ -e "/Library/Apple/usr/share/rosetta" ]]; then
        rosetta_installed=true
    fi
    
    if /bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper" >/dev/null; then
        rosetta_running=true
    fi
    
    if [[ "$output_format" == "json" ]]; then
        {
            echo "{"
            echo "  \"rapport_compatibilite\": {"
            echo "    \"genere\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\","
            echo "    \"nom_hote\": \"$hostname\","
            echo "    \"info_systeme\": {"
            echo "      \"modele\": \"$mac_model\","
            echo "      \"puce\": \"$mac_chip\","
            echo "      \"version_macos\": \"$macos_version\","
            echo "      \"architecture\": \"$cpu_arch\""
            echo "    },"
            echo "    \"statut_rosetta\": {"
            echo "      \"installe\": $rosetta_installed,"
            echo "      \"en_cours\": $rosetta_running,"
            echo "      \"requis\": $([[ "$cpu_arch" == "arm64" ]] && echo "true" || echo "false")"
            echo "    }"
            echo "  }"
            echo "}"
        } > "$report_file"
    else
        {
            echo "Rapport Compatibilité MacFleet"
            echo "=============================="
            echo "Généré : $(date)"
            echo "Nom hôte : $hostname"
            echo ""
            echo "Informations Système :"
            echo "- Modèle : $mac_model"
            echo "- Puce : $mac_chip"
            echo "- Version macOS : $macos_version"
            echo "- Architecture : $cpu_arch"
            echo ""
            echo "Statut Rosetta 2 :"
            echo "- Installé : $([[ "$rosetta_installed" == "true" ]] && echo "Oui" || echo "Non")"
            echo "- En cours : $([[ "$rosetta_running" == "true" ]] && echo "Oui" || echo "Non")"
            echo "- Requis : $([[ "$cpu_arch" == "arm64" ]] && echo "Oui" || echo "Non")"
        } > "$report_file"
    fi
    
    echo "✅ Rapport généré : $report_file"
    echo ""
    echo "=== Résumé Rapport ==="
    echo "Nom hôte : $hostname"
    echo "Architecture : $cpu_arch"
    echo "Rosetta installé : $([[ "$rosetta_installed" == "true" ]] && echo "Oui" || echo "Non")"
    echo "Rosetta en cours : $([[ "$rosetta_running" == "true" ]] && echo "Oui" || echo "Non")"
}

# Exemples utilisation
echo "Exemples Gestionnaire Compatibilité Entreprise :"
echo "================================================"
echo ""

echo "1. Déployer Rosetta flotte :"
enterprise_compatibility_manager "deploy" "system"
echo ""

echo "2. Surveiller compatibilité applications :"
enterprise_compatibility_manager "monitor"
echo ""

echo "3. Générer rapport compatibilité :"
enterprise_compatibility_manager "report" "system" "json"

Notes Importantes

Fonctionnalités Entreprise

  • Déploiement Flotte - Installation Rosetta automatisée sur Mac Apple Silicon
  • Vérification Compatibilité Complète - Analyse système approfondie et validation
  • Surveillance Architecture Applications - Suivi compatibilité apps Intel vs Apple Silicon
  • Optimisation Performance - Surveiller et optimiser performance traduction Rosetta
  • Rapports Entreprise - Rapports compatibilité détaillés pour gestion flotte
  • Audit et Conformité - Suivi déploiement et utilisation Rosetta sur appareils

Gestion Compatibilité

  • Détection Architecture - Identification précise Apple Silicon vs Intel
  • Validation Version macOS - Assurer exigences compatibilité Rosetta 2
  • Vérifications Pré-Installation - Vérifier espace disque, réseau et exigences système
  • Validation Post-Installation - Tests complets après déploiement
  • Analyse Applications - Identifier quelles apps nécessitent traduction Rosetta

Fonctionnalités Performance

  • Surveillance Traduction - Suivre impact performance Rosetta
  • Optimisation Applications - Recommandations alternatives apps Intel
  • Suivi Utilisation Ressources - Surveiller ressources système pendant traduction
  • Tests Performance - Outils comparaison performance apps traduites

Exemples d'Utilisation

# Installation Rosetta basique
# Déterminer architecture appareil macOS
processorBrand=$(/usr/sbin/sysctl -n machdep.cpu.brand_string)
if [[ "${processorBrand}" = *"Apple"* ]]; then
    echo "Processeur Apple présent."
else
    echo "Processeur Apple non présent. Rosetta non requis."
    exit 0
fi

# Vérifier si Rosetta installé
checkRosettaStatus=$(/bin/launchctl list | /usr/bin/grep "com.apple.oahd-root-helper")
RosettaFolder="/Library/Apple/usr/share/rosetta"
if [[ -e "${RosettaFolder}" && "${checkRosettaStatus}" != "" ]]; then
    echo "Dossier Rosetta existe et Service Rosetta en cours. Sortie..."
    exit 0
else
    echo "Dossier Rosetta n'existe pas ou service Rosetta non en cours. Installation Rosetta..."
fi

# Installer Rosetta
/usr/sbin/softwareupdate --install-rosetta --agree-to-license

# Installation MacFleet améliorée
install_rosetta_basic

# Déploiement entreprise
enterprise_compatibility_manager "deploy" "system"

# Surveiller compatibilité applications
enterprise_compatibility_manager "monitor"

Sonnerie à Distance et Gestion de Localisation d'Appareils sur macOS

Gérez la localisation d'appareils et les alertes audio sur vos appareils MacFleet avec une fonctionnalité de sonnerie à distance complète, le suivi de localisation et les solutions de récupération d'appareils d'entreprise. Ce tutoriel couvre l'implémentation de sonnerie à distance, la gestion audio et les services de localisation d'appareils à l'échelle de la flotte.

Comprendre la Sonnerie à Distance et la Localisation d'Appareils

La fonctionnalité de sonnerie à distance sur macOS fournit des capacités essentielles de localisation d'appareils :

  • Alertes Audio - Jouer des sons pour aider à localiser les appareils à proximité
  • Localisation d'Appareils - Trouver les appareils égarés ou perdus dans les environnements d'entreprise
  • Gestion de Flotte - Suivi et récupération d'appareils centralisés
  • Amélioration de Sécurité - Capacités anti-vol et de récupération d'appareils

Cas d'Usage d'Entreprise

La sonnerie à distance et les services de localisation bénéficient aux environnements d'entreprise :

  • Récupération d'Actifs - Localiser rapidement les appareils égarés dans de grands bureaux
  • Réponse de Sécurité - Alertes audio pour la prévention du vol et la récupération d'appareils
  • Gestion d'Inventaire - Suivre les emplacements d'appareils pendant les audits et transitions
  • Protocoles d'Urgence - Localiser les appareils pendant les évacuations ou urgences
  • Assistance Utilisateur - Aider les utilisateurs à trouver leurs appareils sans intervention IT

Implémentation de Base de Sonnerie à Distance

Script Simple de Sonnerie à Distance

#!/bin/bash

# Implémentation basique de sonnerie à distance
basic_remote_ring() {
    local ring_count="${1:-5}"
    local sound_file="${2:-/System/Library/Sounds/Submarine.aiff}"
    
    echo "=== Sonnerie à Distance Basique ==="
    echo "Nombre de sonneries : $ring_count"
    echo "Fichier son : $sound_file"
    echo ""
    
    # Valider que le fichier son existe
    if [[ ! -f "$sound_file" ]]; then
        echo "Erreur : Fichier son non trouvé : $sound_file"
        echo "Utilisation du son système par défaut..."
        sound_file="/System/Library/Sounds/Ping.aiff"
    fi
    
    # Exécuter la sonnerie à distance
    local count=1
    while [[ $count -le $ring_count ]]; do
        echo "Sonnerie $count sur $ring_count"
        afplay "$sound_file"
        count=$(( count + 1 ))
        
        # Ajouter un petit délai entre les sonneries pour une meilleure séparation audio
        sleep 1
    done
    
    echo "Sonnerie à distance terminée : $ring_count sonneries jouées"
}

# Sonnerie à distance améliorée avec validation
enhanced_remote_ring() {
    local ring_count="${1:-5}"
    local sound_file="${2:-/System/Library/Sounds/Submarine.aiff}"
    local volume_level="${3:-75}"
    
    echo "=== Sonnerie à Distance Améliorée ==="
    echo "Nombre de sonneries : $ring_count"
    echo "Fichier son : $sound_file"
    echo "Niveau de volume : $volume_level%"
    echo ""
    
    # Définir le volume système
    osascript -e "set volume output volume $volume_level"
    
    # Valider les paramètres
    if [[ $ring_count -lt 1 || $ring_count -gt 50 ]]; then
        echo "Avertissement : Le nombre de sonneries doit être entre 1 et 50, utilisation par défaut de 5"
        ring_count=5
    fi
    
    # Jouer les sonneries avec retour amélioré
    local count=1
    while [[ $count -le $ring_count ]]; do
        echo "Sonnerie $count/$ring_count - $(date '+%H:%M:%S')"
        
        if afplay "$sound_file" 2>/dev/null; then
            echo "✓ Sonnerie jouée avec succès"
        else
            echo "✗ Échec de lecture de sonnerie"
        fi
        
        count=$(( count + 1 ))
        
        # Délai progressif (plus court pour plusieurs sonneries)
        if [[ $ring_count -gt 1 ]]; then
            sleep 0.5
        fi
    done
    
    echo "Sonnerie à distance améliorée terminée à $(date '+%H:%M:%S')"
}

# Exemples d'utilisation
# basic_remote_ring 3
# enhanced_remote_ring 5 "/System/Library/Sounds/Glass.aiff" 80

Sons Système Disponibles

#!/bin/bash

# Lister et tester les sons système disponibles
list_system_sounds() {
    echo "=== Sons Système Disponibles ==="
    echo "Emplacement : /System/Library/Sounds/"
    echo ""
    
    local sounds_dir="/System/Library/Sounds"
    
    if [[ -d "$sounds_dir" ]]; then
        echo "Fichiers son disponibles :"
        ls -1 "$sounds_dir"/*.aiff 2>/dev/null | while read -r sound_file; do
            local sound_name=$(basename "$sound_file" .aiff)
            echo "  - $sound_name"
        done
    else
        echo "Répertoire des sons système non trouvé"
    fi
    
    echo ""
    echo "Choix populaires pour sonnerie à distance :"
    echo "  - Submarine.aiff (profond, attire l'attention)"
    echo "  - Glass.aiff (clair, distinctif)"
    echo "  - Ping.aiff (aigu, remarquable)"
    echo "  - Sosumi.aiff (son Mac classique)"
    echo "  - Purr.aiff (option plus douce)"
}

# Tester un fichier son spécifique
test_sound_file() {
    local sound_file="$1"
    
    if [[ -z "$sound_file" ]]; then
        echo "Usage : test_sound_file <chemin_fichier_son>"
        return 1
    fi
    
    echo "Test du fichier son : $sound_file"
    
    if [[ -f "$sound_file" ]]; then
        echo "Lecture du son de test..."
        afplay "$sound_file"
        echo "✓ Test de son terminé"
    else
        echo "✗ Fichier son non trouvé : $sound_file"
        return 1
    fi
}

# Usage
list_system_sounds

Gestion du Volume et Audio

#!/bin/bash

# Gérer le volume système pour sonnerie à distance
manage_system_volume() {
    local action="${1:-get}"
    local volume_level="${2:-50}"
    
    case "$action" in
        "get")
            echo "=== Volume Système Actuel ==="
            local current_volume=$(osascript -e "output volume of (get volume settings)")
            echo "Volume actuel : $current_volume%"
            
            # Vérifier si en sourdine
            local mute_status=$(osascript -e "output muted of (get volume settings)")
            if [[ "$mute_status" == "true" ]]; then
                echo "Statut : EN SOURDINE"
            else
                echo "Statut : SON ACTIVÉ"
            fi
            ;;
        "set")
            echo "=== Définition Volume Système ==="
            echo "Volume cible : $volume_level%"
            
            # Désactiver sourdine si activée
            osascript -e "set volume without output muted"
            
            # Définir le niveau de volume
            osascript -e "set volume output volume $volume_level"
            
            echo "✓ Volume défini à $volume_level%"
            ;;
        "mute")
            echo "=== Mise en Sourdine Système ==="
            osascript -e "set volume with output muted"
            echo "✓ Système mis en sourdine"
            ;;
        "unmute")
            echo "=== Désactivation Sourdine Système ==="
            osascript -e "set volume without output muted"
            echo "✓ Sourdine système désactivée"
            ;;
        "max")
            echo "=== Définition Volume Maximum ==="
            osascript -e "set volume without output muted"
            osascript -e "set volume output volume 100"
            echo "✓ Volume défini au maximum (100%)"
            ;;
        *)
            echo "Usage : manage_system_volume [get|set|mute|unmute|max] [niveau_volume]"
            return 1
            ;;
    esac
}

# Surcharge de volume d'urgence pour sonnerie à distance
emergency_volume_override() {
    echo "=== Surcharge de Volume d'Urgence ==="
    echo "Surcharge de tous les paramètres audio pour audibilité maximale"
    
    # Stocker les paramètres actuels
    local current_volume=$(osascript -e "output volume of (get volume settings)")
    local current_mute=$(osascript -e "output muted of (get volume settings)")
    
    echo "Paramètres actuels sauvegardés - Volume : $current_volume%, Sourdine : $current_mute"
    
    # Définir le volume d'urgence
    osascript -e "set volume without output muted"
    osascript -e "set volume output volume 100"
    
    echo "✓ Volume d'urgence activé (100%, son activé)"
    
    # Fonction de retour pour restaurer les paramètres
    echo "Pour restaurer les paramètres précédents, exécuter :"
    echo "osascript -e \"set volume output volume $current_volume\""
    if [[ "$current_mute" == "true" ]]; then
        echo "osascript -e \"set volume with output muted\""
    fi
}

# Usage
manage_system_volume "get"

Fonctionnalités Avancées de Sonnerie à Distance

Système de Sonnerie à Distance Intelligent

#!/bin/bash

# Sonnerie à distance intelligente avec comportement adaptatif
intelligent_remote_ring() {
    local ring_pattern="${1:-standard}"
    local duration="${2:-30}"
    local priority_level="${3:-normal}"
    
    echo "=== Système de Sonnerie à Distance Intelligent ==="
    echo "Motif : $ring_pattern"
    echo "Durée : ${duration}s"
    echo "Priorité : $priority_level"
    echo ""
    
    # Définir le volume basé sur la priorité
    case "$priority_level" in
        "low")
            local volume=40
            local sound="/System/Library/Sounds/Purr.aiff"
            ;;
        "normal")
            local volume=70
            local sound="/System/Library/Sounds/Submarine.aiff"
            ;;
        "high")
            local volume=85
            local sound="/System/Library/Sounds/Glass.aiff"
            ;;
        "emergency")
            local volume=100
            local sound="/System/Library/Sounds/Sosumi.aiff"
            emergency_volume_override
            ;;
        *)
            local volume=70
            local sound="/System/Library/Sounds/Submarine.aiff"
            ;;
    esac
    
    # Définir le volume système
    osascript -e "set volume output volume $volume"
    
    # Exécuter le motif de sonnerie
    case "$ring_pattern" in
        "standard")
            standard_ring_pattern "$duration" "$sound"
            ;;
        "pulse")
            pulse_ring_pattern "$duration" "$sound"
            ;;
        "escalating")
            escalating_ring_pattern "$duration" "$sound"
            ;;
        "morse_sos")
            morse_sos_pattern "$duration" "$sound"
            ;;
        "heartbeat")
            heartbeat_pattern "$duration" "$sound"
            ;;
        *)
            echo "Motif inconnu : $ring_pattern, utilisation standard"
            standard_ring_pattern "$duration" "$sound"
            ;;
    esac
}

# Motif de sonnerie standard
standard_ring_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Lecture motif sonnerie standard pour ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        afplay "$sound"
        sleep 2
    done
}

# Motif de sonnerie pulsée (rafales rapides)
pulse_ring_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Lecture motif sonnerie pulsée pour ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        # Triple pulsation
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.3
        done
        sleep 2
    done
}

# Motif de sonnerie croissante (fréquence augmentant)
escalating_ring_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    local sleep_interval=3
    
    echo "Lecture motif sonnerie croissante pour ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        afplay "$sound"
        sleep $sleep_interval
        
        # Diminuer l'intervalle (augmenter la fréquence)
        if [[ $sleep_interval -gt 1 ]]; then
            sleep_interval=$((sleep_interval - 1))
        fi
    done
}

# Motif code Morse SOS
morse_sos_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Lecture motif Morse SOS pour ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        # S (3 courts)
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.2
            sleep 0.3
        done
        sleep 0.5
        
        # O (3 longs)
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.6
            sleep 0.3
        done
        sleep 0.5
        
        # S (3 courts)
        for i in {1..3}; do
            afplay "$sound" &
            sleep 0.2
            sleep 0.3
        done
        
        sleep 3
    done
}

# Motif battement de cœur
heartbeat_pattern() {
    local duration="$1"
    local sound="$2"
    local end_time=$(($(date +%s) + duration))
    
    echo "Lecture motif battement de cœur pour ${duration}s"
    
    while [[ $(date +%s) -lt $end_time ]]; do
        # Double battement
        afplay "$sound" &
        sleep 0.2
        afplay "$sound" &
        sleep 1.5
    done
}

# Exemples d'utilisation
# intelligent_remote_ring "pulse" 30 "high"
# intelligent_remote_ring "morse_sos" 60 "emergency"

Gestion de Sonnerie Basée sur la Localisation

#!/bin/bash

# Sonnerie à distance consciente de la localisation
location_based_ring() {
    local location_context="${1:-office}"
    local time_context="${2:-business_hours}"
    
    echo "=== Gestion de Sonnerie Basée sur la Localisation ==="
    echo "Contexte de localisation : $location_context"
    echo "Contexte temporel : $time_context"
    echo ""
    
    # Déterminer les paramètres de sonnerie appropriés basés sur le contexte
    case "$location_context" in
        "office")
            handle_office_environment "$time_context"
            ;;
        "meeting_room")
            handle_meeting_room_environment "$time_context"
            ;;
        "public_space")
            handle_public_space_environment "$time_context"
            ;;
        "home_office")
            handle_home_office_environment "$time_context"
            ;;
        "warehouse")
            handle_warehouse_environment "$time_context"
            ;;
        *)
            echo "Contexte de localisation inconnu, utilisation paramètres par défaut"
            intelligent_remote_ring "standard" 30 "normal"
            ;;
    esac
}

# Paramètres environnement bureau
handle_office_environment() {
    local time_context="$1"
    
    echo "Configuration pour environnement bureau..."
    
    case "$time_context" in
        "business_hours")
            # Volume modéré, son professionnel
            intelligent_remote_ring "standard" 20 "normal"
            ;;
        "after_hours")
            # Volume plus élevé, plus accrocheur
            intelligent_remote_ring "escalating" 45 "high"
            ;;
        "lunch_break")
            # Approche plus douce pendant les pauses
            intelligent_remote_ring "pulse" 25 "low"
            ;;
    esac
}

# Paramètres environnement salle de réunion
handle_meeting_room_environment() {
    local time_context="$1"
    
    echo "Configuration pour environnement salle de réunion..."
    
    # Toujours utiliser paramètres discrets dans les zones de réunion
    intelligent_remote_ring "heartbeat" 15 "low"
}

# Paramètres environnement espace public
handle_public_space_environment() {
    local time_context="$1"
    
    echo "Configuration pour environnement espace public..."
    
    # Discret mais efficace
    intelligent_remote_ring "pulse" 30 "normal"
}

# Paramètres environnement bureau à domicile
handle_home_office_environment() {
    local time_context="$1"
    
    echo "Configuration pour environnement bureau à domicile..."
    
    case "$time_context" in
        "business_hours")
            # Peut être plus assertif à domicile
            intelligent_remote_ring "escalating" 40 "high"
            ;;
        "evening")
            # Respectueux du foyer
            intelligent_remote_ring "standard" 20 "low"
            ;;
    esac
}

# Paramètres environnement entrepôt
handle_warehouse_environment() {
    local time_context="$1"
    
    echo "Configuration pour environnement entrepôt..."
    
    # Environnement bruyant nécessite volume maximum
    intelligent_remote_ring "morse_sos" 60 "emergency"
}

# Usage
# location_based_ring "office" "business_hours"

Système de Gestion de Sonnerie à Distance d'Entreprise

#!/bin/bash

# Outil de Gestion de Sonnerie à Distance et Localisation d'Appareils MacFleet
# Localisation d'appareils complète, alertes audio et suivi de flotte

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_remote_ring.log"
REPORT_DIR="/etc/macfleet/reports/location"
CONFIG_DIR="/etc/macfleet/location"
SOUND_DIR="/etc/macfleet/sounds"
POLICY_DIR="/etc/macfleet/policies/location"

# Créer les répertoires s'ils n'existent pas
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$SOUND_DIR" "$POLICY_DIR"

# Politiques de sonnerie pour différents scénarios
declare -A RING_POLICIES=(
    ["standard_office"]="volume:70,pattern:standard,duration:30,sound:submarine"
    ["quiet_environment"]="volume:40,pattern:pulse,duration:15,sound:purr"
    ["emergency_locate"]="volume:100,pattern:morse_sos,duration:120,sound:sosumi"
    ["meeting_room"]="volume:30,pattern:heartbeat,duration:10,sound:glass"
    ["warehouse_floor"]="volume:100,pattern:escalating,duration:60,sound:submarine"
    ["public_area"]="volume:60,pattern:pulse,duration:25,sound:ping"
    ["after_hours"]="volume:85,pattern:escalating,duration:45,sound:glass"
    ["healthcare_facility"]="volume:50,pattern:heartbeat,duration:20,sound:purr"
    ["education_campus"]="volume:65,pattern:standard,duration:30,sound:ping"
    ["retail_store"]="volume:75,pattern:pulse,duration:35,sound:submarine"
)

# Configurations de suivi de localisation
declare -A LOCATION_CONFIGS=(
    ["high_security"]="gps_tracking,wifi_triangulation,bluetooth_beacons,audit_logging"
    ["standard_office"]="wifi_tracking,bluetooth_detection,basic_logging"
    ["public_access"]="limited_tracking,privacy_compliant,minimal_logging"
    ["healthcare"]="hipaa_compliant,secure_tracking,encrypted_logs,audit_trail"
    ["education"]="ferpa_compliant,student_privacy,controlled_tracking,parent_notification"
    ["retail"]="customer_privacy,basic_tracking,loss_prevention,inventory_integration"
)

# Niveaux de réponse d'urgence
declare -A EMERGENCY_LEVELS=(
    ["green"]="normal_operation,standard_ring,basic_logging"
    ["yellow"]="elevated_response,enhanced_ring,increased_logging"
    ["orange"]="urgent_response,emergency_ring,comprehensive_logging"
    ["red"]="critical_response,maximum_ring,full_audit_trail"
)

# Fonction de journalisation
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"
}

# Sonnerie à distance d'entreprise avec gestion complète
enterprise_remote_ring() {
    local device_id="${1:-$(hostname)}"
    local ring_policy="${2:-standard_office}"
    local location_context="${3:-office}"
    local emergency_level="${4:-green}"
    local initiated_by="${5:-$(whoami)}"
    
    log_action "Démarrage sonnerie à distance d'entreprise" "INFO"
    log_action "Appareil : $device_id, Politique : $ring_policy, Contexte : $location_context" "INFO"
    
    echo "=== Gestion de Sonnerie à Distance d'Entreprise ==="
    echo "ID Appareil : $device_id"
    echo "Politique de Sonnerie : $ring_policy"
    echo "Contexte de Localisation : $location_context"
    echo "Niveau d'Urgence : $emergency_level"
    echo "Initié Par : $initiated_by"
    echo "ID Sonnerie : $(uuidgen)"
    echo ""
    
    # Analyser la politique de sonnerie
    local policy_settings="${RING_POLICIES[$ring_policy]}"
    if [[ -z "$policy_settings" ]]; then
        log_action "Politique de sonnerie inconnue : $ring_policy, utilisation standard_office" "WARNING"
        policy_settings="${RING_POLICIES[standard_office]}"
    fi
    
    # Extraire les paramètres de politique
    local volume=$(echo "$policy_settings" | grep -o 'volume:[0-9]*' | cut -d: -f2)
    local pattern=$(echo "$policy_settings" | grep -o 'pattern:[^,]*' | cut -d: -f2)
    local duration=$(echo "$policy_settings" | grep -o 'duration:[0-9]*' | cut -d: -f2)
    local sound=$(echo "$policy_settings" | grep -o 'sound:[^,]*' | cut -d: -f2)
    
    echo "--- Configuration de Politique ---"
    echo "Volume : $volume%"
    echo "Motif : $pattern"
    echo "Durée : ${duration}s"
    echo "Son : $sound"
    
    # Appliquer les modifications de niveau d'urgence
    apply_emergency_modifications "$emergency_level" volume pattern duration
    
    # Exécuter les vérifications pré-sonnerie
    if ! pre_ring_validation "$device_id" "$location_context"; then
        log_action "Validation pré-sonnerie échouée" "ERROR"
        return 1
    fi
    
    # Enregistrer l'initiation de sonnerie
    record_ring_event "$device_id" "$ring_policy" "$location_context" "$initiated_by" "started"
    
    # Exécuter la sonnerie basée sur la politique
    execute_policy_ring "$volume" "$pattern" "$duration" "$sound"
    
    # Enregistrer la fin de sonnerie
    record_ring_event "$device_id" "$ring_policy" "$location_context" "$initiated_by" "completed"
    
    # Générer le rapport de localisation
    generate_location_report "$device_id" "$ring_policy" "$location_context"
    
    log_action "Sonnerie à distance d'entreprise terminée pour appareil : $device_id" "INFO"
}

# Appliquer les modifications de niveau d'urgence
apply_emergency_modifications() {
    local emergency_level="$1"
    local -n vol_ref=$2
    local -n pat_ref=$3
    local -n dur_ref=$4
    
    echo "--- Niveau d'Urgence : $emergency_level ---"
    
    case "$emergency_level" in
        "yellow")
            vol_ref=$((vol_ref + 15))
            dur_ref=$((dur_ref + 10))
            echo "Réponse améliorée : Volume +15%, Durée +10s"
            ;;
        "orange")
            vol_ref=$((vol_ref + 25))
            dur_ref=$((dur_ref + 20))
            pat_ref="escalating"
            echo "Réponse urgente : Volume +25%, Durée +20s, Motif croissant"
            ;;
        "red")
            vol_ref=100
            dur_ref=$((dur_ref * 2))
            pat_ref="morse_sos"
            echo "Réponse critique : Volume maximum, Durée double, Motif SOS"
            ;;
    esac
    
    # Limiter le volume à 100%
    if [[ $vol_ref -gt 100 ]]; then
        vol_ref=100
    fi
}

# Validation pré-sonnerie
pre_ring_validation() {
    local device_id="$1"
    local location_context="$2"
    
    echo "--- Validation Pré-Sonnerie ---"
    
    # Vérifier la disponibilité du système audio
    if ! command -v afplay >/dev/null 2>&1; then
        echo "✗ Système audio non disponible"
        log_action "Vérification système audio échouée" "ERROR"
        return 1
    fi
    
    # Vérifier si l'appareil est en mode ne pas déranger
    local dnd_status=$(defaults read ~/Library/Preferences/ByHost/com.apple.notificationcenterui.* doNotDisturb 2>/dev/null || echo "0")
    if [[ "$dnd_status" == "1" ]]; then
        echo "⚠️ L'appareil est en mode Ne Pas Déranger"
        log_action "Appareil en mode NPD - sonnerie peut être en sourdine" "WARNING"
    fi
    
    # Vérifier le volume système
    local current_volume=$(osascript -e "output volume of (get volume settings)" 2>/dev/null || echo "50")
    echo "Volume système actuel : $current_volume%"
    
    # Vérifier si en sourdine
    local mute_status=$(osascript -e "output muted of (get volume settings)" 2>/dev/null || echo "false")
    if [[ "$mute_status" == "true" ]]; then
        echo "⚠️ Système actuellement en sourdine"
        log_action "Système en sourdine - sera surchargé pour sonnerie" "WARNING"
    fi
    
    # Validations spécifiques à la localisation
    case "$location_context" in
        "meeting_room")
            echo "Contexte salle de réunion - utilisation paramètres discrets"
            ;;
        "healthcare_facility")
            echo "Contexte santé - assurance conformité HIPAA"
            ;;
        "education_campus")
            echo "Contexte éducation - assurance niveaux de volume appropriés"
            ;;
    esac
    
    echo "✓ Validation pré-sonnerie terminée"
    return 0
}

# Exécuter la sonnerie basée sur la politique
execute_policy_ring() {
    local volume="$1"
    local pattern="$2"
    local duration="$3"
    local sound="$4"
    
    echo "--- Exécution de Sonnerie ---"
    
    # Mapper le nom du son vers le chemin de fichier
    local sound_file="/System/Library/Sounds/Submarine.aiff"  # Par défaut
    case "$sound" in
        "submarine") sound_file="/System/Library/Sounds/Submarine.aiff" ;;
        "glass") sound_file="/System/Library/Sounds/Glass.aiff" ;;
        "ping") sound_file="/System/Library/Sounds/Ping.aiff" ;;
        "sosumi") sound_file="/System/Library/Sounds/Sosumi.aiff" ;;
        "purr") sound_file="/System/Library/Sounds/Purr.aiff" ;;
    esac
    
    # Stocker les paramètres audio actuels
    local original_volume=$(osascript -e "output volume of (get volume settings)" 2>/dev/null || echo "50")
    local original_mute=$(osascript -e "output muted of (get volume settings)" 2>/dev/null || echo "false")
    
    # Définir le volume de sonnerie et désactiver sourdine
    osascript -e "set volume without output muted" 2>/dev/null
    osascript -e "set volume output volume $volume" 2>/dev/null
    
    echo "Paramètres sonnerie : Volume $volume%, Motif $pattern, Durée ${duration}s"
    echo "Heure de début : $(date '+%H:%M:%S')"
    
    # Exécuter le motif de sonnerie
    case "$pattern" in
        "standard")
            standard_ring_pattern "$duration" "$sound_file"
            ;;
        "pulse")
            pulse_ring_pattern "$duration" "$sound_file"
            ;;
        "escalating")
            escalating_ring_pattern "$duration" "$sound_file"
            ;;
        "morse_sos")
            morse_sos_pattern "$duration" "$sound_file"
            ;;
        "heartbeat")
            heartbeat_pattern "$duration" "$sound_file"
            ;;
    esac
    
    echo "Heure de fin : $(date '+%H:%M:%S')"
    
    # Restaurer les paramètres audio originaux
    osascript -e "set volume output volume $original_volume" 2>/dev/null
    if [[ "$original_mute" == "true" ]]; then
        osascript -e "set volume with output muted" 2>/dev/null
    fi
    
    echo "✓ Paramètres audio originaux restaurés"
}

# Enregistrer les événements de sonnerie pour piste d'audit
record_ring_event() {
    local device_id="$1"
    local ring_policy="$2"
    local location_context="$3"
    local initiated_by="$4"
    local event_type="$5"
    
    local timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
    local event_file="$CONFIG_DIR/ring_events.log"
    
    echo "$timestamp,$device_id,$ring_policy,$location_context,$initiated_by,$event_type" >> "$event_file"
    
    log_action "Événement sonnerie enregistré : $event_type pour appareil $device_id" "INFO"
}

# Générer un rapport de localisation complet
generate_location_report() {
    local device_id="$1"
    local ring_policy="$2"
    local location_context="$3"
    
    local report_file="$REPORT_DIR/location_report_${device_id}_$(date +%Y%m%d_%H%M%S).json"
    
    # Obtenir les informations de localisation système (si disponibles)
    local wifi_network=$(networksetup -getairportnetwork en0 2>/dev/null | cut -d: -f2 | sed 's/^ *//' || echo "Inconnu")
    local ip_address=$(ifconfig en0 | grep "inet " | awk '{print $2}' || echo "Inconnu")
    
    cat > "$report_file" << EOF
{
    "location_report": {
        "report_metadata": {
            "report_id": "$(uuidgen)",
            "generated_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
            "device_id": "$device_id",
            "hostname": "$(hostname)",
            "script_version": "$SCRIPT_VERSION"
        },
        "ring_details": {
            "ring_policy": "$ring_policy",
            "location_context": "$location_context",
            "execution_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
        },
        "location_information": {
            "wifi_network": "$wifi_network",
            "ip_address": "$ip_address",
            "system_timezone": "$(date +%Z)",
            "estimated_location": "$location_context"
        },
        "system_information": {
            "os_version": "$(sw_vers -productVersion)",
            "hardware_model": "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk '{print $3}')",
            "audio_devices": "$(system_profiler SPAudioDataType | grep -A1 'Audio Devices:' | tail -1 | sed 's/^[ ]*//')"
        }
    }
}
EOF
    
    echo "Rapport de localisation généré : $report_file"
    log_action "Rapport de localisation généré : $report_file" "INFO"
}

# Gestion de sonnerie de flotte
fleet_ring_management() {
    local operation="$1"
    local device_list="$2"
    local ring_policy="${3:-standard_office}"
    local emergency_level="${4:-green}"
    
    echo "=== Gestion de Sonnerie de Flotte ==="
    echo "Opération : $operation"
    echo "Politique de Sonnerie : $ring_policy"
    echo "Niveau d'Urgence : $emergency_level"
    echo ""
    
    case "$operation" in
        "mass_ring")
            echo "Exécution opération sonnerie de masse..."
            IFS=',' read -ra DEVICES <<< "$device_list"
            for device in "${DEVICES[@]}"; do
                echo "Sonnerie appareil : $device"
                enterprise_remote_ring "$device" "$ring_policy" "office" "$emergency_level"
                sleep 2  # Délai entre appareils
            done
            ;;
        "emergency_locate")
            echo "Protocole de localisation d'urgence activé..."
            enterprise_remote_ring "$(hostname)" "emergency_locate" "unknown" "red"
            ;;
        "zone_ring")
            echo "Opération sonnerie basée sur zone..."
            # Implémentation pour sonnerie basée sur zone
            ;;
        *)
            echo "Opération inconnue : $operation"
            return 1
            ;;
    esac
}

# Fonction d'exécution principale
main() {
    local action="${1:-help}"
    local param1="${2:-}"
    local param2="${3:-}"
    local param3="${4:-}"
    local param4="${5:-}"
    local param5="${6:-}"
    
    log_action "=== Gestion de Sonnerie à Distance MacFleet Démarrée ===" "INFO"
    log_action "Action : $action" "INFO"
    
    case "$action" in
        "ring")
            if [[ -z "$param1" ]]; then
                param1="$(hostname)"
            fi
            enterprise_remote_ring "$param1" "$param2" "$param3" "$param4" "$param5"
            ;;
        "emergency")
            echo "Sonnerie d'urgence activée pour appareil actuel"
            enterprise_remote_ring "$(hostname)" "emergency_locate" "unknown" "red" "$(whoami)"
            ;;
        "test")
            echo "Test du système audio..."
            test_sound_file "/System/Library/Sounds/Ping.aiff"
            ;;
        "volume")
            if [[ -z "$param1" ]]; then
                manage_system_volume "get"
            else
                manage_system_volume "$param1" "$param2"
            fi
            ;;
        "sounds")
            list_system_sounds
            ;;
        "fleet")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 fleet <opération> [liste_appareils] [politique] [niveau_urgence]"
                echo "Opérations : mass_ring, emergency_locate, zone_ring"
                exit 1
            fi
            fleet_ring_management "$param1" "$param2" "$param3" "$param4"
            ;;
        "help")
            echo "Usage : $0 [action] [options...]"
            echo "Actions :"
            echo "  ring [id_appareil] [politique] [localisation] [niveau_urgence] [initié_par] - Exécuter sonnerie à distance"
            echo "  emergency - Sonnerie d'urgence pour appareil actuel"
            echo "  test - Tester le système audio"
            echo "  volume [action] [niveau] - Gérer le volume système"
            echo "  sounds - Lister les sons système disponibles"
            echo "  fleet <opération> [liste_appareils] [politique] [niveau_urgence] - Opérations de flotte"
            echo "  help - Afficher cette aide"
            echo ""
            echo "Politiques de Sonnerie : ${!RING_POLICIES[*]}"
            echo "Niveaux d'Urgence : ${!EMERGENCY_LEVELS[*]}"
            ;;
        *)
            log_action "ERREUR : Action inconnue : $action" "ERROR"
            echo "Utilisez '$0 help' pour les informations d'utilisation"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion de sonnerie à distance terminée ===" "INFO"
}

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

Considérations Importantes

Exigences du Système Audio

  • Commande afplay - Lecteur audio intégré de macOS pour lecture de fichiers son
  • Sons Système - Situés dans le répertoire /System/Library/Sounds/
  • Contrôle de Volume - Utilise AppleScript pour gestion du volume système
  • Permissions Audio - Certaines fonctionnalités peuvent nécessiter des permissions d'entrée/sortie audio

Notes de Déploiement d'Entreprise

  • Latence Réseau - Les commandes de sonnerie à distance peuvent avoir des délais réseau
  • États d'Appareils - Les appareils peuvent être en veille, en sourdine ou en mode ne pas déranger
  • Conformité de Confidentialité - Le suivi de localisation doit respecter les réglementations de confidentialité
  • Protocoles d'Urgence - Les sonneries d'urgence doivent outrepasser les restrictions de volume normales
  • Coordination de Flotte - Les opérations de sonnerie de masse doivent être échelonnées pour éviter les conflits

Considérations de Sécurité

  • Contrôle d'Accès - La fonctionnalité de sonnerie doit être restreinte aux administrateurs autorisés
  • Journalisation d'Audit - Toutes les opérations de sonnerie doivent être journalisées pour sécurité et conformité
  • Confidentialité de Localisation - Les informations de localisation d'appareil doivent être traitées selon les politiques de confidentialité
  • Surcharge d'Urgence - Les situations d'urgence peuvent nécessiter de contourner les restrictions normales