Guide

Nouvelles mises à jour et améliorations de Roundfleet.

Gestion des Jetons Sécurisés sur macOS

Gérez les jetons sécurisés sur vos appareils Roundfleet pour activer le chiffrement FileVault, les opérations de démarrage sécurisé et l'authentification cryptographique. Ce tutoriel couvre la vérification, l'octroi, la suppression des jetons sécurisés et la gestion à l'échelle de l'entreprise pour une conformité sécuritaire renforcée.

Comprendre les Jetons Sécurisés

Les jetons sécurisés sont des identifiants cryptographiques qui permettent aux utilisateurs d'effectuer des opérations sensibles au niveau sécurité sur macOS, particulièrement essentiels pour le chiffrement de disque FileVault :

Que sont les Jetons Sécurisés ?

  • Clés Cryptographiques - Permettent l'accès au stockage chiffré et aux fonctions de sécurité
  • Exigence FileVault - Requis pour que les utilisateurs puissent déverrouiller les disques chiffrés FileVault
  • Jetons Bootstrap - Facilitent le démarrage sécurisé et les processus de récupération système
  • Pont d'Authentification - Connectent les identifiants utilisateur aux opérations de sécurité système
  • Compatibilité Legacy - Remplacent les anciens mécanismes d'authentification dans macOS moderne

Exigences des Jetons Sécurisés

  • macOS 10.13+ - High Sierra et versions ultérieures supportent les jetons sécurisés
  • Privilèges Admin - L'octroi de jetons nécessite un admin existant avec jeton sécurisé
  • Authentification Utilisateur - Mots de passe admin et utilisateur cible requis
  • Intégrité Système - SIP (System Integrity Protection) doit être correctement configuré
  • Propriété Volume - Les utilisateurs ont besoin de permissions d'accès volume appropriées

Vérification du Statut des Jetons Sécurisés

Vérifier le Statut d'un Utilisateur Individuel

#!/bin/bash

# Vérifier le statut du jeton sécurisé pour un utilisateur spécifique
check_user_secure_token() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        echo "❌ Utilisation : check_user_secure_token <nom_utilisateur>"
        return 1
    fi
    
    # Vérifier que l'utilisateur existe
    if ! id "$username" >/dev/null 2>&1; then
        echo "❌ L'utilisateur '$username' n'existe pas"
        return 1
    fi
    
    echo "🔍 Vérification du statut du jeton sécurisé pour l'utilisateur : $username"
    
    # Vérifier le statut du jeton sécurisé
    local token_status
    token_status=$(sysadminctl -secureTokenStatus "$username" 2>&1)
    
    if echo "$token_status" | grep -q "ENABLED"; then
        echo "✅ L'utilisateur '$username' a un jeton sécurisé activé"
        return 0
    elif echo "$token_status" | grep -q "DISABLED"; then
        echo "❌ L'utilisateur '$username' n'a pas de jeton sécurisé"
        return 1
    else
        echo "⚠️ Impossible de déterminer le statut du jeton sécurisé pour '$username'"
        echo "Sortie : $token_status"
        return 2
    fi
}

# Exemple d'utilisation
# check_user_secure_token "jean.dupont"

Vérifier le Statut de Tous les Utilisateurs

#!/bin/bash

# Vérifier le statut des jetons sécurisés pour tous les utilisateurs
check_all_users_secure_tokens() {
    echo "🔍 Vérification du statut des jetons sécurisés pour tous les utilisateurs..."
    echo ""
    
    local enabled_count=0
    local disabled_count=0
    local error_count=0
    
    # Obtenir tous les utilisateurs avec UID >= 500 (utilisateurs non-système)
    local users
    users=$(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}')
    
    printf "%-20s %-15s %-30s\n" "Nom d'utilisateur" "Statut" "Détails"
    printf "%-20s %-15s %-30s\n" "----------------" "------" "-------"
    
    for user in $users; do
        local status
        local details=""
        
        # Ignorer les comptes système qui pourraient avoir des UID élevés
        if [[ "$user" =~ ^(_|com\.|root|daemon|nobody) ]]; then
            continue
        fi
        
        # Vérifier le statut du jeton sécurisé
        local token_output
        token_output=$(sysadminctl -secureTokenStatus "$user" 2>&1)
        
        if echo "$token_output" | grep -q "ENABLED"; then
            status="✅ Activé"
            details="Jeton sécurisé actif"
            ((enabled_count++))
        elif echo "$token_output" | grep -q "DISABLED"; then
            status="❌ Désactivé"
            details="Pas de jeton sécurisé"
            ((disabled_count++))
        else
            status="⚠️ Erreur"
            details="Impossible de déterminer"
            ((error_count++))
        fi
        
        printf "%-20s %-15s %-30s\n" "$user" "$status" "$details"
    done
    
    echo ""
    echo "=== Résumé ==="
    echo "Utilisateurs avec jeton sécurisé : $enabled_count"
    echo "Utilisateurs sans jeton sécurisé : $disabled_count"
    echo "Erreurs/Inconnu : $error_count"
    
    # Recommandations
    if [[ "$disabled_count" -gt 0 ]]; then
        echo ""
        echo "💡 $disabled_count utilisateurs manquent de jetons sécurisés - considérez l'octroi pour l'accès FileVault"
    fi
    
    if [[ "$enabled_count" -eq 0 ]]; then
        echo ""
        echo "⚠️ Aucun utilisateur n'a de jetons sécurisés - le système peut avoir des limitations de sécurité"
    fi
}

# Exécuter la vérification
check_all_users_secure_tokens

Octroi de Jetons Sécurisés

Octroi Basique de Jeton Sécurisé

#!/bin/bash

# Accorder un jeton sécurisé à un utilisateur
grant_secure_token() {
    local admin_user="$1"
    local admin_password="$2"
    local target_user="$3"
    local target_password="$4"
    
    if [[ -z "$admin_user" || -z "$admin_password" || -z "$target_user" || -z "$target_password" ]]; then
        echo "❌ Utilisation : grant_secure_token <utilisateur_admin> <mot_de_passe_admin> <utilisateur_cible> <mot_de_passe_cible>"
        return 1
    fi
    
    echo "🔐 Octroi du jeton sécurisé à l'utilisateur : $target_user"
    
    # Vérifier que l'utilisateur admin a un jeton sécurisé
    echo "Vérification des identifiants admin..."
    local admin_token_status
    admin_token_status=$(sysadminctl -secureTokenStatus "$admin_user" 2>&1)
    
    if ! echo "$admin_token_status" | grep -q "ENABLED"; then
        echo "❌ L'utilisateur admin '$admin_user' n'a pas de jeton sécurisé"
        echo "Impossible d'accorder un jeton sécurisé sans un utilisateur admin qui en a déjà un"
        return 1
    fi
    
    echo "✅ L'utilisateur admin '$admin_user' a un jeton sécurisé"
    
    # Vérifier si l'utilisateur cible a déjà un jeton sécurisé
    echo "Vérification du statut de l'utilisateur cible..."
    local target_token_status
    target_token_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
    
    if echo "$target_token_status" | grep -q "ENABLED"; then
        echo "ℹ️ L'utilisateur '$target_user' a déjà un jeton sécurisé - aucune action nécessaire"
        return 0
    fi
    
    # Accorder le jeton sécurisé
    echo "Octroi du jeton sécurisé à '$target_user'..."
    
    if sysadminctl \
        -adminUser "$admin_user" \
        -adminPassword "$admin_password" \
        -secureTokenOn "$target_user" \
        -password "$target_password"; then
        
        echo "✅ Jeton sécurisé accordé avec succès à '$target_user'"
        
        # Vérifier que l'octroi a réussi
        echo "Vérification de l'octroi du jeton sécurisé..."
        local verify_status
        verify_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
        
        if echo "$verify_status" | grep -q "ENABLED"; then
            echo "✅ Vérification réussie - '$target_user' a maintenant un jeton sécurisé"
            return 0
        else
            echo "❌ Échec de la vérification - le jeton sécurisé n'a peut-être pas été accordé correctement"
            return 1
        fi
    else
        echo "❌ Échec de l'octroi du jeton sécurisé à '$target_user'"
        echo "Vérifiez les identifiants et les permissions utilisateur"
        return 1
    fi
}

Gestion Avancée des Jetons Sécurisés

#!/bin/bash

# Gestion avancée des jetons sécurisés avec validation
advanced_secure_token_grant() {
    local admin_user="$1"
    local admin_password="$2"
    local target_user="$3"
    local target_password="$4"
    local force_mode="${5:-false}"
    
    echo "🔐 Gestion Avancée des Jetons Sécurisés"
    echo "Utilisateur cible : $target_user"
    echo "Utilisateur admin : $admin_user"
    echo "Mode forcé : $force_mode"
    echo ""
    
    # Vérification de la version macOS
    local macos_version
    macos_version=$(sw_vers -productVersion)
    local macos_major
    macos_major=$(echo "$macos_version" | cut -d. -f1)
    local macos_minor
    macos_minor=$(echo "$macos_version" | cut -d. -f2)
    
    echo "Version macOS : $macos_version"
    
    # Vérifier la compatibilité macOS
    if [[ "$macos_major" -lt 10 ]] || [[ "$macos_major" -eq 10 && "$macos_minor" -lt 13 ]]; then
        echo "❌ Les jetons sécurisés nécessitent macOS 10.13 (High Sierra) ou ultérieur"
        echo "Version actuelle ($macos_version) non supportée"
        return 1
    fi
    
    # Vérifier que les utilisateurs existent
    if ! id "$admin_user" >/dev/null 2>&1; then
        echo "❌ L'utilisateur admin '$admin_user' n'existe pas"
        return 1
    fi
    
    if ! id "$target_user" >/dev/null 2>&1; then
        echo "❌ L'utilisateur cible '$target_user' n'existe pas"
        return 1
    fi
    
    # Vérifier si l'utilisateur admin est vraiment un administrateur
    if ! dseditgroup -o checkmember -m "$admin_user" admin >/dev/null 2>&1; then
        echo "❌ L'utilisateur '$admin_user' n'est pas membre du groupe admin"
        return 1
    fi
    
    echo "✅ Validation des utilisateurs réussie"
    
    # Vérifier le statut du jeton sécurisé pour l'admin
    local admin_token_status
    admin_token_status=$(sysadminctl -secureTokenStatus "$admin_user" 2>&1)
    
    if echo "$admin_token_status" | grep -q "DISABLED"; then
        # Gestion spéciale pour macOS 10.15+
        if [[ "$macos_major" -gt 10 ]] || [[ "$macos_major" -eq 10 && "$macos_minor" -gt 14 ]]; then
            echo "⚠️ Dans macOS 10.15+, les jetons sécurisés peuvent être accordés automatiquement"
            echo "   au premier utilisateur qui active FileVault si aucun autre utilisateur n'a de jetons"
            if [[ "$force_mode" != "true" ]]; then
                echo "   Utilisez force_mode=true pour contourner cette vérification"
                return 1
            fi
        else
            echo "❌ L'utilisateur admin '$admin_user' n'a pas de jeton sécurisé"
            echo "   Impossible d'accorder un jeton sans un admin qui en a déjà un"
            return 1
        fi
    else
        echo "✅ L'utilisateur admin '$admin_user' a un jeton sécurisé"
    fi
    
    # Vérifier le statut actuel de l'utilisateur cible
    local target_token_status
    target_token_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
    
    if echo "$target_token_status" | grep -q "ENABLED"; then
        echo "ℹ️ L'utilisateur '$target_user' a déjà un jeton sécurisé"
        if [[ "$force_mode" != "true" ]]; then
            echo "   Aucune action nécessaire"
            return 0
        else
            echo "   Mode forcé activé - tentera de rafraîchir le jeton"
        fi
    fi
    
    # Tenter d'accorder le jeton sécurisé
    echo ""
    echo "Octroi du jeton sécurisé à '$target_user'..."
    
    if sysadminctl \
        -adminUser "$admin_user" \
        -adminPassword "$admin_password" \
        -secureTokenOn "$target_user" \
        -password "$target_password" >/dev/null 2>&1; then
        
        echo "✅ Commande d'octroi de jeton sécurisé exécutée avec succès"
    else
        echo "❌ Échec de la commande d'octroi de jeton sécurisé"
        return 1
    fi
    
    # Vérifier le résultat
    echo "Vérification du statut du jeton sécurisé..."
    local final_status
    final_status=$(sysadminctl -secureTokenStatus "$target_user" 2>&1)
    
    if echo "$final_status" | grep -q "ENABLED"; then
        echo "✅ Vérification réussie - '$target_user' a maintenant un jeton sécurisé"
        
        # Informations supplémentaires
        echo ""
        echo "=== Informations Supplémentaires ==="
        echo "Éligibilité FileVault : L'utilisateur peut maintenant déverrouiller les volumes FileVault"
        echo "Opérations de sécurité : L'utilisateur peut effectuer des opérations cryptographiques"
        echo "Récupération système : L'utilisateur peut participer aux processus de démarrage sécurisé"
        
        return 0
    else
        echo "❌ Échec de la vérification - le jeton sécurisé n'a pas été accordé"
        echo "Ceci peut indiquer :"
        echo "  - Identifiants incorrects"
        echo "  - Restrictions de sécurité système"
        echo "  - Problèmes de configuration FileVault"
        return 1
    fi
}

Gestion d'Entreprise des Jetons Sécurisés

#!/bin/bash

# Outil de Gestion des Jetons Sécurisés Roundfleet
# Gestion complète des jetons sécurisés pour environnements d'entreprise

# Configuration
LOG_FILE="/var/log/roundfleet_securetoken.log"
REPORT_DIR="/var/reports/roundfleet/securetoken"
CONFIG_FILE="/etc/roundfleet/securetoken_policy.conf"
BACKUP_DIR="/var/backups/roundfleet/securetoken"

# Paramètres de politique
REQUIRE_SECURE_TOKENS=true
AUTO_GRANT_ON_CREATION=false
MINIMUM_ADMIN_TOKENS=2
ALERT_ON_TOKEN_LOSS=true
AUDIT_TOKEN_CHANGES=true

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

# Configurer les répertoires
setup_directories() {
    for dir in "$REPORT_DIR" "$(dirname "$CONFIG_FILE")" "$BACKUP_DIR"; do
        if [[ ! -d "$dir" ]]; then
            sudo mkdir -p "$dir"
            log_action "Répertoire créé : $dir"
        fi
    done
}

# Générer un rapport complet des jetons sécurisés
generate_secure_token_report() {
    local report_file="$REPORT_DIR/rapport_jetons_securises_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "📊 Génération d'un rapport complet des jetons sécurisés..."
    
    {
        echo "Rapport de Gestion des Jetons Sécurisés Roundfleet"
        echo "Généré : $(date)"
        echo "Appareil : $(hostname)"
        echo "Version macOS : $(sw_vers -productVersion)"
        echo "=============================================="
        echo ""
        
        # Informations système
        echo "=== Informations Système ==="
        echo "Appareil : $(system_profiler SPHardwareDataType | grep "Model Name" | awk -F': ' '{print $2}' | xargs)"
        echo "Série : $(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F': ' '{print $2}' | xargs)"
        echo "Version macOS : $(sw_vers -productVersion)"
        echo "Build : $(sw_vers -buildVersion)"
        echo ""
        
        # Statut FileVault
        echo "=== Informations FileVault ==="
        local fv_status=$(fdesetup status 2>/dev/null || echo "Statut FileVault non disponible")
        echo "Statut FileVault : $fv_status"
        
        if echo "$fv_status" | grep -q "On"; then
            echo "Utilisateurs FileVault :"
            fdesetup list 2>/dev/null | while read -r user; do
                echo "  - $user"
            done
        fi
        echo ""
        
        # Analyse des jetons sécurisés
        echo "=== Analyse des Jetons Sécurisés ==="
        
        local total_users=0
        local enabled_tokens=0
        local disabled_tokens=0
        local admin_with_tokens=0
        local standard_with_tokens=0
        
        # Analyser tous les utilisateurs
        local users
        users=$(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}')
        
        printf "%-25s %-12s %-10s %-15s\n" "Nom d'utilisateur" "Statut Jeton" "Admin" "UID"
        printf "%-25s %-12s %-10s %-15s\n" "----------------" "------------" "-----" "---"
        
        for user in $users; do
            # Ignorer les comptes système
            if [[ "$user" =~ ^(_|com\.|root|daemon|nobody) ]]; then
                continue
            fi
            
            ((total_users++))
            
            local uid
            uid=$(id -u "$user" 2>/dev/null || echo "N/A")
            
            local is_admin="Non"
            if dseditgroup -o checkmember -m "$user" admin >/dev/null 2>&1; then
                is_admin="Oui"
            fi
            
            local token_status
            local token_output
            token_output=$(sysadminctl -secureTokenStatus "$user" 2>&1)
            
            if echo "$token_output" | grep -q "ENABLED"; then
                token_status="✅ Activé"
                ((enabled_tokens++))
                if [[ "$is_admin" == "Oui" ]]; then
                    ((admin_with_tokens++))
                else
                    ((standard_with_tokens++))
                fi
            elif echo "$token_output" | grep -q "DISABLED"; then
                token_status="❌ Désactivé"
                ((disabled_tokens++))
            else
                token_status="⚠️ Inconnu"
            fi
            
            printf "%-25s %-12s %-10s %-15s\n" "$user" "$token_status" "$is_admin" "$uid"
        done
        
        echo ""
        echo "=== Statistiques ==="
        echo "Total utilisateurs analysés : $total_users"
        echo "Utilisateurs avec jetons sécurisés : $enabled_tokens"
        echo "Utilisateurs sans jetons sécurisés : $disabled_tokens"
        echo "Utilisateurs admin avec jetons : $admin_with_tokens"
        echo "Utilisateurs standard avec jetons : $standard_with_tokens"
        
        # Évaluation de sécurité
        echo ""
        echo "=== Évaluation de Sécurité ==="
        
        local security_score=100
        local issues_found=0
        
        if [[ "$enabled_tokens" -eq 0 ]]; then
            echo "❌ CRITIQUE : Aucun utilisateur n'a de jetons sécurisés"
            security_score=$((security_score - 50))
            ((issues_found++))
        fi
        
        if [[ "$admin_with_tokens" -eq 0 ]]; then
            echo "❌ CRITIQUE : Aucun utilisateur admin n'a de jetons sécurisés"
            security_score=$((security_score - 40))
            ((issues_found++))
        elif [[ "$admin_with_tokens" -lt "$MINIMUM_ADMIN_TOKENS" ]]; then
            echo "⚠️ AVERTISSEMENT : Moins de $MINIMUM_ADMIN_TOKENS utilisateurs admin ont des jetons sécurisés"
            security_score=$((security_score - 20))
            ((issues_found++))
        fi
        
        if [[ "$disabled_tokens" -gt "$enabled_tokens" ]]; then
            echo "⚠️ AVERTISSEMENT : Plus d'utilisateurs manquent de jetons sécurisés que n'en ont"
            security_score=$((security_score - 15))
            ((issues_found++))
        fi
        
        if [[ "$issues_found" -eq 0 ]]; then
            echo "✅ Aucun problème de sécurité détecté"
        fi
        
        echo ""
        echo "Score de Sécurité : $security_score/100"
        
        # Recommandations
        echo ""
        echo "=== Recommandations ==="
        
        if [[ "$disabled_tokens" -gt 0 ]]; then
            echo "💡 Accordez des jetons sécurisés à $disabled_tokens utilisateurs pour une compatibilité FileVault complète"
        fi
        
        if [[ "$admin_with_tokens" -lt 2 ]]; then
            echo "💡 Assurez-vous qu'au moins 2 utilisateurs admin ont des jetons sécurisés pour la redondance"
        fi
        
        echo "💡 Audits réguliers des jetons sécurisés recommandés pour la conformité"
        
    } > "$report_file"
    
    echo "📊 Rapport sauvegardé dans : $report_file"
    log_action "Rapport de jetons sécurisés généré : $report_file"
}

# Fonction d'exécution principale
main() {
    local action="${1:-aide}"
    local target_user="${2:-}"
    local admin_user="${3:-}"
    
    log_action "=== Gestion des Jetons Sécurisés Roundfleet Démarrée ==="
    
    setup_directories
    
    case "$action" in
        "verifier")
            if [[ -n "$target_user" ]]; then
                check_user_secure_token "$target_user"
            else
                check_all_users_secure_tokens
            fi
            ;;
        "accorder")
            if [[ -n "$target_user" && -n "$admin_user" ]]; then
                echo "Octroi interactif de jeton sécurisé pour $target_user"
                read -s -p "Mot de passe admin pour $admin_user : " admin_pass
                echo ""
                read -s -p "Mot de passe pour $target_user : " target_pass
                echo ""
                advanced_secure_token_grant "$admin_user" "$admin_pass" "$target_user" "$target_pass"
            else
                echo "❌ Utilisation : $0 accorder <utilisateur_cible> <utilisateur_admin>"
            fi
            ;;
        "rapport")
            generate_secure_token_report
            ;;
        "version")
            local macos_version
            macos_version=$(sw_vers -productVersion)
            echo "Version macOS : $macos_version"
            
            local macos_major
            macos_major=$(echo "$macos_version" | cut -d. -f1)
            local macos_minor
            macos_minor=$(echo "$macos_version" | cut -d. -f2)
            
            if [[ "$macos_major" -lt 10 ]] || [[ "$macos_major" -eq 10 && "$macos_minor" -lt 13 ]]; then
                echo "❌ Les jetons sécurisés nécessitent macOS 10.13 ou ultérieur"
            else
                echo "✅ Jetons sécurisés supportés sur cette version macOS"
            fi
            ;;
        "aide"|*)
            echo "Outil de Gestion des Jetons Sécurisés Roundfleet"
            echo "Utilisation : $0 [action] [options]"
            echo ""
            echo "Actions :"
            echo "  verifier [utilisateur]           - Vérifier le statut des jetons sécurisés (tous les utilisateurs si aucun utilisateur spécifié)"
            echo "  accorder <utilisateur> <admin>   - Accorder un jeton sécurisé à l'utilisateur (mots de passe interactifs)"
            echo "  rapport                          - Générer un rapport complet des jetons sécurisés"
            echo "  version                          - Vérifier la compatibilité de version macOS"
            echo "  aide                             - Afficher ce message d'aide"
            echo ""
            echo "Exemples :"
            echo "  $0 verifier                      # Vérifier tous les utilisateurs"
            echo "  $0 verifier jean.dupont          # Vérifier un utilisateur spécifique"
            echo "  $0 accorder jean.dupont admin.utilisateur  # Accorder jeton interactivement"
            echo "  $0 rapport                       # Générer rapport détaillé"
            echo ""
            echo "Exigences des Jetons Sécurisés :"
            echo "  - macOS 10.13 (High Sierra) ou ultérieur"
            echo "  - Utilisateur admin avec jeton sécurisé existant"
            echo "  - Identifiants valides pour admin et utilisateurs cibles"
            echo "  - Permissions système appropriées et configuration SIP"
            ;;
    esac
    
    log_action "=== Gestion des Jetons Sécurisés Roundfleet Terminée ==="
}

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

Meilleures Pratiques des Jetons Sécurisés

Considérations de Sécurité

AspectRecommandationJustification
Redondance AdminMaintenir 2+ utilisateurs admin avec jetonsÉvite les scénarios de verrouillage
Sécurité Mot de PasseUtiliser des mots de passe forts et uniquesLes jetons ne sont sécurisés que par les mots de passe
Audits RéguliersRévisions mensuelles du statut des jetonsDétecter les changements non autorisés
Intégration FileVaultAccorder les jetons avant d'activer FileVaultAssure que tous les utilisateurs peuvent déverrouiller les disques
DocumentationMaintenir un registre des jetons utilisateurSuivre la conformité d'entreprise

Notes Importantes

  • Exigences de Version macOS - Les jetons sécurisés nécessitent macOS 10.13 (High Sierra) ou ultérieur
  • Prérequis Admin - L'octroi de jetons nécessite un utilisateur admin existant avec jeton sécurisé
  • Sécurité Mot de Passe - Les mots de passe admin et utilisateur cible doivent être fournis pour l'octroi de jetons
  • Intégration FileVault - Les utilisateurs ont besoin de jetons sécurisés pour déverrouiller les volumes chiffrés FileVault
  • Déploiement d'Entreprise - Testez les opérations de jetons sur des appareils individuels avant le déploiement de flotte
  • Surveillance - Les audits réguliers assurent la conformité avec les politiques de sécurité d'entreprise

Effacement Sécurisé de Données sur macOS

Gérez l'effacement sécurisé des données et la protection de la vie privée sur vos appareils Roundfleet en utilisant des systèmes de désinfection de données avancés. Ce tutoriel couvre l'effacement d'espace libre, la suppression sécurisée, la surveillance de conformité et la gestion complète du cycle de vie des données.

Comprendre l'Effacement Sécurisé de Données macOS

macOS fournit des capacités d'effacement sécurisé des données pour la vie privée et la conformité :

  • diskutil secureErase - Effacement sécurisé d'espace libre et volumes
  • Effacement d'Espace Libre - Supprimer les traces de fichiers supprimés du disque
  • Niveaux d'Effacement Sécurisé - Multiples standards de sécurité (DoD, DoE, Gutmann)
  • Protection de Vie Privée - Empêcher la récupération de données et analyse médico-légale
  • Exigences de Conformité - Respecter les standards réglementaires pour destruction de données

Opérations d'Effacement Sécurisé de Base

Effacer l'Espace Libre

#!/bin/bash

# Effacement d'espace libre de base
diskutil secureErase freespace 4 /Volumes/Macintosh\ HD

echo "Effacement sécurisé d'espace libre terminé"

Configuration d'Effacement Sécurisé Améliorée

#!/bin/bash

# Effacement sécurisé complet avec multiples niveaux de sécurité
secure_erase_freespace() {
    local volume_path="$1"
    local security_level="${2:-4}"
    
    echo "=== Effacement Sécurisé d'Espace Libre ==="
    echo "Volume : $volume_path"
    echo "Niveau de Sécurité : $security_level"
    
    # Valider que le volume existe
    if [[ ! -d "$volume_path" ]]; then
        echo "❌ Volume non trouvé : $volume_path"
        return 1
    fi
    
    # Afficher les informations de niveau de sécurité
    case "$security_level" in
        0) echo "Méthode de Sécurité : Effacement à remplissage zéro en un passage" ;;
        1) echo "Méthode de Sécurité : Effacement à remplissage aléatoire en un passage" ;;
        2) echo "Méthode de Sécurité : Effacement sécurisé US DoD à 7 passages" ;;
        3) echo "Méthode de Sécurité : Algorithme Gutmann à 35 passages d'effacement sécurisé" ;;
        4) echo "Méthode de Sécurité : Algorithme US DoE à 3 passages d'effacement sécurisé" ;;
        *) echo "❌ Niveau de sécurité invalide : $security_level"; return 1 ;;
    esac
    
    # Obtenir les informations du volume
    local free_space
    free_space=$(df -h "$volume_path" | tail -1 | awk '{print $4}')
    echo "Espace Libre à Effacer : $free_space"
    
    # Estimer le temps basé sur le niveau de sécurité et l'espace libre
    echo "⏱️  Temps estimé : Cela peut prendre plusieurs heures selon la taille du disque et le niveau de sécurité"
    
    # Effectuer l'effacement sécurisé
    echo "Démarrage de l'effacement sécurisé..."
    if diskutil secureErase freespace "$security_level" "$volume_path"; then
        echo "✅ Effacement sécurisé d'espace libre terminé avec succès"
        log_erasure_action "espace_libre" "$volume_path" "$security_level" "succès"
    else
        echo "❌ Effacement sécurisé échoué"
        log_erasure_action "espace_libre" "$volume_path" "$security_level" "échoué"
        return 1
    fi
    
    return 0
}

# Fonction de journalisation
log_erasure_action() {
    local action="$1"
    local target="$2"
    local level="$3"
    local result="$4"
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Effacement Sécurisé : $action sur $target (Niveau : $level) - $result" >> "/var/log/roundfleet_effacement_securise.log"
}

# Exemple d'utilisation
# secure_erase_freespace "/Volumes/Macintosh HD" 4

Catégories d'Effacement Sécurisé

Niveaux de Classification des Données

#!/bin/bash

# Catégories d'effacement sécurisé pour différents niveaux de sensibilité des données
declare -A ERASURE_CATEGORIES=(
    ["donnees_publiques"]="Informations publiques à faible sensibilité nécessitant un effacement de base"
    ["affaires_internes"]="Données d'affaires internes nécessitant un effacement sécurisé standard"
    ["donnees_confidentielles"]="Informations d'affaires confidentielles nécessitant un effacement amélioré"
    ["financieres_restreintes"]="Données financières et comptables nécessitant des protocoles d'effacement stricts"
    ["identifiables_personnelles"]="Données PII nécessitant des procédures d'effacement conformes à la vie privée"
    ["dossiers_medicaux"]="Informations de santé protégées HIPAA nécessitant un effacement de qualité médicale"
    ["privilege_legal"]="Informations privilégiées avocat-client nécessitant un effacement de sécurité maximale"
    ["gouvernement_classifie"]="Données gouvernementales classifiées nécessitant un effacement de niveau militaire"
    ["recherche_intellectuelle"]="Données de recherche et PI nécessitant des protocoles d'effacement complets"
    ["preuves_medico_legales"]="Preuves médico-légales numériques nécessitant un effacement de chaîne de possession"
)

# Niveaux de sécurité pour chaque catégorie
declare -A CATEGORY_SECURITY_LEVELS=(
    ["donnees_publiques"]="1"           # Un passage aléatoire
    ["affaires_internes"]="2"           # DoD 7 passages
    ["donnees_confidentielles"]="4"     # DoE 3 passages
    ["financieres_restreintes"]="4"     # DoE 3 passages
    ["identifiables_personnelles"]="4"  # DoE 3 passages
    ["dossiers_medicaux"]="3"           # Gutmann 35 passages
    ["privilege_legal"]="3"             # Gutmann 35 passages
    ["gouvernement_classifie"]="3"      # Gutmann 35 passages
    ["recherche_intellectuelle"]="4"    # DoE 3 passages
    ["preuves_medico_legales"]="3"      # Gutmann 35 passages
)

# Cadres de conformité
declare -A COMPLIANCE_FRAMEWORKS=(
    ["donnees_publiques"]="securite_de_base"
    ["affaires_internes"]="iso27001"
    ["donnees_confidentielles"]="iso27001,sox"
    ["financieres_restreintes"]="sox,pci_dss"
    ["identifiables_personnelles"]="gdpr,ccpa"
    ["dossiers_medicaux"]="hipaa,hitech"
    ["privilege_legal"]="privilege_avocat_client"
    ["gouvernement_classifie"]="fisma,nist_sp800"
    ["recherche_intellectuelle"]="iso27001,secrets_commerciaux"
    ["preuves_medico_legales"]="chaine_de_possession,decouverte_legale"
)

print_erasure_categories() {
    echo "=== Catégories d'Effacement Sécurisé ==="
    for category in "${!ERASURE_CATEGORIES[@]}"; do
        echo "Catégorie : $category"
        echo "  Description : ${ERASURE_CATEGORIES[$category]}"
        echo "  Niveau de Sécurité : ${CATEGORY_SECURITY_LEVELS[$category]}"
        echo "  Conformité : ${COMPLIANCE_FRAMEWORKS[$category]}"
        echo ""
    done
}

# Afficher les catégories disponibles
print_erasure_categories

Politiques d'Effacement Sécurisé

Politiques de Protection de Vie Privée

#!/bin/bash

# Politiques d'effacement sécurisé pour différentes exigences de vie privée et conformité
declare -A ERASURE_POLICIES=(
    ["vie_privee_de_base"]="Protection de vie privée de base avec méthodes d'effacement standard"
    ["conforme_gdpr"]="Effacement de données personnelles conforme GDPR avec pistes d'audit"
    ["medical_hipaa"]="Effacement de dossiers médicaux conforme HIPAA avec certification"
    ["financier_sox"]="Effacement de données financières conforme SOX avec validation"
    ["gouvernement_classifie"]="Effacement de données gouvernementales classifiées avec chaîne de possession"
    ["legal_medico_legal"]="Effacement de données légales et médico-légales avec préservation de preuves"
)

# Obtenir la configuration de politique d'effacement
get_erasure_policy() {
    local policy_type="$1"
    
    case "$policy_type" in
        "vie_privee_de_base")
            cat << EOF
{
    "effacement_active": true,
    "niveau_securite_defaut": 2,
    "planification_automatique": false,
    "verification_requise": false,
    "journalisation_audit": "de_base",
    "cadres_conformite": ["securite_de_base"],
    "generation_certificat": false,
    "chaine_de_possession": false,
    "classification_donnees": "public_interne",
    "politique_retention": "effacement_immediat",
    "methodes_verification": ["verification_de_base"],
    "niveau_rapport": "resume"
}
EOF
            ;;
        "conforme_gdpr")
            cat << EOF
{
    "effacement_active": true,
    "niveau_securite_defaut": 4,
    "planification_automatique": true,
    "verification_requise": true,
    "journalisation_audit": "complete",
    "cadres_conformite": ["gdpr", "ccpa"],
    "generation_certificat": true,
    "chaine_de_possession": true,
    "classification_donnees": "identifiables_personnelles",
    "politique_retention": "effacement_verifie",
    "methodes_verification": ["verification_medico_legale", "analyse_entropie"],
    "niveau_rapport": "detaille",
    "evaluation_impact_vie_privee": true,
    "droits_sujet_donnees": "droit_effacement",
    "considerations_transfrontalieres": true
}
EOF
            ;;
        "medical_hipaa")
            cat << EOF
{
    "effacement_active": true,
    "niveau_securite_defaut": 3,
    "planification_automatique": true,
    "verification_requise": true,
    "journalisation_audit": "complete",
    "cadres_conformite": ["hipaa", "hitech"],
    "generation_certificat": true,
    "chaine_de_possession": true,
    "classification_donnees": "dossiers_medicaux",
    "politique_retention": "calendrier_retention_medical",
    "methodes_verification": ["verification_medico_legale", "certification_medicale"],
    "niveau_rapport": "detaille",
    "verification_chiffrement": true,
    "controles_acces": "base_sur_role",
    "considerations_dispositifs_medicaux": true
}
EOF
            ;;
        *)
            echo "Politique d'effacement inconnue : $policy_type"
            return 1
            ;;
    esac
}

# Appliquer une politique d'effacement
apply_erasure_policy() {
    local policy="$1"
    local config_file="/tmp/politique_effacement.json"
    
    echo "Application de la politique d'effacement sécurisé : $policy"
    
    get_erasure_policy "$policy" > "$config_file"
    
    if [[ ! -f "$config_file" ]]; then
        echo "❌ Échec de génération de configuration de politique"
        return 1
    fi
    
    echo "✅ Politique d'effacement sécurisé appliquée avec succès"
    echo "Configuration : $config_file"
    
    # Afficher les paramètres clés de politique
    echo "=== Résumé de Politique ==="
    echo "Effacement Activé : $(jq -r '.effacement_active' "$config_file")"
    echo "Niveau de Sécurité Défaut : $(jq -r '.niveau_securite_defaut' "$config_file")"
    echo "Vérification Requise : $(jq -r '.verification_requise' "$config_file")"
    echo "Journalisation d'Audit : $(jq -r '.journalisation_audit' "$config_file")"
    
    return 0
}

Surveillance Avancée d'Effacement Sécurisé

Vérification et Analyse d'Effacement

#!/bin/bash

# Surveillance et vérification complètes d'effacement sécurisé
verify_secure_erasure() {
    local verification_profile="$1"
    local target_volume="$2"
    local verification_report="/tmp/verification_effacement_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Vérification d'Effacement Sécurisé ==="
    echo "Profil de Vérification : $verification_profile"
    echo "Volume Cible : $target_volume"
    
    # Initialiser le rapport de vérification
    cat > "$verification_report" << EOF
{
    "profil_verification": "$verification_profile",
    "volume_cible": "$target_volume",
    "horodatage_verification": "$(date -Iseconds)",
    "nom_hote": "$(hostname)",
    "resultats_verification": {},
    "statut_conformite": {},
    "analyse_medico_legale": {}
}
EOF
    
    # Effectuer les vérifications
    echo "Exécution des vérifications..."
    
    # Vérifier le statut du volume
    local volume_status="inconnu"
    if [[ -d "$target_volume" ]]; then
        volume_status="accessible"
    else
        volume_status="inaccessible"
    fi
    
    # Analyser l'entropie de l'espace libre
    echo "Analyse de l'entropie de l'espace libre..."
    local entropy_score
    entropy_score=$(calculate_entropy "$target_volume")
    
    # Vérifier les résidus de données
    echo "Recherche de résidus de données..."
    local remnant_scan_result
    remnant_scan_result=$(scan_data_remnants "$target_volume")
    
    # Vérifier la complétude de l'effacement
    echo "Vérification de la complétude de l'effacement..."
    local completeness_score
    completeness_score=$(verify_erasure_completeness "$target_volume")
    
    # Afficher les résultats
    echo ""
    echo "Résultats de Vérification :"
    echo "  Statut du Volume : $volume_status"
    echo "  Score d'Entropie : $entropy_score"
    echo "  Résidus de Données : $remnant_scan_result"
    echo "  Complétude : $completeness_score"
    echo "  Rapport de Vérification : $verification_report"
    
    return 0
}

# Fonctions d'aide
calculate_entropy() {
    local volume="$1"
    # Calcul d'entropie simplifié
    echo "entropie_elevee"
}

scan_data_remnants() {
    local volume="$1"
    # Recherche de résidus simplifiée
    echo "aucun_residu_detecte"
}

verify_erasure_completeness() {
    local volume="$1"
    # Vérification de complétude simplifiée
    echo "100_pourcent"
}

Système de Gestion d'Effacement Sécurisé des Données

#!/bin/bash

# Système de Gestion d'Effacement Sécurisé des Données Roundfleet
# Désinfection complète des données, protection de la vie privée et surveillance de conformité

# Configuration
CONFIG_DIR="/etc/roundfleet/effacement"
LOG_FILE="/var/log/roundfleet_effacement_securise.log"
AUDIT_LOG="/var/log/roundfleet_audit_effacement.log"
CERTIFICATES_DIR="/var/certificates/roundfleet/effacement"

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

audit_log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [AUDIT] $1" | tee -a "$AUDIT_LOG"
}

# Découverte et analyse de volumes
discover_volumes() {
    echo "=== Découverte de Volumes ==="
    
    log_action "Démarrage de la découverte de volumes"
    
    # Lister tous les volumes montés
    echo "Volumes Montés :"
    df -h | grep "^/dev/" | while read -r line; do
        local device
        device=$(echo "$line" | awk '{print $1}')
        local mount_point
        mount_point=$(echo "$line" | awk '{print $9}')
        local size
        size=$(echo "$line" | awk '{print $2}')
        local available
        available=$(echo "$line" | awk '{print $4}')
        
        echo "  Périphérique : $device"
        echo "  Point de Montage : $mount_point"
        echo "  Taille : $size"
        echo "  Disponible : $available"
        echo ""
    done
    
    log_action "Découverte de volumes terminée"
}

# Exécution d'effacement sécurisé
execute_secure_erasure() {
    local volume_path="$1"
    local security_level="$2"
    local category="${3:-affaires_internes}"
    local policy="${4:-vie_privee_de_base}"
    
    log_action "Exécution d'effacement sécurisé : $volume_path (Niveau : $security_level, Catégorie : $category)"
    
    echo "=== Exécution d'Effacement Sécurisé ==="
    echo "Volume : $volume_path"
    echo "Niveau de Sécurité : $security_level"
    echo "Catégorie de Données : $category"
    echo "Politique d'Effacement : $policy"
    
    # Validation pré-effacement
    echo "Validation pré-effacement..."
    
    # Vérifier l'accessibilité du volume
    if [[ ! -d "$volume_path" ]]; then
        log_error "Volume non accessible : $volume_path"
        return 1
    fi
    
    # Exécuter l'effacement basé sur le niveau de sécurité
    echo "Démarrage de l'opération d'effacement sécurisé..."
    local start_time
    start_time=$(date +%s)
    
    case "$security_level" in
        0|1|2|3|4)
            if diskutil secureErase freespace "$security_level" "$volume_path"; then
                local end_time
                end_time=$(date +%s)
                local duration=$((end_time - start_time))
                
                echo "✅ Effacement sécurisé terminé avec succès"
                echo "⏱️  Durée : ${duration} secondes"
                
                # Générer un certificat de complétude
                generate_erasure_certificate "$volume_path" "$security_level" "$category" "$policy" "$duration" "succès"
                
                audit_log "Effacement sécurisé réussi : $volume_path (Niveau : $security_level, Durée : ${duration}s)"
                return 0
            else
                log_error "Effacement sécurisé échoué : $volume_path"
                
                # Générer un rapport d'échec
                generate_erasure_certificate "$volume_path" "$security_level" "$category" "$policy" "0" "échoué"
                
                audit_log "Effacement sécurisé échoué : $volume_path (Niveau : $security_level)"
                return 1
            fi
            ;;
        *)
            log_error "Niveau de sécurité invalide : $security_level"
            return 1
            ;;
    esac
}

# Générer un certificat d'effacement
generate_erasure_certificate() {
    local volume_path="$1"
    local security_level="$2"
    local category="$3"
    local policy="$4"
    local duration="$5"
    local status="$6"
    
    local certificate_file="$CERTIFICATES_DIR/certificat_effacement_$(date +%Y%m%d_%H%M%S).json"
    
    # Obtenir la description de la méthode de sécurité
    local security_method
    case "$security_level" in
        0) security_method="Effacement à remplissage zéro en un passage" ;;
        1) security_method="Effacement à remplissage aléatoire en un passage" ;;
        2) security_method="Effacement sécurisé US DoD à 7 passages" ;;
        3) security_method="Algorithme Gutmann à 35 passages d'effacement sécurisé" ;;
        4) security_method="Algorithme US DoE à 3 passages d'effacement sécurisé" ;;
        *) security_method="Méthode inconnue" ;;
    esac
    
    cat > "$certificate_file" << EOF
{
    "type_certificat": "effacement_securise_donnees",
    "id_certificat": "CERT-$(date +%Y%m%d%H%M%S)-$(uuidgen | cut -d'-' -f1)",
    "details_effacement": {
        "chemin_volume": "$volume_path",
        "niveau_securite": $security_level,
        "methode_securite": "$security_method",
        "categorie_donnees": "$category",
        "politique_effacement": "$policy",
        "duree_secondes": $duration,
        "statut": "$status"
    },
    "informations_systeme": {
        "nom_hote": "$(hostname)",
        "operateur": "$(whoami)",
        "horodatage": "$(date -Iseconds)",
        "version_macos": "$(sw_vers -productVersion)"
    },
    "informations_conformite": {
        "verification_effectuee": true,
        "chaine_de_possession": true,
        "piste_audit": "disponible"
    }
}
EOF
    
    echo "📜 Certificat d'effacement généré : $certificate_file"
    log_action "Certificat d'effacement généré : $certificate_file"
}

# Fonction principale avec routage de commandes
main() {
    local command="$1"
    shift
    
    case "$command" in
        "effacer_espace_libre")
            # Exécuter l'effacement sécurisé d'espace libre
            execute_secure_erasure "$@"
            ;;
        "decouvrir_volumes")
            # Découvrir et lister les volumes disponibles
            discover_volumes
            ;;
        "verifier_effacement")
            # Vérifier la complétude de l'effacement
            verify_secure_erasure "$@"
            ;;
        "appliquer_politique")
            # Appliquer une politique d'effacement
            apply_erasure_policy "$@"
            ;;
        "generer_certificat")
            # Générer un certificat d'effacement
            generate_erasure_certificate "$@"
            ;;
        "afficher_categories")
            # Afficher les catégories d'effacement
            print_erasure_categories
            ;;
        "afficher_politiques")
            # Afficher les politiques disponibles
            for policy in vie_privee_de_base conforme_gdpr medical_hipaa financier_sox gouvernement_classifie legal_medico_legal; do
                echo "Politique : $policy"
                get_erasure_policy "$policy" | jq .
                echo ""
            done
            ;;
        *)
            echo "Système de Gestion d'Effacement Sécurisé des Données Roundfleet"
            echo "Utilisation : $0 <commande> [options]"
            echo ""
            echo "Commandes :"
            echo "  effacer_espace_libre <volume> <niveau> [catégorie] [politique]  - Exécuter effacement sécurisé d'espace libre"
            echo "  decouvrir_volumes                                               - Découvrir volumes disponibles"
            echo "  verifier_effacement <profil> <volume>                          - Vérifier complétude effacement"
            echo "  appliquer_politique <politique>                                - Appliquer politique d'effacement"
            echo "  generer_certificat <volume> <niveau> <catégorie>               - Générer certificat d'effacement"
            echo "  afficher_categories                                            - Afficher catégories de données"
            echo "  afficher_politiques                                            - Afficher politiques d'effacement"
            echo ""
            echo "Niveaux de Sécurité :"
            echo "  0 - Effacement à remplissage zéro en un passage"
            echo "  1 - Effacement à remplissage aléatoire en un passage"
            echo "  2 - Effacement sécurisé US DoD à 7 passages"
            echo "  3 - Algorithme Gutmann à 35 passages d'effacement sécurisé"
            echo "  4 - Algorithme US DoE à 3 passages d'effacement sécurisé"
            echo ""
            echo "Exemples :"
            echo "  $0 effacer_espace_libre \"/Volumes/Data\" 4 donnees_confidentielles conforme_gdpr"
            echo "  $0 decouvrir_volumes"
            echo "  $0 verifier_effacement complet \"/Volumes/Data\""
            echo "  $0 appliquer_politique medical_hipaa"
            ;;
    esac
}

# Exécuter la fonction principale avec tous les arguments
main "$@"

Considérations de Sécurité

Sécurité de Désinfection des Données

  • Écrasement Multi-Passages - Utiliser des niveaux de sécurité appropriés pour la sensibilité des données
  • Procédures de Vérification - Vérifier l'effacement complet et l'impossibilité de récupération des données
  • Standards de Conformité - Respecter les exigences réglementaires pour destruction de données
  • Chaîne de Possession - Maintenir pistes d'audit et documentation
  • Sécurité Physique - Considérer la destruction physique pour les besoins de sécurité les plus élevés

Cadre de Conformité

  • Conformité GDPR - Droit à l'effacement et exigences de protection des données
  • HIPAA Médical - Destruction de dossiers médicaux avec certification appropriée
  • SOX Financier - Effacement de données financières avec exigences d'audit
  • Standards Gouvernementaux - FISMA, NIST SP 800-88 pour données classifiées
  • Standards Industriels - DoD 5220.22-M, Critères Communs pour effacement sécurisé

Guide de Dépannage

Problèmes Courants

Processus d'Effacement Échoue

  • Vérifier que le volume n'est pas en cours d'utilisation : lsof | grep /Volumes/NomVolume
  • Vérifier les permissions suffisantes : Exécuter avec sudo si nécessaire
  • Vérifier la santé du disque : diskutil verifyVolume /Volumes/NomVolume

Performance d'Effacement Lente

  • Les niveaux de sécurité plus élevés (3,4) prennent significativement plus de temps
  • Différences de performance SSD vs HDD
  • La charge système et les ressources disponibles affectent la vitesse

Commandes de Diagnostic

# Lister tous les volumes
diskutil list

# Vérifier les informations du volume
diskutil info /Volumes/NomVolume

# Vérifier l'espace libre
df -h /Volumes/NomVolume

# Surveiller le progrès d'effacement
sudo fs_usage -w -f diskio diskutil

Notes Importantes

  • Sauvegarder les Données Critiques - Toujours sauvegarder les fichiers importants avant effacement
  • Exigences de Temps - Les niveaux de sécurité plus élevés nécessitent significativement plus de temps
  • Noms de Volumes - Échapper les espaces dans les noms de volumes avec des barres obliques inverses
  • Sécurité vs Performance - Équilibrer les besoins de sécurité avec les contraintes de temps
  • Vérification - Toujours vérifier la complétude de l'effacement pour la conformité
  • Documentation - Maintenir des pistes d'audit et certificats appropriés pour la conformité réglementaire

Gestion Sécurisée d'Archives sur macOS

Gérez des archives de fichiers sécurisées sur vos appareils Roundfleet avec des outils de compression et chiffrement de niveau entreprise. Ce tutoriel couvre la création de ZIP protégés par mot de passe, les opérations d'archivage par lots, la conformité sécuritaire et la gestion complète d'archives à l'échelle de la flotte.

Comprendre la Gestion Sécurisée d'Archives

La gestion sécurisée d'archives sur macOS implique la création de fichiers compressés protégés pour le transfert, stockage et conformité des données :

Composants Principaux

  • Compression ZIP - Format d'archive standard avec compatibilité étendue
  • Protection Mot de Passe - Chiffrement AES pour sécurité d'archive
  • Opérations Lot - Création et gestion d'archives en masse
  • Vérification Intégrité - Validation d'archive et détection corruption
  • Suivi Conformité - Pistes d'audit et rapports sécuritaires

Avantages Entreprise

  • Sécurité Données - Transfert et stockage fichiers protégés
  • Optimisation Stockage - Archives compressées économisent espace disque
  • Exigences Conformité - Archivage sécurisé données pour réglementations
  • Gestion Flotte - Opérations d'archive standardisées sur appareils
  • Capacités Audit - Suivi complet opérations d'archive

Création Basique ZIP Protégé par Mot de Passe

Création ZIP Simple avec Mot de Passe

#!/bin/bash

# Création basique ZIP protégé par mot de passe
create_basic_password_zip() {
    local file_path="${1:-/Users/Shared/exemple.txt}"
    local zip_name="${2:-archive_securisee.zip}"
    local password="${3:-ChangezMoiMaintenant123!}"
    local content="${4:-Bonjour Roundfleet - Archive Sécurisée Créée}"
    
    echo "📦 Création Archive ZIP Protégée par Mot de Passe"
    echo "================================================"
    echo "Fichier : $file_path"
    echo "Archive : $zip_name"
    echo "Contenu : $content"
    echo ""
    
    # Créer le fichier avec contenu
    echo "Création fichier avec contenu..."
    touch "$file_path"
    printf '%s\n' "$content" > "$file_path"
    
    if [[ -f "$file_path" ]]; then
        echo "✅ Fichier créé avec succès : $file_path"
    else
        echo "❌ Échec création fichier : $file_path"
        return 1
    fi
    
    # Naviguer vers répertoire fichier
    local file_dir=$(dirname "$file_path")
    local file_name=$(basename "$file_path")
    
    echo "Navigation vers répertoire : $file_dir"
    cd "$file_dir" || return 1
    
    # Créer ZIP protégé par mot de passe
    echo "Création archive ZIP protégée par mot de passe..."
    if zip -r "$zip_name" "$file_name" --password "$password" >/dev/null 2>&1; then
        echo "✅ Archive ZIP créée avec succès : $file_dir/$zip_name"
        
        # Vérifier archive
        if [[ -f "$zip_name" ]]; then
            local zip_size=$(du -h "$zip_name" | cut -f1)
            echo "Taille archive : $zip_size"
            echo "Emplacement archive : $file_dir/$zip_name"
        fi
    else
        echo "❌ Échec création archive ZIP"
        return 1
    fi
    
    # Nettoyer fichier original (optionnel)
    echo ""
    read -p "Supprimer fichier original ? (o/n) : " remove_original
    if [[ "$remove_original" =~ ^[Oo]$ ]]; then
        rm "$file_path"
        echo "✅ Fichier original supprimé"
    fi
    
    return 0
}

# Exécuter création ZIP basique
create_basic_password_zip "/Users/Shared/test_roundfleet.txt" "roundfleet_securise.zip" "MotDePasseSecurise123!" "Archive Entreprise Roundfleet"

Convertir Fichier Existant en ZIP Protégé par Mot de Passe

#!/bin/bash

# Convertir fichier existant en ZIP protégé par mot de passe
convert_file_to_secure_zip() {
    local source_file="$1"
    local zip_name="${2:-}"
    local password="${3:-}"
    local compression_level="${4:-6}"
    
    echo "🔄 Conversion Fichier en ZIP Sécurisé"
    echo "===================================="
    echo ""
    
    # Valider fichier d'entrée
    if [[ ! -f "$source_file" ]]; then
        echo "❌ Fichier source non trouvé : $source_file"
        echo "Veuillez fournir un chemin fichier valide"
        return 1
    fi
    
    # Obtenir informations fichier
    local file_dir=$(dirname "$source_file")
    local file_name=$(basename "$source_file")
    local file_ext="${file_name##*.}"
    local file_base="${file_name%.*}"
    
    # Générer nom ZIP si non fourni
    if [[ -z "$zip_name" ]]; then
        zip_name="${file_base}_securise.zip"
    fi
    
    # Générer mot de passe sécurisé si non fourni
    if [[ -z "$password" ]]; then
        password=$(openssl rand -base64 12 | tr -d "=+/" | cut -c1-12)
        echo "🔐 Mot de passe sécurisé généré : $password"
        echo "⚠️ Sauvegardez ce mot de passe - il ne peut être récupéré !"
    fi
    
    echo "Fichier source : $source_file"
    echo "Nom archive : $zip_name"
    echo "Niveau compression : $compression_level (1-9)"
    echo ""
    
    # Obtenir taille fichier avant compression
    local original_size=$(du -h "$source_file" | cut -f1)
    echo "Taille fichier original : $original_size"
    
    # Naviguer vers répertoire fichier
    cd "$file_dir" || return 1
    
    # Créer ZIP sécurisé avec compression spécifiée
    echo "Création archive ZIP sécurisée..."
    if zip -"$compression_level" -r "$zip_name" "$file_name" --password "$password" >/dev/null 2>&1; then
        echo "✅ ZIP sécurisé créé avec succès"
        
        # Obtenir taille compressée et calculer ratio compression
        local compressed_size=$(du -h "$zip_name" | cut -f1)
        local original_bytes=$(du -b "$source_file" | cut -f1)
        local compressed_bytes=$(du -b "$zip_name" | cut -f1)
        local compression_ratio=$(echo "scale=1; (($original_bytes - $compressed_bytes) * 100) / $original_bytes" | bc 2>/dev/null || echo "N/A")
        
        echo ""
        echo "=== Résumé Archive ==="
        echo "Taille originale : $original_size"
        echo "Taille compressée : $compressed_size"
        echo "Ratio compression : ${compression_ratio}%"
        echo "Emplacement archive : $file_dir/$zip_name"
        echo "Mot de passe : $password"
        
        # Tester intégrité archive
        echo ""
        echo "Test intégrité archive..."
        if unzip -t "$zip_name" >/dev/null 2>&1; then
            echo "✅ Intégrité archive vérifiée"
        else
            echo "⚠️ Vérification intégrité archive échouée"
        fi
        
    else
        echo "❌ Échec création archive ZIP sécurisée"
        return 1
    fi
    
    return 0
}

# Exemple d'utilisation
echo "Exemple : Convertir fichier existant en ZIP sécurisé"
# convert_file_to_secure_zip "/Users/Shared/document.pdf" "document_securise.zip" "MonMotDePasseSecurise123!"

Gestion d'Archives d'Entreprise

Système de Création d'Archives Complet

#!/bin/bash

# Système de gestion d'archives d'entreprise
enterprise_archive_manager() {
    local operation="${1:-create}"
    local source_path="$2"
    local archive_config="${3:-default}"
    local output_dir="${4:-/tmp/roundfleet_archives}"
    
    echo "🏢 Gestionnaire d'Archives Entreprise Roundfleet"
    echo "=============================================="
    echo "Opération : $operation"
    echo "Source : $source_path"
    echo "Config : $archive_config"
    echo "Sortie : $output_dir"
    echo ""
    
    # Assurer que répertoire sortie existe
    mkdir -p "$output_dir"
    
    # Préréglages configuration
    declare -A archive_configs
    archive_configs[default]="zip:6:AES256"
    archive_configs[haute_securite]="zip:9:AES256"
    archive_configs[rapide]="zip:1:AES128"
    archive_configs[maximum]="zip:9:AES256"
    
    # Analyser configuration
    local config_string="${archive_configs[$archive_config]:-${archive_configs[default]}}"
    IFS=':' read -r format compression encryption <<< "$config_string"
    
    # Générer métadonnées sécurisées
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local hostname=$(hostname)
    local user=$(whoami)
    local archive_id=$(openssl rand -hex 8)
    
    case "$operation" in
        "create")
            create_enterprise_archive "$source_path" "$output_dir" "$format" "$compression" "$encryption" "$timestamp" "$archive_id"
            ;;
        "batch")
            batch_archive_creation "$source_path" "$output_dir" "$format" "$compression" "$encryption"
            ;;
        "verify")
            verify_archive_integrity "$source_path"
            ;;
        "extract")
            secure_archive_extraction "$source_path" "$output_dir"
            ;;
        *)
            echo "❌ Opération inconnue : $operation"
            echo "Opérations disponibles : create, batch, verify, extract"
            return 1
            ;;
    esac
}

# Créer archive de niveau entreprise
create_enterprise_archive() {
    local source="$1"
    local output_dir="$2"
    local format="$3"
    local compression="$4"
    local encryption="$5"
    local timestamp="$6"
    local archive_id="$7"
    
    echo "📦 Création Archive Entreprise"
    echo "=============================="
    
    # Valider source
    if [[ ! -e "$source" ]]; then
        echo "❌ Source non trouvée : $source"
        return 1
    fi
    
    # Générer mot de passe sécurisé
    local password=$(openssl rand -base64 16 | tr -d "=+/" | cut -c1-16)
    
    # Déterminer nom archive
    local source_name=$(basename "$source")
    local archive_name="roundfleet_${archive_id}_${timestamp}.${format}"
    local archive_path="$output_dir/$archive_name"
    local metadata_file="$output_dir/${archive_name}.metadata.json"
    local password_file="$output_dir/${archive_name}.password"
    
    echo "ID Archive : $archive_id"
    echo "Source : $source"
    echo "Archive : $archive_path"
    echo "Compression : Niveau $compression"
    echo "Chiffrement : $encryption"
    echo ""
    
    # Obtenir informations source
    local source_size=""
    local source_type=""
    local file_count=0
    
    if [[ -f "$source" ]]; then
        source_type="fichier"
        source_size=$(du -h "$source" | cut -f1)
        file_count=1
    elif [[ -d "$source" ]]; then
        source_type="répertoire"
        source_size=$(du -sh "$source" | cut -f1)
        file_count=$(find "$source" -type f | wc -l | xargs)
    fi
    
    echo "Type source : $source_type"
    echo "Taille source : $source_size"
    echo "Nombre fichiers : $file_count"
    echo ""
    
    # Créer archive
    echo "Création archive..."
    local start_time=$(date +%s)
    
    if zip -r -"$compression" "$archive_path" "$source" --password "$password" >/dev/null 2>&1; then
        local end_time=$(date +%s)
        local duration=$((end_time - start_time))
        
        echo "✅ Archive créée avec succès"
        echo "Temps création : ${duration}s"
        
        # Obtenir statistiques archive
        local archive_size=$(du -h "$archive_path" | cut -f1)
        local checksum=$(shasum -a 256 "$archive_path" | cut -d' ' -f1)
        
        # Sauvegarder mot de passe de manière sécurisée
        echo "$password" > "$password_file"
        chmod 600 "$password_file"
        
        # Générer métadonnées
        cat > "$metadata_file" << EOF
{
    "info_archive": {
        "id": "$archive_id",
        "nom": "$archive_name",
        "cree": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
        "nom_hote": "$(hostname)",
        "utilisateur": "$(whoami)",
        "version_roundfleet": "2025.07"
    },
    "info_source": {
        "chemin": "$source",
        "type": "$source_type",
        "taille": "$source_size",
        "nombre_fichiers": $file_count
    },
    "details_archive": {
        "format": "$format",
        "niveau_compression": $compression,
        "chiffrement": "$encryption",
        "taille": "$archive_size",
        "checksum_sha256": "$checksum",
        "duree_creation": ${duration}
    },
    "securite": {
        "protege_mot_de_passe": true,
        "fichier_mot_de_passe": "${archive_name}.password",
        "algorithme_chiffrement": "AES-256"
    }
}
EOF
        
        echo ""
        echo "=== Résumé Archive ==="
        echo "Archive : $archive_path"
        echo "Taille : $archive_size"
        echo "Checksum : $checksum"
        echo "Fichier mot de passe : $password_file"
        echo "Métadonnées : $metadata_file"
        
    else
        echo "❌ Échec création archive"
        return 1
    fi
}

# Création archives par lots
batch_archive_creation() {
    local source_dir="$1"
    local output_dir="$2"
    local format="$3"
    local compression="$4"
    local encryption="$5"
    
    echo "📦 Création Archives par Lots"
    echo "============================="
    echo "Répertoire source : $source_dir"
    echo ""
    
    if [[ ! -d "$source_dir" ]]; then
        echo "❌ Répertoire source non trouvé : $source_dir"
        return 1
    fi
    
    local processed=0
    local failed=0
    
    # Traiter chaque élément dans répertoire source
    for item in "$source_dir"/*; do
        if [[ -e "$item" ]]; then
            local item_name=$(basename "$item")
            echo "Traitement : $item_name"
            
            local timestamp=$(date +"%Y%m%d_%H%M%S")
            local archive_id=$(openssl rand -hex 4)
            
            if create_enterprise_archive "$item" "$output_dir" "$format" "$compression" "$encryption" "$timestamp" "$archive_id"; then
                echo "✅ Archivage réussi : $item_name"
                ((processed++))
            else
                echo "❌ Échec archivage : $item_name"
                ((failed++))
            fi
            echo ""
        fi
    done
    
    echo "=== Résumé Lot ==="
    echo "Traités : $processed"
    echo "Échoués : $failed"
    echo "Total : $((processed + failed))"
}

# Vérification intégrité archive
verify_archive_integrity() {
    local archive_path="$1"
    
    echo "🔍 Vérification Intégrité Archive"
    echo "================================="
    echo "Archive : $archive_path"
    echo ""
    
    if [[ ! -f "$archive_path" ]]; then
        echo "❌ Archive non trouvée : $archive_path"
        return 1
    fi
    
    # Vérifier si c'est un fichier ZIP
    if ! file "$archive_path" | grep -q "Zip archive"; then
        echo "❌ Pas une archive ZIP valide"
        return 1
    fi
    
    # Tester intégrité archive
    echo "Test intégrité archive..."
    if unzip -t "$archive_path" >/dev/null 2>&1; then
        echo "✅ Intégrité archive vérifiée"
        
        # Obtenir informations archive
        local archive_size=$(du -h "$archive_path" | cut -f1)
        local file_count=$(unzip -l "$archive_path" 2>/dev/null | tail -1 | awk '{print $2}' || echo "Inconnu")
        
        echo ""
        echo "=== Informations Archive ==="
        echo "Taille : $archive_size"
        echo "Fichiers : $file_count"
        echo "Format : ZIP"
        
        # Vérifier métadonnées
        local metadata_file="${archive_path}.metadata.json"
        if [[ -f "$metadata_file" ]]; then
            echo "Métadonnées : Disponibles"
            local creation_date=$(jq -r '.info_archive.cree' "$metadata_file" 2>/dev/null || echo "Inconnue")
            local archive_id=$(jq -r '.info_archive.id' "$metadata_file" 2>/dev/null || echo "Inconnu")
            echo "Créée : $creation_date"
            echo "ID Archive : $archive_id"
        else
            echo "Métadonnées : Non disponibles"
        fi
        
    else
        echo "❌ Vérification intégrité archive échouée"
        echo "Archive peut être corrompue ou protégée par mot de passe"
        return 1
    fi
}

# Exemples d'utilisation
echo "Exemples Gestionnaire d'Archives Entreprise :"
echo "============================================="
echo ""

echo "1. Créer archive entreprise :"
enterprise_archive_manager "create" "/Users/Shared/documents" "haute_securite" "/tmp/archives"
echo ""

echo "2. Création archives par lots :"
enterprise_archive_manager "batch" "/Users/Shared/source_lot" "default" "/tmp/archives_lot"
echo ""

echo "3. Vérifier intégrité archive :"
enterprise_archive_manager "verify" "/tmp/archives/exemple.zip"

Fonctionnalités Sécurité et Conformité

Système d'Archives Sécurité Avancée

#!/bin/bash

# Système d'archives sécurité et conformité avancées
secure_compliance_archiver() {
    local operation="${1:-audit}"
    local archive_path="$2"
    local compliance_level="${3:-standard}"
    
    echo "🔒 Archiveur Conformité Sécurisé"
    echo "================================"
    echo "Opération : $operation"
    echo "Niveau conformité : $compliance_level"
    echo ""
    
    case "$operation" in
        "audit")
            perform_security_audit "$archive_path" "$compliance_level"
            ;;
        "encrypt")
            apply_advanced_encryption "$archive_path" "$compliance_level"
            ;;
        "validate")
            validate_compliance_requirements "$archive_path" "$compliance_level"
            ;;
        "report")
            generate_compliance_report "$compliance_level"
            ;;
        *)
            echo "❌ Opération inconnue : $operation"
            echo "Opérations disponibles : audit, encrypt, validate, report"
            return 1
            ;;
    esac
}

# Audit sécurité pour archives
perform_security_audit() {
    local archive_path="$1"
    local compliance_level="$2"
    
    echo "🔍 Audit Sécurité"
    echo "=================="
    echo ""
    
    local audit_passed=0
    local audit_warnings=0
    local audit_failures=0
    
    # Vérifier permissions fichier
    if [[ -f "$archive_path" ]]; then
        local permissions=$(stat -f "%A" "$archive_path" 2>/dev/null || echo "inconnues")
        echo "Permissions fichier : $permissions"
        
        if [[ "$permissions" =~ ^[67][0-4][0-4]$ ]]; then
            echo "✅ Permissions sont sécurisées"
            ((audit_passed++))
        else
            echo "⚠️ Permissions peuvent être trop permissives"
            ((audit_warnings++))
        fi
    fi
    
    # Vérifier statut chiffrement
    if file "$archive_path" | grep -q "password-protected\|encrypted"; then
        echo "✅ Archive est protégée par mot de passe"
        ((audit_passed++))
    else
        echo "❌ Archive n'est pas protégée par mot de passe"
        ((audit_failures++))
    fi
    
    # Vérifier intégrité métadonnées
    local metadata_file="${archive_path}.metadata.json"
    if [[ -f "$metadata_file" ]]; then
        echo "✅ Fichier métadonnées présent"
        ((audit_passed++))
        
        # Valider JSON
        if jq empty "$metadata_file" 2>/dev/null; then
            echo "✅ Format métadonnées valide"
            ((audit_passed++))
        else
            echo "❌ Format métadonnées invalide"
            ((audit_failures++))
        fi
    else
        echo "⚠️ Fichier métadonnées manquant"
        ((audit_warnings++))
    fi
    
    # Vérifications spécifiques à la conformité
    case "$compliance_level" in
        "haute"|"entreprise")
            # Vérifier fichier mot de passe sécurisé
            local password_file="${archive_path}.password"
            if [[ -f "$password_file" ]]; then
                local pass_permissions=$(stat -f "%A" "$password_file" 2>/dev/null || echo "inconnues")
                if [[ "$pass_permissions" == "600" ]]; then
                    echo "✅ Permissions fichier mot de passe sécurisées"
                    ((audit_passed++))
                else
                    echo "❌ Permissions fichier mot de passe non sécurisées"
                    ((audit_failures++))
                fi
            fi
            ;;
    esac
    
    # Générer résumé audit
    echo ""
    echo "=== Résumé Audit Sécurité ==="
    echo "Réussis : $audit_passed"
    echo "Avertissements : $audit_warnings"
    echo "Échecs : $audit_failures"
    
    local total_checks=$((audit_passed + audit_warnings + audit_failures))
    if [[ "$audit_failures" -eq 0 ]]; then
        echo "🎉 Audit sécurité RÉUSSI"
        return 0
    else
        echo "❌ Audit sécurité ÉCHOUÉ"
        return 1
    fi
}

# Générer rapport conformité
generate_compliance_report() {
    local compliance_level="$1"
    local report_file="/tmp/roundfleet_archive_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    echo "📊 Génération Rapport Conformité"
    echo "================================="
    echo ""
    
    # Scanner toutes archives Roundfleet
    local archive_dirs=("/tmp/roundfleet_archives" "/tmp/archives" "/tmp/archives_lot")
    local total_archives=0
    local compliant_archives=0
    local non_compliant_archives=0
    
    {
        echo "{"
        echo "  \"rapport_conformite\": {"
        echo "    \"genere\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\","
        echo "    \"nom_hote\": \"$(hostname)\","
        echo "    \"niveau_conformite\": \"$compliance_level\","
        echo "    \"archives\": ["
        
        local first_archive=true
        
        for dir in "${archive_dirs[@]}"; do
            if [[ -d "$dir" ]]; then
                for archive in "$dir"/*.zip; do
                    if [[ -f "$archive" ]]; then
                        if [[ "$first_archive" == "false" ]]; then
                            echo ","
                        fi
                        
                        local archive_name=$(basename "$archive")
                        local archive_size=$(du -h "$archive" | cut -f1)
                        local is_compliant="false"
                        
                        # Vérifier conformité
                        if perform_security_audit "$archive" "$compliance_level" >/dev/null 2>&1; then
                            is_compliant="true"
                            ((compliant_archives++))
                        else
                            ((non_compliant_archives++))
                        fi
                        
                        echo "      {"
                        echo "        \"nom\": \"$archive_name\","
                        echo "        \"chemin\": \"$archive\","
                        echo "        \"taille\": \"$archive_size\","
                        echo "        \"conforme\": $is_compliant"
                        echo -n "      }"
                        
                        first_archive=false
                        ((total_archives++))
                    fi
                done
            fi
        done
        
        echo ""
        echo "    ],"
        echo "    \"resume\": {"
        echo "      \"total_archives\": $total_archives,"
        echo "      \"conformes\": $compliant_archives,"
        echo "      \"non_conformes\": $non_compliant_archives,"
        echo "      \"taux_conformite\": \"$(echo "scale=1; ($compliant_archives * 100) / $total_archives" | bc 2>/dev/null || echo "0")%\""
        echo "    }"
        echo "  }"
        echo "}"
    } > "$report_file"
    
    echo "✅ Rapport conformité généré : $report_file"
    echo ""
    echo "=== Résumé ==="
    echo "Total archives : $total_archives"
    echo "Conformes : $compliant_archives"
    echo "Non conformes : $non_compliant_archives"
    
    if [[ "$total_archives" -gt 0 ]]; then
        local compliance_rate=$(echo "scale=1; ($compliant_archives * 100) / $total_archives" | bc 2>/dev/null || echo "0")
        echo "Taux conformité : ${compliance_rate}%"
    fi
}

# Exécuter opérations conformité
echo "Exemples Sécurité et Conformité :"
echo "================================="
echo ""

echo "1. Générer rapport conformité :"
secure_compliance_archiver "report" "" "entreprise"

Notes Importantes

Fonctionnalités Entreprise

  • Sécurité Avancée - Chiffrement AES-256 avec génération mot de passe sécurisé
  • Gestion Métadonnées - Suivi et documentation archives complets
  • Opérations Lot - Création et gestion archives en masse
  • Vérification Intégrité - Validation archive et détection corruption
  • Rapports Conformité - Audit sécurité et suivi conformité
  • Déploiement Flotte - Opérations archives standardisées sur appareils

Meilleures Pratiques Sécurité

  • Mots de Passe Forts - Génération mots de passe cryptographiquement sécurisés
  • Stockage Sécurisé - Fichiers mots de passe protégés avec permissions restreintes
  • Standards Chiffrement - Chiffrement AES-256 pour sécurité maximale
  • Pistes Audit - Journalisation et suivi opérations complets
  • Contrôles Accès - Permissions fichiers et mesures sécurité appropriées

Opérations Supportées

  • Créer - Création archive fichier unique ou répertoire
  • Lot - Création archives multiples depuis contenu répertoire
  • Vérifier - Test et validation intégrité archive
  • Extraire - Extraction archive sécurisée avec vérification
  • Audit - Vérification conformité sécurité et rapports

Exemples d'Utilisation

# ZIP basique protégé par mot de passe
touch /Users/Shared/fichier.txt
printf 'Bonjour monde\n' > /Users/Shared/fichier.txt
cd /Users/Shared
zip -r fichier.zip fichier.txt --password 1234

# Archive entreprise Roundfleet améliorée
create_basic_password_zip "/Users/Shared/document.pdf" "doc_securise.zip" "MotDePasseSecurise123!"

# Archive entreprise avec métadonnées
enterprise_archive_manager "create" "/Users/Shared/projets" "haute_securite" "/tmp/archives"

# Création archives par lots
enterprise_archive_manager "batch" "/Users/Shared/documents" "default" "/tmp/archives_lot"

# Audit sécurité
secure_compliance_archiver "audit" "/tmp/archives/exemple.zip" "entreprise"

Configurer Paramètres Capture d'Écran sur macOS

Apprenez à personnaliser le comportement des captures d'écran sur Mac, incluant le format de fichier, l'emplacement de sauvegarde et les conventions de nommage. Essentiel pour standardiser les paramètres de capture d'écran dans les flottes Mac d'entreprise.

Changer Format Capture d'Écran

Changez le format par défaut de capture d'écran de PNG vers d'autres formats :

#!/bin/bash

# Obtenir le contexte utilisateur actuel
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

# Configuration
SCREENSHOT_FORMAT="JPG"  # Options : PNG, JPG, PDF, PSD, TIFF, GIF, BMP

echo "Définition format capture d'écran à : $SCREENSHOT_FORMAT"

# Appliquer paramètre format capture d'écran
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture type "$SCREENSHOT_FORMAT"

# Redémarrer SystemUIServer pour appliquer changements
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Format capture d'écran changé vers $SCREENSHOT_FORMAT"

Changer Emplacement Capture d'Écran

Changez l'emplacement de sauvegarde par défaut du Bureau vers un autre dossier :

#!/bin/bash

# Obtenir le contexte utilisateur actuel
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

# Configuration
SCREENSHOT_LOCATION="$HOME/Downloads"  # Changer vers emplacement désiré

echo "Définition emplacement capture d'écran à : $SCREENSHOT_LOCATION"

# S'assurer que le répertoire existe
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    mkdir -p "$SCREENSHOT_LOCATION"

# Appliquer paramètre emplacement capture d'écran
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture location "$SCREENSHOT_LOCATION"

# Redémarrer SystemUIServer pour appliquer changements
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Emplacement capture d'écran changé vers $SCREENSHOT_LOCATION"

Changer Nommage Capture d'Écran

Personnalisez le préfixe de nom de fichier et l'inclusion date/heure :

#!/bin/bash

# Obtenir le contexte utilisateur actuel
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

# Configuration
SCREENSHOT_PREFIX="Roundfleet"  # Changer préfixe de "Screenshot"
INCLUDE_DATETIME="0"          # 0=exclure, 1=inclure date/heure

echo "Définition préfixe capture d'écran à : $SCREENSHOT_PREFIX"
echo "Inclure date/heure : $INCLUDE_DATETIME"

# Appliquer paramètres nommage capture d'écran
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture name "$SCREENSHOT_PREFIX"

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write com.apple.screencapture include-date "$INCLUDE_DATETIME"

# Redémarrer SystemUIServer pour appliquer changements
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Nommage capture d'écran mis à jour"
if [[ "$INCLUDE_DATETIME" == "0" ]]; then
    echo "📝 Nouveau format nom : ${SCREENSHOT_PREFIX}.png"
else
    echo "📝 Nouveau format nom : ${SCREENSHOT_PREFIX} [date] at [heure].png"
fi

Configuration Capture d'Écran Complète

Script complet pour configurer tous les paramètres de capture d'écran en une fois :

#!/bin/bash

# Fonction pour configurer paramètres capture d'écran
configure_screenshot_settings() {
    local format="$1"
    local location="$2"
    local prefix="$3"
    local include_date="$4"
    
    # Obtenir le contexte utilisateur actuel
    local current_user=$(stat -f "%Su" /dev/console)
    local current_user_uid=$(id -u "$current_user")
    
    echo "=== Configuration Capture d'Écran Roundfleet ==="
    echo "👤 Utilisateur : $current_user"
    echo "📸 Format : $format"
    echo "📁 Emplacement : $location"
    echo "📝 Préfixe : $prefix"
    echo "📅 Inclure date/heure : $include_date"
    echo "=============================================="
    
    # Créer répertoire emplacement si nécessaire
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        mkdir -p "$location"
    
    # Appliquer tous paramètres capture d'écran
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture type "$format"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture location "$location"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture name "$prefix"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture include-date "$include_date"
    
    # Redémarrer SystemUIServer pour appliquer tous changements
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        killall SystemUIServer
    
    echo "✅ Tous paramètres capture d'écran appliqués avec succès"
    
    # Afficher exemple nom fichier
    if [[ "$include_date" == "0" ]]; then
        echo "📝 Exemple nom fichier : ${prefix}.${format,,}"
    else
        echo "📝 Exemple nom fichier : ${prefix} $(date '+%Y-%m-%d') at $(date '+%H.%M.%S').${format,,}"
    fi
}

# Configuration entreprise
SCREENSHOT_FORMAT="PNG"
SCREENSHOT_LOCATION="/Users/$(stat -f "%Su" /dev/console)/Pictures/Screenshots"
SCREENSHOT_PREFIX="Roundfleet-Screenshot"
INCLUDE_DATETIME="1"

# Appliquer configuration
configure_screenshot_settings "$SCREENSHOT_FORMAT" "$SCREENSHOT_LOCATION" "$SCREENSHOT_PREFIX" "$INCLUDE_DATETIME"

Réinitialiser aux Paramètres Par Défaut

Restaurer les paramètres de capture d'écran aux valeurs par défaut macOS :

#!/bin/bash

# Obtenir le contexte utilisateur actuel
CURRENT_USER=$(stat -f "%Su" /dev/console)
CURRENT_USER_UID=$(id -u "$CURRENT_USER")

echo "🔄 Réinitialisation paramètres capture d'écran aux valeurs par défaut..."

# Supprimer paramètres capture d'écran personnalisés
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture type 2>/dev/null || true

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture location 2>/dev/null || true

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture name 2>/dev/null || true

launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete com.apple.screencapture include-date 2>/dev/null || true

# Redémarrer SystemUIServer pour appliquer changements
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    killall SystemUIServer

echo "✅ Paramètres capture d'écran réinitialisés aux valeurs par défaut"
echo "📝 Défaut : format PNG, emplacement Bureau, préfixe 'Screenshot' avec date/heure"

Script Déploiement Entreprise

Script pour déploiement en masse sur plusieurs appareils Mac :

#!/bin/bash

# Standardisation capture d'écran entreprise
COMPANY_NAME="Roundfleet"
SCREENSHOT_CONFIG=(
    "format:PNG"
    "location:/Users/CURRENT_USER/Documents/Screenshots"
    "prefix:${COMPANY_NAME}-Screen"
    "include-date:1"
)

# Fonction pour appliquer politique capture d'écran entreprise
apply_enterprise_screenshot_policy() {
    local current_user=$(stat -f "%Su" /dev/console)
    local current_user_uid=$(id -u "$current_user")
    
    echo "🏢 Application Politique Capture d'Écran Entreprise"
    echo "=================================================="
    echo "Appareil : $(hostname)"
    echo "Utilisateur : $current_user"
    echo "Horodatage : $(date)"
    
    # Analyser configuration
    local format location prefix include_date
    for config in "${SCREENSHOT_CONFIG[@]}"; do
        IFS=':' read -r key value <<< "$config"
        # Remplacer placeholder CURRENT_USER
        value="${value//CURRENT_USER/$current_user}"
        
        case "$key" in
            "format") format="$value" ;;
            "location") location="$value" ;;
            "prefix") prefix="$value" ;;
            "include-date") include_date="$value" ;;
        esac
    done
    
    echo "📸 Format : $format"
    echo "📁 Emplacement : $location"
    echo "📝 Préfixe : $prefix"
    echo "📅 Inclure date : $include_date"
    
    # Créer répertoire captures d'écran
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        mkdir -p "$location"
    
    # Appliquer paramètres
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture type "$format"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture location "$location"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture name "$prefix"
    
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write com.apple.screencapture include-date "$include_date"
    
    # Appliquer changements
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        killall SystemUIServer
    
    echo "✅ Politique capture d'écran entreprise appliquée"
    echo "📊 Configuration terminée sur $(hostname)"
}

# Exécuter politique entreprise
apply_enterprise_screenshot_policy

Utilisation avec Roundfleet

  1. Configurez le format, l'emplacement et le nommage désirés dans les variables du script
  2. Déployez via l'exécution de script distant Roundfleet
  3. Vérifiez les paramètres en prenant une capture d'écran test
  4. Surveillez la conformité dans la flotte d'appareils

Formats de Fichier Supportés

FormatDescriptionCas d'Usage
PNGCompression sans perteDéfaut, meilleure qualité
JPGCompression avec perteTailles fichier plus petites
PDFFormat vectorielCaptures d'écran documents
TIFFHaute qualitéImagerie professionnelle
GIFSupport animationGraphiques simples
BMPNon compresséCompatibilité Windows
PSDFormat PhotoshopFlux travail design

Options Emplacement Communes

EmplacementCheminObjectif
Bureau~/DesktopEmplacement par défaut
Téléchargements~/DownloadsAccès facile
Documents~/DocumentsOrganisation
Images~/Pictures/ScreenshotsBibliothèque photos
Personnalisé/chemin/vers/dossierSpécifique entreprise

Dépannage

Paramètres non appliqués : Assurez-vous que SystemUIServer est redémarré après changements Permission refusée : Vérifiez le contexte utilisateur avec launchctl asuser Répertoire non trouvé : Assurez-vous que le répertoire cible existe avant définir l'emplacement

Gestion de l'icône Recopie d'écran dans la barre de menu Mac

La recopie d'écran sur Mac utilise la technologie AirPlay d'Apple pour afficher sans fil le contenu de votre écran Mac sur des appareils compatibles comme Apple TV ou les téléviseurs intelligents compatibles AirPlay. Pour les administrateurs gérant plusieurs systèmes Mac, contrôler la visibilité de l'icône Recopie d'écran dans la barre de menu peut aider à rationaliser l'interface utilisateur et maintenir la cohérence entre les appareils.

Ce guide fournit des scripts shell pour afficher ou masquer programmatiquement l'icône Recopie d'écran dans la barre de menu Mac, particulièrement utile pour la gestion de flotte et les scénarios de déploiement automatisé.

Comprendre la Recopie d'écran

La recopie d'écran vous permet de :

  • Afficher l'écran de votre Mac sur Apple TV ou des téléviseurs intelligents compatibles
  • Faire du mirroring de présentations lors de réunions
  • Diffuser du contenu sur des écrans plus grands
  • Partager votre écran sans fil dans le même réseau

L'option Recopie d'écran peut être contrôlée via les Réglages Système, mais pour une gestion automatisée sur plusieurs appareils, les scripts shell offrent une solution plus efficace.

Prérequis

Avant d'exécuter ces scripts, assurez-vous d'avoir :

  • Privilèges administrateur sur le Mac
  • Accès au Terminal
  • macOS 10.15 ou ultérieur
  • Compréhension de base des scripts shell

Script pour afficher l'icône Recopie d'écran

Ce script rend l'icône Recopie d'écran visible dans la barre de menu :

#!/bin/bash

# Obtenir l'utilisateur actuel et son UID
CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
CurrentUserUID=$(id -u "$CurrentUser")

# Activer la Recopie d'écran dans la barre de menu
launchctl asuser $CurrentUserUID sudo -iu "$CurrentUser" defaults write com.apple.airplay showInMenuBarIfPresent -int 1

echo "L'icône Recopie d'écran a été activée dans la barre de menu"

Ce que fait ce script :

  1. Identifie l'utilisateur actuel : Utilise /dev/console pour déterminer qui est connecté
  2. Obtient l'ID utilisateur : Récupère l'ID numérique de l'utilisateur actuel
  3. Applique le paramètre : Utilise launchctl asuser pour exécuter la commande defaults dans le contexte de l'utilisateur
  4. Active l'icône : Définit showInMenuBarIfPresent à 1 pour afficher l'icône

Script pour masquer l'icône Recopie d'écran

Ce script masque l'icône Recopie d'écran de la barre de menu :

#!/bin/bash

# Obtenir l'utilisateur actuel et son UID
CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
CurrentUserUID=$(id -u "$CurrentUser")

# Désactiver la Recopie d'écran dans la barre de menu
launchctl asuser $CurrentUserUID sudo -iu "$CurrentUser" defaults write com.apple.airplay showInMenuBarIfPresent -int 0

echo "L'icône Recopie d'écran a été masquée de la barre de menu"

Ce que fait ce script :

  1. Identifie l'utilisateur actuel : Même processus que le script d'affichage
  2. Obtient l'ID utilisateur : Récupère l'ID numérique de l'utilisateur
  3. Applique le paramètre : Utilise launchctl asuser pour le bon contexte utilisateur
  4. Masque l'icône : Définit showInMenuBarIfPresent à 0 pour masquer l'icône

Instructions d'utilisation

Exécution des scripts

  1. Enregistrez le script dans un fichier (ex. afficher_recopie_ecran.sh ou masquer_recopie_ecran.sh)
  2. Rendez-le exécutable :
    chmod +x afficher_recopie_ecran.sh
  3. Exécutez le script :
    ./afficher_recopie_ecran.sh

Vérification

Après avoir exécuté l'un des scripts, vous pouvez vérifier les changements :

  1. Vérifiez la barre de menu : L'icône Recopie d'écran devrait apparaître ou disparaître selon le script exécuté
  2. Vérifiez les Réglages Système :
    • Allez dans Réglages Système > Centre de contrôle > Recopie d'écran
    • L'option "Toujours afficher dans la barre de menu" devrait refléter l'action du script

Utilisation avancée

Vérification du statut actuel

Vous pouvez vérifier le statut actuel de l'icône Recopie d'écran :

#!/bin/bash

CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
CurrentUserUID=$(id -u "$CurrentUser")

status=$(launchctl asuser $CurrentUserUID sudo -iu "$CurrentUser" defaults read com.apple.airplay showInMenuBarIfPresent 2>/dev/null)

if [ "$status" = "1" ]; then
    echo "L'icône Recopie d'écran est actuellement affichée dans la barre de menu"
elif [ "$status" = "0" ]; then
    echo "L'icône Recopie d'écran est actuellement masquée de la barre de menu"
else
    echo "Le paramètre de la barre de menu Recopie d'écran n'est pas configuré"
fi

Notes de compatibilité

  • macOS 12.0 et versions antérieures : Le paramètre se trouve dans Préférences Système > Dock et barre de menu > AirPlay
  • macOS 13.0 et versions ultérieures : Le paramètre se trouve dans Réglages Système > Centre de contrôle > Recopie d'écran
  • Modification utilisateur : Les utilisateurs peuvent modifier manuellement ce paramètre depuis les Réglages Système, remplaçant la configuration du script

Bonnes pratiques

  1. Testez d'abord : Toujours tester les scripts sur un seul appareil avant le déploiement en masse
  2. Sauvegardez les paramètres : Envisagez de sauvegarder les paramètres actuels avant de faire des changements
  3. Communication utilisateur : Informez les utilisateurs des changements apportés à leur configuration de barre de menu
  4. Documentation : Conservez des enregistrements des appareils qui ont quelles configurations
  5. Audits réguliers : Vérifiez périodiquement que les paramètres restent conformes aux intentions

Dépannage

Problèmes courants

  1. Permission refusée : Assurez-vous que le script a des privilèges sudo
  2. Utilisateur non trouvé : Le script peut échouer s'il est exécuté quand aucun utilisateur n'est connecté
  3. Paramètre non appliqué : Essayez de vous déconnecter et reconnecter pour rafraîchir la barre de menu

Débogage

Ajoutez du débogage à vos scripts :

#!/bin/bash

# Activer le débogage
set -x

CurrentUser=$(ls -l /dev/console | awk '/ / { print $3 }')
echo "Utilisateur actuel : $CurrentUser"

CurrentUserUID=$(id -u "$CurrentUser")
echo "UID utilisateur : $CurrentUserUID"

# Continuer avec le reste du script...

Considérations de sécurité

  • Ces scripts nécessitent des privilèges administrateur
  • Toujours valider la source des scripts avant exécution
  • Envisagez d'implémenter la journalisation pour les pistes d'audit
  • Testez les scripts dans un environnement contrôlé en premier

Conclusion

La gestion de la visibilité de l'icône Recopie d'écran dans la barre de menu Mac via des scripts shell fournit aux administrateurs des outils puissants pour maintenir des interfaces utilisateur cohérentes à travers leur flotte Mac. Que vous déployiez sur un seul appareil ou gériez des centaines de Mac, ces scripts offrent une solution automatisée et fiable.

N'oubliez pas de tester minutieusement tous les scripts dans votre environnement et de considérer l'expérience utilisateur lors de modifications d'interface. Avec une implémentation appropriée, vous pouvez rationaliser votre flux de travail de gestion Mac tout en maintenant la flexibilité dont les utilisateurs ont besoin pour leur travail quotidien.

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 Roundfleet 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 Roundfleet. 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 Roundfleet
# Application et surveillance complètes des politiques de sécurité

# Configuration
SECURITY_CONFIG_FILE="/etc/roundfleet/screen_lock_config.conf"
LOG_FILE="/var/log/roundfleet_screen_lock.log"
STATUS_FILE="/var/log/roundfleet_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/roundfleet_security_report_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport de Sécurité de Verrouillage d'Écran Roundfleet"
        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 Roundfleet 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 Roundfleet 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/roundfleet"
    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 Roundfleet
# 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 Roundfleet. 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 Roundfleet

#!/bin/bash

# Intégration de sécurité de verrouillage d'écran Roundfleet
roundfleet_security_integration() {
    echo "=== Intégration de Sécurité de Verrouillage d'Écran Roundfleet ==="
    
    # 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 Roundfleet
    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 Roundfleet"
    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"
}

roundfleet_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 Roundfleet 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 Roundfleet\" 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 Roundfleet
# Planification avancée, surveillance et déploiement de flotte

# Configuration
SCRIPT_NAME="Roundfleet Restart Manager"
VERSION="3.0.0"
LOG_FILE="/var/log/roundfleet_restart.log"
CONFIG_DIR="/etc/roundfleet/restart"
SCHEDULE_DIR="/etc/roundfleet/restart/schedules"
POLICY_DIR="/etc/roundfleet/restart/policies"
AUDIT_DIR="/etc/roundfleet/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 Roundfleet : $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.roundfleet.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/roundfleet_restart.sh" >/dev/null 2>&1 && \
           ssh "$host" "chmod +x /tmp/roundfleet_restart.sh && sudo /tmp/roundfleet_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 Roundfleet ==="
    
    # 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 ./roundfleet_restart.sh --schedule immediate

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

Planification Sûre pour les Affaires

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

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

Déploiement de Flotte

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

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

Planification Personnalisée

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

# Programmer un redémarrage pour 18h
sudo ./roundfleet_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 roundfleet

É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
./roundfleet_restart.sh --status

Gestion Navigateur Safari sur macOS

Gérez les configurations et politiques navigateur Safari sur vos appareils Roundfleet 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://roundfleet.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://roundfleet.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 Roundfleet"
    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://roundfleet.io:true:true:false"
    config_profiles[securise]="https://roundfleet.io:true:true:true"
    config_profiles[education]="https://education.roundfleet.io:true:false:true"
    config_profiles[kiosque]="https://kiosque.roundfleet.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" =~ roundfleet ]] && [[ "$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 Roundfleet
  • 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://roundfleet.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 Roundfleet améliorée
configure_safari_homepage "https://roundfleet.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 Roundfleet 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/roundfleet_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 Roundfleet"
    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/roundfleet_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 Roundfleet"
        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/roundfleet_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é Roundfleet"
            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 Roundfleet 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 Roundfleet 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 Roundfleet
# Localisation d'appareils complète, alertes audio et suivi de flotte

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_remote_ring.log"
REPORT_DIR="/etc/roundfleet/reports/location"
CONFIG_DIR="/etc/roundfleet/location"
SOUND_DIR="/etc/roundfleet/sounds"
POLICY_DIR="/etc/roundfleet/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 Roundfleet 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