Guide

Nouvelles mises à jour et améliorations de Roundfleet.

Découverte et Gestion de Recherche de Fichiers sur macOS

Découvrez et gérez les fichiers sur vos appareils Roundfleet en utilisant des systèmes de recherche et découverte de fichiers avancés. Ce tutoriel couvre la recherche de chemins de fichiers, les recherches basées sur les extensions, l'analyse de contenu et la gestion complète du cycle de vie des fichiers.

Comprendre la Découverte de Fichiers macOS

macOS fournit plusieurs capacités de découverte et recherche de fichiers :

  • find - Utilitaire de recherche de fichiers et répertoires en ligne de commande
  • Résolution de Chemin de Fichier - Localiser des fichiers spécifiques par nom et extension
  • Filtrage par Extension - Rechercher des fichiers par type et format de fichier
  • Recherche de Contenu - Trouver des fichiers basés sur le contenu et les métadonnées
  • Intégration Spotlight - Exploiter l'indexation macOS pour des recherches rapides

Opérations de Découverte de Fichiers de Base

Trouver un Chemin de Fichier

#!/bin/bash

# Recherche de chemin de fichier de base
find / -name 'nom de fichier avec extension' -print 2>/dev/null

echo "Recherche de chemin de fichier terminée"

Découverte de Fichiers Améliorée

#!/bin/bash

# Découverte de fichiers complète avec multiples méthodes de recherche
discover_file_paths() {
    local file_pattern="$1"
    local search_scope="${2:-/}"
    local search_type="${3:-name}"
    
    echo "=== Découverte de Fichiers et Résolution de Chemin ==="
    echo "Motif de Recherche : $file_pattern"
    echo "Portée de Recherche : $search_scope"
    echo "Type de Recherche : $search_type"
    
    # Valider les paramètres de recherche
    if [[ -z "$file_pattern" ]]; then
        echo "❌ Le motif de fichier est requis"
        return 1
    fi
    
    if [[ ! -d "$search_scope" ]]; then
        echo "❌ Répertoire de portée de recherche non trouvé : $search_scope"
        return 1
    fi
    
    # Effectuer la recherche basée sur le type
    echo "Démarrage de la découverte de fichiers..."
    local results_count=0
    
    case "$search_type" in
        "name")
            echo "Recherche par nom de fichier..."
            find "$search_scope" -name "$file_pattern" -print 2>/dev/null | while read -r file_path; do
                echo "Trouvé : $file_path"
                ((results_count++))
            done
            ;;
        "iname")
            echo "Recherche par nom de fichier (insensible à la casse)..."
            find "$search_scope" -iname "$file_pattern" -print 2>/dev/null | while read -r file_path; do
                echo "Trouvé : $file_path"
                ((results_count++))
            done
            ;;
        "type")
            echo "Recherche par type de fichier..."
            find "$search_scope" -type f -name "$file_pattern" -print 2>/dev/null | while read -r file_path; do
                echo "Trouvé : $file_path"
                ((results_count++))
            done
            ;;
        "content")
            echo "Recherche par contenu..."
            grep -r "$file_pattern" "$search_scope" 2>/dev/null | while read -r match; do
                echo "Correspondance de contenu : $match"
                ((results_count++))
            done
            ;;
        *)
            echo "❌ Type de recherche inconnu : $search_type"
            return 1
            ;;
    esac
    
    echo "✅ Découverte de fichiers terminée"
    log_discovery_action "$file_pattern" "$search_scope" "$search_type" "succès"
    
    return 0
}

# Exemple d'utilisation
# discover_file_paths "document.txt" "/" "name"

Lister les Fichiers par Extension

#!/bin/bash

# Recherche d'extension de fichier améliorée
find_files_by_extension() {
    local extension="$1"
    local count="${2:-10}"
    local search_path="${3:-/}"
    
    echo "=== Recherche de Fichiers par Extension ==="
    echo "Extension : .$extension"
    echo "Limite de Résultats : $count"
    echo "Chemin de Recherche : $search_path"
    
    # Recherche d'extension de base
    echo "Recherche de fichiers .$extension..."
    find "$search_path" -name "*.$extension" -print 2>/dev/null | head -n "$count"
    
    echo "✅ Recherche d'extension terminée"
}

# Exemple d'utilisation
# find_files_by_extension "txt" 10 "/"

Catégories de Découverte de Fichiers

Classifications de Types de Fichiers

#!/bin/bash

# Catégories de découverte de fichiers pour différents types de fichiers et objectifs
declare -A FILE_CATEGORIES=(
    ["config_systeme"]="Fichiers de configuration système et préférences"
    ["donnees_application"]="Fichiers de données d'application et préférences utilisateur"
    ["contenu_media"]="Images, vidéos, fichiers audio et contenu multimédia"
    ["fichiers_document"]="Documents texte, feuilles de calcul, présentations"
    ["code_developpement"]="Code source, scripts, projets de développement"
    ["archive_compresse"]="Archives compressées et fichiers de sauvegarde"
    ["certificats_securite"]="Certificats de sécurité, clés et identifiants"
    ["log_diagnostic"]="Journaux système, fichiers de diagnostic et données de dépannage"
    ["cache_temporaire"]="Fichiers cache, données temporaires et contenu jetable"
    ["base_donnees_structuree"]="Fichiers de base de données et stockage de données structurées"
)

# Extensions de fichiers pour chaque catégorie
declare -A CATEGORY_EXTENSIONS=(
    ["config_systeme"]="plist,conf,cfg,ini,settings,preferences"
    ["donnees_application"]="app,dmg,pkg,bundle,framework"
    ["contenu_media"]="jpg,jpeg,png,gif,mp4,mov,mp3,wav,m4a"
    ["fichiers_document"]="pdf,doc,docx,xls,xlsx,ppt,pptx,txt,rtf"
    ["code_developpement"]="swift,m,h,py,js,ts,php,java,cpp,c"
    ["archive_compresse"]="zip,tar,gz,bz2,rar,7z,dmg"
    ["certificats_securite"]="p12,pem,crt,key,keychain,cer"
    ["log_diagnostic"]="log,crash,diag,report,trace"
    ["cache_temporaire"]="cache,tmp,temp,bak,swp"
    ["base_donnees_structuree"]="db,sqlite,sql,json,xml,csv"
)

# Priorités de recherche pour différentes catégories
declare -A SEARCH_PRIORITIES=(
    ["config_systeme"]="haute"
    ["donnees_application"]="moyenne"
    ["contenu_media"]="faible"
    ["fichiers_document"]="haute"
    ["code_developpement"]="moyenne"
    ["archive_compresse"]="faible"
    ["certificats_securite"]="critique"
    ["log_diagnostic"]="moyenne"
    ["cache_temporaire"]="faible"
    ["base_donnees_structuree"]="haute"
)

print_file_categories() {
    echo "=== Catégories de Découverte de Fichiers ==="
    for category in "${!FILE_CATEGORIES[@]}"; do
        echo "Catégorie : $category"
        echo "  Description : ${FILE_CATEGORIES[$category]}"
        echo "  Extensions : ${CATEGORY_EXTENSIONS[$category]}"
        echo "  Priorité : ${SEARCH_PRIORITIES[$category]}"
        echo ""
    done
}

# Afficher les catégories disponibles
print_file_categories

Politiques de Découverte de Fichiers

Politiques de Recherche et Découverte

#!/bin/bash

# Politiques de découverte de fichiers pour différentes exigences organisationnelles
declare -A DISCOVERY_POLICIES=(
    ["audit_securite"]="Découverte de fichiers axée sécurité avec numérisation complète"
    ["conformite_gdpr"]="Découverte de fichiers conforme GDPR pour identification de données personnelles"
    ["inventaire_actifs"]="Inventaire complet d'actifs et catalogage de fichiers"
    ["nettoyage_performance"]="Optimisation de performance par identification de nettoyage de fichiers"
    ["verification_sauvegarde"]="Vérification de sauvegarde et contrôle d'intégrité de données"
    ["enquete_medico_legale"]="Découverte de fichiers médico-légaux pour enquête d'incident"
)

# Obtenir la configuration de politique de découverte
get_discovery_policy() {
    local policy_type="$1"
    
    case "$policy_type" in
        "audit_securite")
            cat << EOF
{
    "decouverte_activee": true,
    "portee_recherche": "complete",
    "types_fichiers_priorite": ["certificats_securite", "config_systeme", "log_diagnostic"],
    "analyse_contenu": true,
    "collecte_metadonnees": true,
    "analyse_permissions": true,
    "verification_hash": true,
    "suivi_acces": true,
    "detection_chiffrement": true,
    "motifs_suspects": ["password", "key", "token", "secret"],
    "niveau_rapport": "detaille",
    "journalisation_audit": "complete",
    "surveillance_temps_reel": true
}
EOF
            ;;
        "conformite_gdpr")
            cat << EOF
{
    "decouverte_activee": true,
    "portee_recherche": "donnees_utilisateur_focus",
    "types_fichiers_priorite": ["fichiers_document", "base_donnees_structuree", "donnees_application"],
    "analyse_contenu": true,
    "collecte_metadonnees": true,
    "detection_donnees_personnelles": true,
    "classification_donnees": true,
    "analyse_retention": true,
    "suivi_consentement": false,
    "identification_sujet_donnees": true,
    "analyse_transfrontaliere": true,
    "motifs_vie_privee": ["email", "phone", "ssn", "passport", "address"],
    "niveau_rapport": "conforme_vie_privee",
    "journalisation_audit": "conforme_gdpr",
    "cartographie_donnees": true
}
EOF
            ;;
        "inventaire_actifs")
            cat << EOF
{
    "decouverte_activee": true,
    "portee_recherche": "systeme_complet",
    "types_fichiers_priorite": ["donnees_application", "config_systeme", "fichiers_document"],
    "analyse_contenu": false,
    "collecte_metadonnees": true,
    "analyse_taille": true,
    "suivi_modification": true,
    "analyse_propriete": true,
    "detection_version": true,
    "conformite_licence": true,
    "detection_doublons": true,
    "optimisation_stockage": true,
    "niveau_rapport": "focus_inventaire",
    "journalisation_audit": "standard",
    "catalogage": true
}
EOF
            ;;
        *)
            echo "Politique de découverte inconnue : $policy_type"
            return 1
            ;;
    esac
}

# Appliquer une politique de découverte
apply_discovery_policy() {
    local policy="$1"
    local config_file="/tmp/politique_decouverte.json"
    
    echo "Application de la politique de découverte de fichiers : $policy"
    
    get_discovery_policy "$policy" > "$config_file"
    
    if [[ ! -f "$config_file" ]]; then
        echo "❌ Échec de génération de configuration de politique"
        return 1
    fi
    
    echo "✅ Politique de découverte de fichiers appliquée avec succès"
    echo "Configuration : $config_file"
    
    # Afficher les paramètres clés de politique
    echo "=== Résumé de Politique ==="
    echo "Découverte Activée : $(jq -r '.decouverte_activee' "$config_file")"
    echo "Portée de Recherche : $(jq -r '.portee_recherche' "$config_file")"
    echo "Analyse de Contenu : $(jq -r '.analyse_contenu' "$config_file")"
    echo "Collecte de Métadonnées : $(jq -r '.collecte_metadonnees' "$config_file")"
    echo "Niveau de Rapport : $(jq -r '.niveau_rapport' "$config_file")"
    
    return 0
}

Découverte et Analyse Avancées de Fichiers

Système de Découverte de Fichiers Complet

#!/bin/bash

# Découverte de fichiers avancée avec analyse de contenu et extraction de métadonnées
advanced_file_discovery() {
    local search_criteria="$1"
    local analysis_level="${2:-standard}"
    local output_format="${3:-text}"
    
    echo "=== Système de Découverte de Fichiers Avancé ==="
    echo "Critères de Recherche : $search_criteria"
    echo "Niveau d'Analyse : $analysis_level"
    echo "Format de Sortie : $output_format"
    
    local discovery_report="/tmp/decouverte_fichiers_$(date +%Y%m%d_%H%M%S).json"
    
    # Initialiser le rapport de découverte
    cat > "$discovery_report" << EOF
{
    "session_decouverte": {
        "criteres_recherche": "$search_criteria",
        "niveau_analyse": "$analysis_level",
        "horodatage": "$(date -Iseconds)",
        "nom_hote": "$(hostname)",
        "operateur": "$(whoami)"
    },
    "fichiers_decouverts": [],
    "statistiques_fichiers": {},
    "analyse_contenu": {},
    "resultats_securite": {}
}
EOF
    
    # Effectuer une découverte de fichiers complète
    echo "Exécution de recherche de fichiers complète..."
    
    # Recherche par multiples critères
    local files_found=0
    
    # Recherche de nom de fichier de base
    echo "  - Recherche par motifs de nom de fichier..."
    find / -name "*$search_criteria*" -type f -print 2>/dev/null | while read -r file_path; do
        analyze_discovered_file "$file_path" "$analysis_level" "$discovery_report"
        ((files_found++))
    done
    
    # Recherche basée sur le contenu
    if [[ "$analysis_level" == "complet" ]]; then
        echo "  - Exécution d'analyse de contenu..."
        grep -r "$search_criteria" / 2>/dev/null | head -100 | while read -r match; do
            local file_path
            file_path=$(echo "$match" | cut -d':' -f1)
            analyze_discovered_file "$file_path" "$analysis_level" "$discovery_report"
        done
    fi
    
    # Générer des statistiques de fichiers
    generate_file_statistics "$discovery_report"
    
    # Afficher les résultats
    echo ""
    echo "Résultats de Découverte :"
    echo "  Fichiers Trouvés : $files_found"
    echo "  Rapport de Découverte : $discovery_report"
    
    # Formater la sortie
    case "$output_format" in
        "json")
            cat "$discovery_report"
            ;;
        "resume")
            jq -r '.session_decouverte, .statistiques_fichiers' "$discovery_report"
            ;;
        *)
            echo "Découverte terminée - voir le fichier de rapport pour détails"
            ;;
    esac
    
    return 0
}

# Analyser un fichier découvert
analyze_discovered_file() {
    local file_path="$1"
    local analysis_level="$2"
    local report_file="$3"
    
    if [[ ! -f "$file_path" ]]; then
        return 1
    fi
    
    # Informations de fichier de base
    local file_size
    file_size=$(stat -f%z "$file_path" 2>/dev/null || echo "0")
    local file_permissions
    file_permissions=$(stat -f%A "$file_path" 2>/dev/null || echo "inconnu")
    local file_owner
    file_owner=$(stat -f%Su "$file_path" 2>/dev/null || echo "inconnu")
    local modification_time
    modification_time=$(stat -f%Sm "$file_path" 2>/dev/null || echo "inconnu")
    
    # Analyse améliorée pour niveau complet
    local file_type="inconnu"
    local content_preview=""
    local security_flags=""
    
    if [[ "$analysis_level" == "complet" ]]; then
        file_type=$(file -b "$file_path" 2>/dev/null || echo "inconnu")
        
        # Aperçu de contenu sécurisé pour fichiers texte
        if file "$file_path" | grep -q "text"; then
            content_preview=$(head -c 200 "$file_path" 2>/dev/null | tr '\n' ' ')
        fi
        
        # Analyse de sécurité
        if [[ "$file_permissions" =~ 7.* ]]; then
            security_flags="executable_par_proprietaire"
        fi
        
        if [[ "$file_path" =~ \.key$|\.pem$|\.p12$ ]]; then
            security_flags="${security_flags},potentiel_identifiant_securite"
        fi
    fi
    
    # Journaliser la découverte de fichier
    log_discovered_file "$file_path" "$file_size" "$file_type" "$security_flags"
}

# Journaliser un fichier découvert
log_discovered_file() {
    local file_path="$1"
    local file_size="$2"
    local file_type="$3"
    local security_flags="$4"
    
    echo "$(date '+%Y-%m-%d %H:%M:%S') - Fichier Découvert : $file_path (Taille : $file_size, Type : $file_type, Sécurité : $security_flags)" >> "/var/log/roundfleet_decouverte_fichiers.log"
}

Système de Gestion de Découverte de Fichiers

#!/bin/bash

# Système de Gestion de Découverte et Recherche de Fichiers Roundfleet
# Découverte, catalogage et gestion complètes de fichiers

# Configuration
CONFIG_DIR="/etc/roundfleet/decouverte"
LOG_FILE="/var/log/roundfleet_decouverte_fichiers.log"
AUDIT_LOG="/var/log/roundfleet_audit_decouverte.log"
INDEX_DIR="/var/index/roundfleet/decouverte"

# 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"
}

# Indexation du système de fichiers
create_file_index() {
    local index_scope="${1:-/Users}"
    local index_level="${2:-standard}"
    
    log_action "Création d'index du système de fichiers : $index_scope (Niveau : $index_level)"
    
    echo "=== Indexation du Système de Fichiers ==="
    echo "Portée d'Index : $index_scope"
    echo "Niveau d'Index : $index_level"
    
    local index_file="$INDEX_DIR/index_fichiers_$(date +%Y%m%d_%H%M%S).json"
    
    # Initialiser l'index
    cat > "$index_file" << EOF
{
    "metadonnees_index": {
        "portee": "$index_scope",
        "niveau": "$index_level",
        "cree": "$(date -Iseconds)",
        "nom_hote": "$(hostname)",
        "total_fichiers": 0,
        "taille_totale": 0
    },
    "entrees_fichiers": []
}
EOF
    
    echo "Démarrage de l'indexation du système de fichiers..."
    local file_count=0
    
    # Indexer les fichiers basé sur le niveau
    case "$index_level" in
        "de_base")
            find "$index_scope" -type f -print 2>/dev/null | while read -r file_path; do
                index_file_basic "$file_path" "$index_file"
                ((file_count++))
                
                if [[ $((file_count % 1000)) -eq 0 ]]; then
                    echo "  Indexé $file_count fichiers..."
                fi
            done
            ;;
        "standard")
            find "$index_scope" -type f -print 2>/dev/null | while read -r file_path; do
                index_file_standard "$file_path" "$index_file"
                ((file_count++))
                
                if [[ $((file_count % 500)) -eq 0 ]]; then
                    echo "  Indexé $file_count fichiers..."
                fi
            done
            ;;
        "complet")
            find "$index_scope" -type f -print 2>/dev/null | while read -r file_path; do
                index_file_comprehensive "$file_path" "$index_file"
                ((file_count++))
                
                if [[ $((file_count % 100)) -eq 0 ]]; then
                    echo "  Indexé $file_count fichiers..."
                fi
            done
            ;;
        *)
            echo "❌ Niveau d'index inconnu : $index_level"
            return 1
            ;;
    esac
    
    echo "✅ Indexation du système de fichiers terminée"
    echo "  Fichiers Indexés : $file_count"
    echo "  Fichier d'Index : $index_file"
    
    audit_log "Index du système de fichiers créé : $index_scope ($file_count fichiers)"
    
    return 0
}

# Fonction principale avec routage de commandes
main() {
    local command="$1"
    shift
    
    case "$command" in
        "trouver_fichier")
            # Trouver un fichier spécifique par nom
            discover_file_paths "$@"
            ;;
        "trouver_extension")
            # Trouver des fichiers par extension
            find_files_by_extension "$@"
            ;;
        "recherche_avancee")
            # Découverte de fichiers avancée
            advanced_file_discovery "$@"
            ;;
        "creer_index")
            # Créer un index du système de fichiers
            create_file_index "$@"
            ;;
        "appliquer_politique")
            # Appliquer une politique de découverte
            apply_discovery_policy "$@"
            ;;
        "afficher_categories")
            # Afficher les catégories de fichiers
            print_file_categories
            ;;
        "afficher_politiques")
            # Afficher les politiques disponibles
            for policy in audit_securite conformite_gdpr inventaire_actifs nettoyage_performance verification_sauvegarde enquete_medico_legale; do
                echo "Politique : $policy"
                get_discovery_policy "$policy" | jq .
                echo ""
            done
            ;;
        *)
            echo "Système de Gestion de Découverte et Recherche de Fichiers Roundfleet"
            echo "Utilisation : $0 <commande> [options]"
            echo ""
            echo "Commandes :"
            echo "  trouver_fichier <motif> [portée] [type]               - Trouver fichiers spécifiques par motif"
            echo "  trouver_extension <ext> [nombre] [chemin]             - Trouver fichiers par extension"
            echo "  recherche_avancee <critères> [niveau] [format]       - Découverte de fichiers avancée"
            echo "  creer_index [portée] [niveau]                        - Créer index du système de fichiers"
            echo "  appliquer_politique <politique>                      - Appliquer politique de découverte"
            echo "  afficher_categories                                  - Afficher catégories de fichiers"
            echo "  afficher_politiques                                  - Afficher politiques de découverte"
            echo ""
            echo "Exemples :"
            echo "  $0 trouver_fichier \"document.txt\" \"/Users\" \"name\""
            echo "  $0 trouver_extension \"pdf\" 20 \"/Users\""
            echo "  $0 recherche_avancee \"config\" \"complet\" \"json\""
            echo "  $0 creer_index \"/Users\" \"standard\""
            echo "  $0 appliquer_politique \"audit_securite\""
            ;;
    esac
}

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

Considérations de Sécurité

Sécurité de Découverte de Fichiers

  • Contrôles d'Accès - Respecter les permissions de fichiers et restrictions d'accès
  • Protection de Données Sensibles - Éviter d'exposer le contenu de fichiers sensibles dans les journaux
  • Impact sur les Performances - Surveiller les performances système pendant la découverte à grande échelle
  • Conformité de Vie Privée - S'assurer que les pratiques de découverte respectent les réglementations de vie privée
  • Pistes d'Audit - Maintenir des journaux complets des activités de découverte

Cadre de Conformité

  • Classification de Données - Classifier correctement les fichiers découverts basé sur la sensibilité
  • Politiques de Rétention - Implémenter la rétention et élimination appropriées de données
  • Journalisation d'Accès - Journaliser tous les accès aux fichiers et activités de découverte
  • Protection de Vie Privée - Protéger les informations personnelles et sensibles pendant la découverte
  • Conformité Réglementaire - Respecter les exigences de découverte et catalogage spécifiques à l'industrie

Guide de Dépannage

Problèmes Courants

Erreurs de Permission Refusée

  • Exécuter la découverte avec privilèges appropriés : sudo pour recherches système
  • Vérifier les permissions de fichiers et répertoires : ls -la
  • Vérifier l'accessibilité de la portée de recherche

Performance de Recherche Lente

  • Limiter la portée de recherche à des répertoires spécifiques
  • Utiliser des recherches indexées pour données fréquemment consultées
  • Considérer la spécificité des critères de recherche

Commandes de Diagnostic

# Tester la fonctionnalité find de base
find /Users -name "*.txt" -print 2>/dev/null | head -5

# Vérifier les permissions du système de fichiers
ls -la /chemin/vers/repertoire/recherche

# Surveiller les performances de recherche
time find /Users -name "motif" -print 2>/dev/null

# Vérifier l'espace disque disponible pour l'indexation
df -h

Notes Importantes

  • Échappement de Chemin de Fichier - Utiliser des guillemets ou barres obliques inverses pour chemins avec espaces : "Nouveau Dossier/fichier.txt" ou Nouveau\ Dossier/fichier.txt
  • Portée de Recherche - Les recherches plus larges prennent plus de temps mais fournissent des résultats plus complets
  • Impact Système - La découverte de fichiers à grande échelle peut impacter les performances système
  • Limites de Résultats - Utiliser des limites appropriées pour éviter une sortie écrasante
  • Maintenance d'Index - Mettre régulièrement à jour les index de fichiers pour précision
  • Sensibilisation à la Sécurité - Être prudent lors de la recherche de fichiers et identifiants sensibles

Gestion Entreprise de la Suppression de Fichiers et Dossiers pour macOS

Implémentez une gestion de suppression de fichiers et dossiers de niveau entreprise sur votre déploiement Roundfleet avec la suppression sécurisée de données, les pistes d'audit, la protection par sauvegarde, la gestion de conformité et les opérations de nettoyage automatisées. Ce tutoriel fournit des solutions pour maintenir l'hygiène des données tout en assurant la sécurité, la conformité et la protection des données.

Comprendre la Gestion de Suppression de Fichiers macOS

macOS fournit plusieurs méthodes pour la suppression de fichiers et dossiers :

  • rm - Supprimer fichiers et répertoires depuis la ligne de commande
  • rm -r - Suppression récursive pour répertoires avec contenu
  • rm -f - Suppression forcée sans invites de confirmation
  • Finder - Opérations de suppression/corbeille basées sur GUI
  • srm - Suppression sécurisée avec écrasement de données (legacy)

Opérations de Suppression de Fichiers de Base

Suppression Simple de Fichier/Dossier

#!/bin/bash

# Suppression de fichier de base
rm '/chemin vers le fichier ou dossier'

Suppression de Répertoire Récursive

#!/bin/bash

# Suppression de dossier récursive
rm -rf /Users/nomutilisateur/Desktop/Mes\ Fichiers

Supprimer Seulement le Contenu du Dossier

#!/bin/bash

# Supprimer le contenu du dossier
rm '/chemin vers le dossier/*'

Suppression de Fichiers Multiples

#!/bin/bash

# Supprimer des fichiers spécifiques multiples
rm Desktop/1.png Desktop/2.png

# Supprimer des fichiers par motif
rm Desktop/{1,2}.png

# Supprimer tous les fichiers d'un type
rm Desktop/*.png

Système de Gestion de Suppression de Fichiers Entreprise

#!/bin/bash

# Outil de Gestion de Suppression de Fichiers et Dossiers Entreprise Roundfleet
# Suppression sécurisée de données avec capacités de conformité et d'audit

# Configuration
CONFIG_FILE="/etc/roundfleet/file_deletion_policy.conf"
LOG_FILE="/var/log/roundfleet_file_deletion.log"
BACKUP_DIR="/Library/Roundfleet/DeletedFiles"
AUDIT_LOG="/var/log/roundfleet_deletion_audit.log"
QUARANTINE_DIR="/Library/Roundfleet/QuarantinedFiles"

# Créer les répertoires
mkdir -p "$(dirname "$CONFIG_FILE")" "$(dirname "$LOG_FILE")" "$BACKUP_DIR" "$(dirname "$AUDIT_LOG")" "$QUARANTINE_DIR"

# Politique de gestion de suppression de fichiers par défaut
cat > "$CONFIG_FILE" 2>/dev/null << 'EOF' || true
# Politique de Gestion de Suppression de Fichiers Entreprise Roundfleet
# Version : 2.0

# Application des Politiques de Suppression
ENFORCE_DELETION_POLICIES=true
REQUIRE_BACKUP_BEFORE_DELETE=true
SECURE_DELETION_ENABLED=true
PREVENT_SYSTEM_FILE_DELETION=true
BUSINESS_HOURS_PROTECTION=true

# Sécurité et Protection des Données
REQUIRE_ADMIN_APPROVAL=false
VALIDATE_FILE_PERMISSIONS=true
PROTECTED_DIRECTORIES_ENFORCEMENT=true
MALWARE_QUARANTINE_CHECK=true
SENSITIVE_DATA_DETECTION=true

# Sauvegarde et Récupération
AUTOMATIC_BACKUP_ENABLED=true
BACKUP_RETENTION_DAYS=30
COMPRESSED_BACKUPS=true
ENCRYPTED_BACKUPS=true
RECOVERY_VALIDATION=true

# Conformité et Audit
AUDIT_ALL_DELETIONS=true
COMPLIANCE_REPORTING=true
INCIDENT_DOCUMENTATION=true
GDPR_COMPLIANCE=true
DATA_CLASSIFICATION_AWARE=true

# Expérience Utilisateur
USER_NOTIFICATION_ENABLED=true
DELETION_CONFIRMATION=true
PROGRESS_MONITORING=true
BATCH_OPERATION_SUPPORT=true
ROLLBACK_CAPABILITY=true

# Performance et Sécurité
DELETION_TIMEOUT=300
MAX_CONCURRENT_DELETIONS=5
SIZE_LIMIT_CHECK=true
FREE_SPACE_MONITORING=true
SYSTEM_LOAD_MONITORING=true
EOF

# Charger la configuration
source "$CONFIG_FILE" 2>/dev/null || true

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

# Fonction de journalisation d'audit
audit_log() {
    local action="$1"
    local file_path="$2"
    local result="$3"
    local details="$4"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ACTION:$action FILE:$file_path RESULT:$result DETAILS:$details USER:$(whoami) SIZE:$(get_file_size "$file_path")" >> "$AUDIT_LOG"
}

# Obtenir la taille de fichier pour audit
get_file_size() {
    local file_path="$1"
    if [[ -e "$file_path" ]]; then
        du -sh "$file_path" 2>/dev/null | awk '{print $1}' || echo "inconnu"
    else
        echo "0"
    fi
}

# Valider la sécurité de suppression de fichier
validate_deletion_safety() {
    local file_path="$1"
    local force="${2:-false}"
    
    echo "=== Validation de Sécurité de Suppression de Fichier ==="
    
    # Vérifier si le fichier/répertoire existe
    if [[ ! -e "$file_path" ]]; then
        echo "❌ Fichier ou répertoire introuvable : $file_path"
        audit_log "VALIDATION" "$file_path" "NOT_FOUND" "Fichier ou répertoire n'existe pas"
        return 1
    fi
    
    echo "✅ Fichier/répertoire trouvé : $file_path"
    
    # Empêcher la suppression de fichiers système
    if [[ "$PREVENT_SYSTEM_FILE_DELETION" == "true" ]]; then
        local protected_paths=(
            "/System"
            "/Library/System"
            "/usr/bin"
            "/usr/sbin"
            "/bin"
            "/sbin"
            "/var/db"
            "/private/var/db"
            "/Applications/Utilities"
        )
        
        for protected_path in "${protected_paths[@]}"; do
            if [[ "$file_path" == "$protected_path"* ]]; then
                echo "❌ Impossible de supprimer le chemin système protégé : $file_path"
                audit_log "VALIDATION" "$file_path" "PROTECTED_PATH" "Suppression de fichier système bloquée"
                return 1
            fi
        done
    fi
    
    # Vérifier les répertoires protégés
    if [[ "$PROTECTED_DIRECTORIES_ENFORCEMENT" == "true" && "$force" != "true" ]]; then
        local protected_dirs=(
            "/Users/*/Documents/Important"
            "/Users/*/Desktop/Critique"
            "/Library/Roundfleet/Config"
            "/etc"
            "/Applications"
        )
        
        for protected_dir in "${protected_dirs[@]}"; do
            if [[ "$file_path" == $protected_dir* ]]; then
                echo "❌ Fichier dans répertoire protégé : $file_path"
                audit_log "VALIDATION" "$file_path" "PROTECTED_DIR" "Accès répertoire protégé bloqué"
                return 1
            fi
        done
    fi
    
    # Protection des heures de bureau pour données utilisateur
    if [[ "$BUSINESS_HOURS_PROTECTION" == "true" && "$force" != "true" ]]; then
        local current_hour
        current_hour=$(date +%H)
        local current_day
        current_day=$(date +%u)  # 1=Lundi, 7=Dimanche
        
        if [[ $current_day -ge 1 && $current_day -le 5 && $current_hour -ge 9 && $current_hour -lt 18 ]]; then
            if [[ "$file_path" == "/Users/"* ]]; then
                echo "⚠️  Protection heures de bureau : Suppression données utilisateur restreinte"
                audit_log "VALIDATION" "$file_path" "BUSINESS_HOURS" "Suppression données utilisateur bloquée pendant heures de bureau"
                return 1
            fi
        fi
    fi
    
    # Vérifier les permissions de fichier
    if [[ "$VALIDATE_FILE_PERMISSIONS" == "true" ]]; then
        if [[ ! -w "$file_path" && ! -w "$(dirname "$file_path")" ]]; then
            echo "❌ Permissions insuffisantes pour supprimer : $file_path"
            audit_log "VALIDATION" "$file_path" "NO_PERMISSION" "Permissions insuffisantes pour suppression"
            return 1
        fi
    fi
    
    # Détection de données sensibles
    if [[ "$SENSITIVE_DATA_DETECTION" == "true" ]]; then
        if detect_sensitive_data "$file_path"; then
            echo "⚠️  Données sensibles détectées dans : $file_path"
            if [[ "$force" != "true" ]]; then
                audit_log "VALIDATION" "$file_path" "SENSITIVE_DATA" "Suppression données sensibles nécessite flag force"
                return 1
            fi
        fi
    fi
    
    audit_log "VALIDATION" "$file_path" "PASSED" "Toutes les vérifications de sécurité réussies"
    return 0
}

# Détecter les données sensibles dans les fichiers
detect_sensitive_data() {
    local file_path="$1"
    
    if [[ -f "$file_path" ]]; then
        # Vérifier les motifs de données sensibles courants
        local sensitive_patterns=(
            "\b\d{3}-\d{2}-\d{4}\b"  # Motif SSN
            "\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b"  # Motif carte de crédit
            "password"
            "secret"
            "private.*key"
            "confidential"
        )
        
        for pattern in "${sensitive_patterns[@]}"; do
            if grep -qi "$pattern" "$file_path" 2>/dev/null; then
                return 0  # Données sensibles trouvées
            fi
        done
    fi
    
    return 1  # Aucune donnée sensible trouvée
}

# Créer une sauvegarde avant suppression
create_backup() {
    local file_path="$1"
    local backup_reason="${2:-deletion}"
    
    if [[ "$AUTOMATIC_BACKUP_ENABLED" != "true" ]]; then
        return 0
    fi
    
    echo "=== Création de Sauvegarde ==="
    
    local backup_timestamp
    backup_timestamp=$(date +%Y%m%d_%H%M%S)
    local backup_name
    backup_name="$(basename "$file_path")_${backup_timestamp}_${backup_reason}"
    local backup_path="$BACKUP_DIR/$backup_name"
    
    # Créer la structure de répertoire de sauvegarde
    mkdir -p "$BACKUP_DIR"
    
    # Copier fichier/répertoire vers l'emplacement de sauvegarde
    if [[ -d "$file_path" ]]; then
        # Sauvegarde de répertoire
        if [[ "$COMPRESSED_BACKUPS" == "true" ]]; then
            tar -czf "${backup_path}.tar.gz" -C "$(dirname "$file_path")" "$(basename "$file_path")" 2>/dev/null
            backup_path="${backup_path}.tar.gz"
        else
            cp -R "$file_path" "$backup_path" 2>/dev/null
        fi
    else
        # Sauvegarde de fichier
        if [[ "$COMPRESSED_BACKUPS" == "true" && $(stat -f%z "$file_path" 2>/dev/null || echo 0) -gt 1048576 ]]; then
            gzip -c "$file_path" > "${backup_path}.gz" 2>/dev/null
            backup_path="${backup_path}.gz"
        else
            cp "$file_path" "$backup_path" 2>/dev/null
        fi
    fi
    
    if [[ $? -eq 0 ]]; then
        echo "✅ Sauvegarde créée : $backup_path"
        
        # Chiffrer la sauvegarde si activé
        if [[ "$ENCRYPTED_BACKUPS" == "true" ]]; then
            encrypt_backup "$backup_path"
        fi
        
        # Enregistrer la sauvegarde dans les métadonnées
        echo "$(date -u +%Y-%m-%dT%H:%M:%SZ)|$file_path|$backup_path|$backup_reason" >> "$BACKUP_DIR/backup_manifest.log"
        
        log_action "Sauvegarde créée pour $file_path à $backup_path"
        audit_log "BACKUP" "$file_path" "CREATED" "Chemin sauvegarde : $backup_path"
        
        return 0
    else
        echo "❌ Échec de création de sauvegarde pour : $file_path"
        log_action "ÉCHEC : Création de sauvegarde échouée pour $file_path"
        audit_log "BACKUP" "$file_path" "FAILED" "Erreur création sauvegarde"
        return 1
    fi
}

# Chiffrer le fichier de sauvegarde
encrypt_backup() {
    local backup_path="$1"
    
    # Chiffrement simple utilisant les outils intégrés (en production, utiliser chiffrement entreprise approprié)
    if command -v openssl >/dev/null 2>&1; then
        openssl enc -aes-256-cbc -salt -in "$backup_path" -out "${backup_path}.enc" -k "Roundfleet_Backup_Key_$(date +%Y)" 2>/dev/null
        if [[ $? -eq 0 ]]; then
            rm "$backup_path"
            echo "🔐 Sauvegarde chiffrée : ${backup_path}.enc"
            log_action "Sauvegarde chiffrée : ${backup_path}.enc"
        fi
    fi
}

# Suppression sécurisée de fichier
secure_delete() {
    local file_path="$1"
    local secure_passes="${2:-3}"
    
    echo "=== Processus de Suppression Sécurisée ==="
    
    if [[ ! -e "$file_path" ]]; then
        echo "❌ Fichier introuvable pour suppression sécurisée : $file_path"
        return 1
    fi
    
    local file_size
    file_size=$(get_file_size "$file_path")
    
    # Pour les fichiers, effectuer écrasement sécurisé avant suppression
    if [[ -f "$file_path" && "$SECURE_DELETION_ENABLED" == "true" ]]; then
        echo "🔐 Effectuant suppression sécurisée avec $secure_passes passes..."
        
        # Écrasement multiple passes
        for ((pass=1; pass<=secure_passes; pass++)); do
            echo "Passe $pass/$secure_passes : Écrasement avec données aléatoires..."
            dd if=/dev/urandom of="$file_path" bs=1024 count=$(du -k "$file_path" 2>/dev/null | cut -f1) 2>/dev/null || true
            sync
        done
        
        # Passe finale zéros
        dd if=/dev/zero of="$file_path" bs=1024 count=$(du -k "$file_path" 2>/dev/null | cut -f1) 2>/dev/null || true
        sync
        
        echo "🔐 Écrasement sécurisé terminé"
        audit_log "SECURE_DELETE" "$file_path" "OVERWRITTEN" "Écrasement sécurisé avec $secure_passes passes"
    fi
    
    # Effectuer suppression finale
    if [[ -d "$file_path" ]]; then
        # Suppression de répertoire
        rm -rf "$file_path" 2>/dev/null
    else
        # Suppression de fichier
        rm -f "$file_path" 2>/dev/null
    fi
    
    local deletion_result=$?
    
    if [[ $deletion_result -eq 0 ]]; then
        echo "✅ Fichier supprimé de manière sécurisée : $file_path (Taille : $file_size)"
        audit_log "SECURE_DELETE" "$file_path" "SUCCESS" "Suppression sécurisée terminée (Taille : $file_size)"
        return 0
    else
        echo "❌ Échec de suppression : $file_path"
        audit_log "SECURE_DELETE" "$file_path" "FAILED" "Suppression échouée"
        return 1
    fi
}

# Suppression de fichier entreprise avec gestion complète
enterprise_file_delete() {
    local file_path="$1"
    local force="${2:-false}"
    local secure="${3:-true}"
    local backup="${4:-true}"
    
    echo "=== Suppression de Fichier Entreprise ==="
    
    if [[ -z "$file_path" ]]; then
        echo "❌ Chemin de fichier requis"
        return 1
    fi
    
    log_action "SUPPRESSION FICHIER ENTREPRISE : Début suppression de $file_path"
    
    # Validation pré-suppression
    if ! validate_deletion_safety "$file_path" "$force"; then
        log_action "ÉCHEC : Validation sécurité suppression fichier échouée pour $file_path"
        return 1
    fi
    
    # Créer sauvegarde si requis
    if [[ "$backup" == "true" || "$REQUIRE_BACKUP_BEFORE_DELETE" == "true" ]]; then
        if ! create_backup "$file_path" "pre_deletion"; then
            if [[ "$force" != "true" ]]; then
                echo "❌ Sauvegarde échouée et mode force non activé"
                return 1
            else
                echo "⚠️  Procédure sans sauvegarde (mode force)"
            fi
        fi
    fi
    
    # Vérifier les ressources système
    check_system_resources
    
    # Confirmation utilisateur si activée
    if [[ "$DELETION_CONFIRMATION" == "true" && "$force" != "true" ]]; then
        echo "⚠️  Confirmation suppression requise pour : $file_path"
        # Dans les scripts automatisés, ceci s'intégrerait avec les flux d'approbation
        log_action "Confirmation suppression requise pour $file_path"
    fi
    
    # Effectuer la suppression
    local start_time
    start_time=$(date +%s)
    
    if [[ "$secure" == "true" ]]; then
        secure_delete "$file_path"
    else
        # Suppression standard
        if [[ -d "$file_path" ]]; then
            rm -rf "$file_path" 2>/dev/null
        else
            rm -f "$file_path" 2>/dev/null
        fi
    fi
    
    local deletion_result=$?
    local end_time
    end_time=$(date +%s)
    local duration=$((end_time - start_time))
    
    # Envoyer des notifications
    send_deletion_notification "$file_path" "$deletion_result" "$duration"
    
    # Nettoyage et vérification
    if [[ $deletion_result -eq 0 ]]; then
        echo "✅ Suppression de fichier terminée avec succès : $file_path"
        log_action "SUCCÈS : Fichier supprimé avec succès : $file_path (Durée : ${duration}s)"
        
        # Mettre à jour les statistiques d'utilisation
        update_deletion_stats "$file_path"
        
        # Nettoyer les fichiers liés
        cleanup_related_files "$file_path"
        
        return 0
    else
        echo "❌ Suppression de fichier échouée : $file_path"
        log_action "ÉCHEC : Impossible de supprimer le fichier : $file_path"
        return 1
    fi
}

# Envoyer une notification de suppression
send_deletion_notification() {
    local file_path="$1"
    local result="$2"
    local duration="$3"
    
    if [[ "$USER_NOTIFICATION_ENABLED" != "true" ]]; then
        return 0
    fi
    
    echo "=== Envoi des Notifications de Suppression ==="
    
    local notification_title="Gestion de Fichiers Roundfleet"
    local result_text="succès"
    if [[ $result -ne 0 ]]; then
        result_text="échec"
    fi
    
    local notification_message="Suppression de fichier $result_text : $(basename "$file_path") (${duration}s)"
    
    # Afficher notification aux utilisateurs connectés
    local logged_users
    logged_users=$(who | awk '{print $1}' | sort -u)
    
    for user in $logged_users; do
        if [[ -n "$user" ]]; then
            sudo -u "$user" osascript -e "display notification \"$notification_message\" with title \"$notification_title\"" 2>/dev/null || true
            echo "📱 Notification envoyée à l'utilisateur : $user"
        fi
    done
    
    log_action "Notifications de suppression envoyées pour $file_path ($result_text)"
}

# Opérations de suppression de fichiers en masse
bulk_file_deletion() {
    local file_list="$1"
    local force="${2:-false}"
    local secure="${3:-true}"
    
    echo "=== Opérations de Suppression de Fichiers en Masse ==="
    
    local success_count=0
    local failure_count=0
    local total_count=0
    
    # Gérer différents types d'entrée
    if [[ -f "$file_list" ]]; then
        # Liste de fichiers depuis fichier
        while IFS= read -r file_path; do
            # Ignorer lignes vides et commentaires
            if [[ -z "$file_path" || "$file_path" == \#* ]]; then
                continue
            fi
            
            ((total_count++))
            echo "Traitement ($total_count) : $file_path"
            
            if enterprise_file_delete "$file_path" "$force" "$secure"; then
                ((success_count++))
            else
                ((failure_count++))
            fi
            
            echo "---"
            sleep 1  # Brève pause entre opérations
        done < "$file_list"
    else
        # Suppression basée sur motif
        echo "Suppression basée sur motif : $file_list"
        
        # Étendre le motif et traiter chaque fichier
        for file_path in $file_list; do
            if [[ -e "$file_path" ]]; then
                ((total_count++))
                echo "Traitement ($total_count) : $file_path"
                
                if enterprise_file_delete "$file_path" "$force" "$secure"; then
                    ((success_count++))
                else
                    ((failure_count++))
                fi
            fi
        done
    fi
    
    echo "=== Résumé de Suppression en Masse ==="
    echo "Total fichiers traités : $total_count"
    echo "Suppressions réussies : $success_count"
    echo "Suppressions échouées : $failure_count"
    
    log_action "Suppression en masse terminée : $success_count/$total_count réussies"
    audit_log "BULK_DELETE" "MULTIPLE" "COMPLETED" "Succès : $success_count Échecs : $failure_count Total : $total_count"
}

# Nettoyer les anciennes sauvegardes selon la politique de rétention
cleanup_old_backups() {
    echo "=== Nettoyage de Rétention de Sauvegarde ==="
    
    if [[ ! -d "$BACKUP_DIR" ]]; then
        echo "Aucun répertoire de sauvegarde trouvé"
        return 0
    fi
    
    local retention_days="${BACKUP_RETENTION_DAYS:-30}"
    local cleanup_count=0
    
    # Trouver et supprimer les anciennes sauvegardes
    while IFS= read -r old_backup; do
        if [[ -n "$old_backup" ]]; then
            rm -f "$old_backup"
            ((cleanup_count++))
            echo "Ancienne sauvegarde supprimée : $old_backup"
        fi
    done < <(find "$BACKUP_DIR" -type f -mtime +$retention_days 2>/dev/null)
    
    echo "Nettoyage de $cleanup_count anciennes sauvegardes (plus de $retention_days jours)"
    log_action "Nettoyage sauvegarde : $cleanup_count anciennes sauvegardes supprimées"
}

# Vérifier les ressources système avant suppression
check_system_resources() {
    echo "=== Vérification des Ressources Système ==="
    
    # Vérifier l'espace disque disponible
    local available_space
    available_space=$(df -h / | tail -1 | awk '{print $4}' | sed 's/G//')
    
    echo "Espace Disponible : ${available_space}GB"
    
    if [[ "$FREE_SPACE_MONITORING" == "true" ]] && (( $(echo "$available_space < 5" | bc -l) )); then
        echo "⚠️  Avertissement espace disque faible : ${available_space}GB disponible"
        log_action "Espace disque faible pendant opération suppression : ${available_space}GB"
    fi
    
    # Vérifier la charge système
    local load_average
    load_average=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',')
    
    echo "Charge Système : $load_average"
    
    if [[ "$SYSTEM_LOAD_MONITORING" == "true" ]] && (( $(echo "$load_average > 5.0" | bc -l) )); then
        echo "⚠️  Charge système élevée : $load_average"
        log_action "Charge système élevée pendant opération suppression : $load_average"
    fi
}

# Générer un rapport de suppression de fichiers
generate_deletion_report() {
    local report_file="/Library/Roundfleet/Reports/file_deletion_report_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Génération du Rapport de Suppression de Fichiers ==="
    
    mkdir -p "$(dirname "$report_file")"
    
    # Compter les opérations récentes du journal d'audit
    local recent_deletions=0
    local successful_deletions=0
    local failed_deletions=0
    local total_backup_size=0
    
    if [[ -f "$AUDIT_LOG" ]]; then
        recent_deletions=$(grep -c "ACTION:SECURE_DELETE\|ACTION:BULK_DELETE" "$AUDIT_LOG" 2>/dev/null || echo 0)
        successful_deletions=$(grep -c "RESULT:SUCCESS" "$AUDIT_LOG" 2>/dev/null || echo 0)
        failed_deletions=$(grep -c "RESULT:FAILED" "$AUDIT_LOG" 2>/dev/null || echo 0)
    fi
    
    if [[ -d "$BACKUP_DIR" ]]; then
        total_backup_size=$(du -sh "$BACKUP_DIR" 2>/dev/null | awk '{print $1}' || echo "0")
    fi
    
    cat > "$report_file" << EOF
{
  "report_type": "file_deletion_management",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "device_info": {
    "hostname": "$(hostname)",
    "os_version": "$(sw_vers -productVersion)",
    "available_space": "$(df -h / | tail -1 | awk '{print $4}')"
  },
  "deletion_statistics": {
    "recent_deletions": $recent_deletions,
    "successful_deletions": $successful_deletions,
    "failed_deletions": $failed_deletions,
    "success_rate": "$(echo "scale=2; $successful_deletions * 100 / ($successful_deletions + $failed_deletions + 1)" | bc)%"
  },
  "backup_statistics": {
    "total_backup_size": "$total_backup_size",
    "backup_retention_days": $BACKUP_RETENTION_DAYS,
    "encrypted_backups": $ENCRYPTED_BACKUPS
  },
  "policy_configuration": {
    "secure_deletion": $SECURE_DELETION_ENABLED,
    "automatic_backup": $AUTOMATIC_BACKUP_ENABLED,
    "business_hours_protection": $BUSINESS_HOURS_PROTECTION,
    "sensitive_data_detection": $SENSITIVE_DATA_DETECTION
  },
  "security_status": {
    "system_file_protection": $PREVENT_SYSTEM_FILE_DELETION,
    "protected_directories": $PROTECTED_DIRECTORIES_ENFORCEMENT,
    "audit_enabled": $AUDIT_ALL_DELETIONS
  }
}
EOF
    
    echo "Rapport de suppression de fichiers sauvegardé dans : $report_file"
    log_action "Rapport de suppression généré : $report_file"
}

# Fonction principale avec gestion d'arguments
main() {
    log_action "=== Outil de Gestion de Suppression de Fichiers Roundfleet Démarré ==="
    
    case "${1:-help}" in
        "delete"|"supprimer")
            enterprise_file_delete "$2" "$3" "$4" "$5"
            ;;
        "bulk"|"masse")
            bulk_file_deletion "$2" "$3" "$4"
            ;;
        "cleanup-backups"|"nettoyer-sauvegardes")
            cleanup_old_backups
            ;;
        "report"|"rapport")
            generate_deletion_report
            ;;
        *)
            echo "Outil de Gestion de Suppression de Fichiers et Dossiers Entreprise Roundfleet"
            echo "Usage : $0 [commande] [options]"
            echo ""
            echo "Commandes :"
            echo "  delete [chemin_fichier] [force] [secure] [backup]  - Supprimer fichier avec contrôles entreprise"
            echo "  bulk [fichier_liste/motif] [force] [secure]       - Suppression en masse depuis liste ou motif"
            echo "  cleanup-backups                                   - Supprimer anciennes sauvegardes selon politique rétention"
            echo "  report                                            - Générer rapport gestion suppression"
            echo ""
            echo "Options :"
            echo "  force    - true/false (contourner vérifications sécurité)"
            echo "  secure   - true/false (activer suppression sécurisée)"
            echo "  backup   - true/false (créer sauvegarde avant suppression)"
            echo ""
            echo "Exemples :"
            echo "  $0 delete \"/Users/user/temp.txt\"            - Suppression sécurisée avec sauvegarde"
            echo "  $0 delete \"/tmp/folder\" true true false     - Suppression sécurisée forcée sans sauvegarde"
            echo "  $0 bulk \"*.log\" false true                 - Suppression sécurisée en masse fichiers log"
            echo "  $0 bulk file_list.txt true                   - Suppression forcée en masse depuis liste"
            echo "  $0 cleanup-backups                           - Nettoyer anciennes sauvegardes"
            ;;
    esac
    
    log_action "=== Opération de gestion de suppression de fichiers terminée ==="
}

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

## Notes de Configuration Importantes

### Commandes de Suppression de Fichiers macOS

- **`rm`** - Suppression de fichier de base
- **`rm -r`** - Suppression de répertoire récursive
- **`rm -f`** - Suppression forcée sans invites
- **`rm -rf`** - Suppression récursive forcée
- **Correspondance de motifs** - `*.txt`, `{1,2}.png` pour opérations en masse

### Points d'Intégration Entreprise

- **Prévention de Perte de Données (DLP)** - Intégration avec systèmes DLP
- **Systèmes de Sauvegarde et Récupération** - Intégration sauvegarde automatisée
- **Plateformes de Conformité** - Rapports de conformité GDPR, HIPAA
- **Gestion d'Information et d'Événements de Sécurité (SIEM)** - Journalisation audit suppression

### Bonnes Pratiques pour Suppression de Fichiers Entreprise

1. **Sécurité et Protection des Données**
   - Toujours créer des sauvegardes avant suppression
   - Utiliser suppression sécurisée pour données sensibles
   - Valider les permissions de fichier avant suppression
   - Implémenter protection heures de bureau

2. **Conformité et Gouvernance**
   - Maintenir pistes d'audit complètes
   - Implémenter conscience classification données
   - Supporter exigences conformité réglementaires
   - Documenter toutes opérations suppression

3. **Sécurité et Récupération**
   - Empêcher suppression fichiers système
   - Implémenter capacités de retour arrière
   - Surveiller ressources système pendant opérations
   - Fournir systèmes notification clairs

N'oubliez pas de tester minutieusement les procédures de suppression de fichiers dans un environnement contrôlé avant l'implémentation sur l'ensemble de votre Roundfleet pour assurer la sécurité des données et la conformité avec les politiques organisationnelles. 

Gestion Entreprise de Création de Fichiers et Dossiers sur macOS

Gérez efficacement les opérations de création de fichiers et dossiers dans votre déploiement Roundfleet avec une gestion de modèles de niveau entreprise, un contrôle des permissions et des capacités d'audit complètes. Ce tutoriel transforme les commandes de base touch et mkdir en solutions robustes de provisionnement de système de fichiers.

Comprendre les Opérations de Création de Fichiers en Entreprise

La création de fichiers en entreprise nécessite plus que de simples opérations de système de fichiers, exigeant :

  • Gestion de modèles pour des structures de fichiers et dossiers standardisées
  • Contrôle des permissions pour appliquer les politiques de sécurité
  • Validation du contenu pour les fichiers et répertoires créés
  • Journalisation d'audit pour le suivi de conformité
  • Provisionnement automatisé pour l'intégration des utilisateurs
  • Application de politiques pour les conventions de nommage et la structure

Opérations de Création de Base

Création de Fichier Basique

#!/bin/bash

# Création simple de fichier avec validation
create_file() {
    local file_path="$1"
    local content="${2:-}"
    
    # Valider que le répertoire parent existe
    local parent_dir=$(dirname "$file_path")
    if [[ ! -d "$parent_dir" ]]; then
        echo "Erreur : Le répertoire parent '$parent_dir' n'existe pas"
        return 1
    fi
    
    # Créer le fichier
    if touch "$file_path"; then
        # Ajouter le contenu si fourni
        if [[ -n "$content" ]]; then
            echo "$content" > "$file_path"
        fi
        echo "Fichier créé avec succès '$file_path'"
        return 0
    else
        echo "Échec de la création du fichier '$file_path'"
        return 1
    fi
}

# Exemple d'utilisation
# create_file "/Users/admin/document.txt" "Contenu initial"

Création de Répertoire Basique

#!/bin/bash

# Création de répertoire avec validation
create_directory() {
    local dir_path="$1"
    local permissions="${2:-755}"
    
    # Créer le répertoire avec parents si nécessaire
    if mkdir -p "$dir_path"; then
        # Définir les permissions
        chmod "$permissions" "$dir_path"
        echo "Répertoire créé avec succès '$dir_path'"
        return 0
    else
        echo "Échec de la création du répertoire '$dir_path'"
        return 1
    fi
}

# Exemple d'utilisation
# create_directory "/Users/admin/projet" "755"

Système de Gestion de Création Entreprise

#!/bin/bash

# Système de Gestion de Création de Fichiers Entreprise Roundfleet
# Création complète de fichiers et dossiers avec fonctionnalités entreprise

# Configuration
SCRIPT_NAME="Gestionnaire de Création Roundfleet"
VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_creation_operations.log"
TEMPLATE_DIR="/etc/roundfleet/templates"
POLICY_DIR="/etc/roundfleet/policies"
TEMP_DIR="/tmp/roundfleet_creation"
DEFAULT_FILE_PERMISSIONS="644"
DEFAULT_DIR_PERMISSIONS="755"
RESTRICTED_PATHS=("/System" "/usr/bin" "/usr/sbin" "/private/var" "/Library/LaunchDaemons")
ALLOWED_EXTENSIONS=(".txt" ".md" ".pdf" ".docx" ".xlsx" ".pptx" ".csv" ".json" ".xml" ".log")
MAX_FILENAME_LENGTH=255
MAX_PATH_DEPTH=20
BUSINESS_HOURS_START=9
BUSINESS_HOURS_END=17

# Créer les répertoires nécessaires
mkdir -p "$TEMP_DIR"
mkdir -p "$TEMPLATE_DIR"
mkdir -p "$POLICY_DIR"
mkdir -p "$(dirname "$LOG_FILE")"

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

# Vérifier si l'heure actuelle est dans les heures de bureau
is_business_hours() {
    local current_hour=$(date +%H)
    if [[ $current_hour -ge $BUSINESS_HOURS_START && $current_hour -lt $BUSINESS_HOURS_END ]]; then
        return 0
    else
        return 1
    fi
}

# Valider l'extension de fichier
is_allowed_extension() {
    local file="$1"
    local extension="${file##*.}"
    extension=".$extension"
    
    for allowed in "${ALLOWED_EXTENSIONS[@]}"; do
        if [[ "$extension" == "$allowed" ]]; then
            return 0
        fi
    done
    return 1
}

# Vérifier si le chemin est restreint
is_restricted_path() {
    local path="$1"
    for restricted in "${RESTRICTED_PATHS[@]}"; do
        if [[ "$path" == "$restricted"* ]]; then
            return 0
        fi
    done
    return 1
}

# Valider les conventions de nommage
validate_naming_convention() {
    local name="$1"
    local type="$2"  # "file" ou "directory"
    
    # Vérifier la longueur
    if [[ ${#name} -gt $MAX_FILENAME_LENGTH ]]; then
        log_operation "ERROR" "Nom trop long (${#name} > $MAX_FILENAME_LENGTH) : $name"
        return 1
    fi
    
    # Vérifier les caractères invalides
    if [[ "$name" =~ [^a-zA-Z0-9._-] ]]; then
        log_operation "WARNING" "Le nom contient des caractères spéciaux : $name"
    fi
    
    # Vérifier les noms réservés
    local reserved_names=("CON" "PRN" "AUX" "NUL" "COM1" "COM2" "LPT1" "LPT2")
    local base_name=$(basename "$name" | tr '[:lower:]' '[:upper:]')
    
    for reserved in "${reserved_names[@]}"; do
        if [[ "$base_name" == "$reserved" ]]; then
            log_operation "ERROR" "Nom réservé non autorisé : $name"
            return 1
        fi
    done
    
    return 0
}

# Vérifier la profondeur du chemin
validate_path_depth() {
    local path="$1"
    local depth=$(echo "$path" | tr '/' '\n' | wc -l)
    
    if [[ $depth -gt $MAX_PATH_DEPTH ]]; then
        log_operation "ERROR" "Profondeur de chemin trop importante ($depth > $MAX_PATH_DEPTH) : $path"
        return 1
    fi
    
    return 0
}

# Charger le modèle de fichier
load_file_template() {
    local template_name="$1"
    local template_file="$TEMPLATE_DIR/$template_name.template"
    
    if [[ -f "$template_file" ]]; then
        cat "$template_file"
        return 0
    else
        log_operation "WARNING" "Modèle non trouvé : $template_name"
        return 1
    fi
}

# Appliquer la substitution de variables au modèle
apply_template_variables() {
    local content="$1"
    local variables="$2"  # Chaîne JSON avec variables
    
    # Substitution de variables de base
    content=$(echo "$content" | sed "s/{{DATE}}/$(date '+%Y-%m-%d')/g")
    content=$(echo "$content" | sed "s/{{TIME}}/$(date '+%H:%M:%S')/g")
    content=$(echo "$content" | sed "s/{{USER}}/$(whoami)/g")
    content=$(echo "$content" | sed "s/{{HOSTNAME}}/$(hostname)/g")
    
    # Variables personnalisées depuis JSON (simplifié)
    if [[ -n "$variables" ]]; then
        # Ceci serait amélioré avec un parsing JSON approprié en production
        log_operation "INFO" "Application des variables de modèle personnalisées"
    fi
    
    echo "$content"
}

# Créer une structure de répertoire depuis un modèle
create_structure_from_template() {
    local template_name="$1"
    local base_path="$2"
    local variables="${3:-}"
    
    local structure_file="$TEMPLATE_DIR/structures/$template_name.json"
    
    if [[ ! -f "$structure_file" ]]; then
        log_operation "ERROR" "Modèle de structure non trouvé : $template_name"
        return 1
    fi
    
    log_operation "INFO" "Création de structure depuis le modèle : $template_name à $base_path"
    
    # Ceci analyserait la structure JSON et créerait répertoires/fichiers
    # Implémentation simplifiée pour démonstration
    mkdir -p "$base_path"
    
    return 0
}

# Création de fichier améliorée avec fonctionnalités entreprise
enterprise_create_file() {
    local file_path="$1"
    local template_name="${2:-}"
    local permissions="${3:-$DEFAULT_FILE_PERMISSIONS}"
    local variables="${4:-}"
    
    local operation_id=$(date +%s)
    log_operation "INFO" "Début de l'opération de création de fichier [$operation_id] : $file_path"
    
    # Validations préliminaires
    local filename=$(basename "$file_path")
    local parent_dir=$(dirname "$file_path")
    
    # Valider les conventions de nommage
    if ! validate_naming_convention "$filename" "file"; then
        log_operation "ERROR" "Échec de validation des conventions de nommage : $filename"
        return 1
    fi
    
    # Valider la profondeur du chemin
    if ! validate_path_depth "$file_path"; then
        return 1
    fi
    
    # Vérifier si le chemin est restreint
    if is_restricted_path "$file_path"; then
        log_operation "SECURITY" "Création bloquée dans un chemin restreint : $file_path"
        return 1
    fi
    
    # Valider l'extension de fichier
    if ! is_allowed_extension "$file_path"; then
        log_operation "SECURITY" "Fichier bloqué avec extension non autorisée : $file_path"
        return 1
    fi
    
    # Vérifier si le fichier existe déjà
    if [[ -f "$file_path" ]]; then
        log_operation "WARNING" "Le fichier existe déjà : $file_path"
        return 1
    fi
    
    # Créer le répertoire parent s'il n'existe pas
    if [[ ! -d "$parent_dir" ]]; then
        if ! mkdir -p "$parent_dir"; then
            log_operation "ERROR" "Échec de création du répertoire parent : $parent_dir"
            return 1
        fi
        log_operation "INFO" "Répertoire parent créé : $parent_dir"
    fi
    
    # Charger le contenu du modèle si spécifié
    local content=""
    if [[ -n "$template_name" ]]; then
        content=$(load_file_template "$template_name")
        if [[ $? -eq 0 ]]; then
            content=$(apply_template_variables "$content" "$variables")
            log_operation "INFO" "Modèle appliqué : $template_name"
        else
            log_operation "WARNING" "Échec du chargement du modèle, création d'un fichier vide"
        fi
    fi
    
    # Créer le fichier
    if touch "$file_path"; then
        # Ajouter le contenu si disponible
        if [[ -n "$content" ]]; then
            echo "$content" > "$file_path"
        fi
        
        # Définir les permissions
        chmod "$permissions" "$file_path"
        
        # Définir la propriété (si exécuté en tant que root)
        if [[ $EUID -eq 0 ]]; then
            local target_user=$(stat -f "%Su" "$parent_dir")
            local target_group=$(stat -f "%Sg" "$parent_dir")
            chown "$target_user:$target_group" "$file_path"
        fi
        
        log_operation "SUCCESS" "Fichier créé avec succès [$operation_id] : $file_path"
        log_operation "AUDIT" "Fichier créé : $file_path (permissions : $permissions)"
        
        return 0
    else
        log_operation "ERROR" "Échec de création du fichier [$operation_id] : $file_path"
        return 1
    fi
}

# Création de répertoire améliorée avec fonctionnalités entreprise
enterprise_create_directory() {
    local dir_path="$1"
    local template_name="${2:-}"
    local permissions="${3:-$DEFAULT_DIR_PERMISSIONS}"
    local create_parents="${4:-true}"
    
    local operation_id=$(date +%s)
    log_operation "INFO" "Début de l'opération de création de répertoire [$operation_id] : $dir_path"
    
    # Validations préliminaires
    local dirname=$(basename "$dir_path")
    
    # Valider les conventions de nommage
    if ! validate_naming_convention "$dirname" "directory"; then
        log_operation "ERROR" "Échec de validation des conventions de nommage : $dirname"
        return 1
    fi
    
    # Valider la profondeur du chemin
    if ! validate_path_depth "$dir_path"; then
        return 1
    fi
    
    # Vérifier si le chemin est restreint
    if is_restricted_path "$dir_path"; then
        log_operation "SECURITY" "Création bloquée dans un chemin restreint : $dir_path"
        return 1
    fi
    
    # Vérifier si le répertoire existe déjà
    if [[ -d "$dir_path" ]]; then
        log_operation "WARNING" "Le répertoire existe déjà : $dir_path"
        return 1
    fi
    
    # Créer le répertoire
    local mkdir_options=""
    if [[ "$create_parents" == "true" ]]; then
        mkdir_options="-p"
    fi
    
    if mkdir $mkdir_options "$dir_path"; then
        # Définir les permissions
        chmod "$permissions" "$dir_path"
        
        # Définir la propriété (si exécuté en tant que root)
        if [[ $EUID -eq 0 ]]; then
            local parent_dir=$(dirname "$dir_path")
            if [[ -d "$parent_dir" ]]; then
                local target_user=$(stat -f "%Su" "$parent_dir")
                local target_group=$(stat -f "%Sg" "$parent_dir")
                chown "$target_user:$target_group" "$dir_path"
            fi
        fi
        
        # Appliquer la structure du modèle si spécifiée
        if [[ -n "$template_name" ]]; then
            create_structure_from_template "$template_name" "$dir_path"
        fi
        
        log_operation "SUCCESS" "Répertoire créé avec succès [$operation_id] : $dir_path"
        log_operation "AUDIT" "Répertoire créé : $dir_path (permissions : $permissions)"
        
        return 0
    else
        log_operation "ERROR" "Échec de création du répertoire [$operation_id] : $dir_path"
        return 1
    fi
}

# Opérations de création en lot
bulk_create_operation() {
    local operation_type="$1"  # "file" ou "directory"
    local items_file="$2"      # Fichier contenant les spécifications de création
    local template_name="${3:-}"
    
    if [[ ! -f "$items_file" ]]; then
        log_operation "ERROR" "Fichier d'éléments non trouvé : $items_file"
        return 1
    fi
    
    local total_items=$(grep -v '^#\|^$' "$items_file" | wc -l)
    local current_item=0
    local success_count=0
    local failure_count=0
    
    log_operation "INFO" "Début de l'opération de création en lot - Total d'éléments : $total_items"
    
    while IFS='|' read -r path permissions variables; do
        # Ignorer les lignes vides et commentaires
        [[ -z "$path" || "$path" =~ ^#.* ]] && continue
        
        ((current_item++))
        
        # Supprimer les espaces
        path=$(echo "$path" | xargs)
        permissions=$(echo "$permissions" | xargs)
        variables=$(echo "$variables" | xargs)
        
        echo "Traitement [$current_item/$total_items] : $(basename "$path")"
        
        case "$operation_type" in
            "file")
                if enterprise_create_file "$path" "$template_name" "$permissions" "$variables"; then
                    ((success_count++))
                else
                    ((failure_count++))
                fi
                ;;
            "directory")
                if enterprise_create_directory "$path" "$template_name" "$permissions"; then
                    ((success_count++))
                else
                    ((failure_count++))
                fi
                ;;
        esac
        
        # Mise à jour du progrès
        local progress=$((current_item * 100 / total_items))
        echo "Progrès : $progress% ($success_count réussis, $failure_count échoués)"
        
    done < "$items_file"
    
    log_operation "SUCCESS" "Création en lot terminée - Succès : $success_count, Échecs : $failure_count"
    return $failure_count
}

# Automatisation d'intégration utilisateur
create_user_workspace() {
    local username="$1"
    local user_type="${2:-standard}"  # standard, admin, developer
    local base_path="/Users/$username"
    
    log_operation "INFO" "Création de l'espace de travail pour l'utilisateur : $username (type : $user_type)"
    
    # Créer les répertoires utilisateur
    local directories=(
        "$base_path/Documents"
        "$base_path/Desktop"
        "$base_path/Downloads"
        "$base_path/Pictures"
        "$base_path/Movies"
        "$base_path/Music"
    )
    
    # Ajouter des répertoires spécifiques au type
    case "$user_type" in
        "developer")
            directories+=("$base_path/Projects" "$base_path/Scripts" "$base_path/Tools")
            ;;
        "admin")
            directories+=("$base_path/Admin" "$base_path/Logs" "$base_path/Configs")
            ;;
    esac
    
    # Créer les répertoires
    for dir in "${directories[@]}"; do
        if enterprise_create_directory "$dir" "" "755"; then
            log_operation "INFO" "Répertoire utilisateur créé : $dir"
        fi
    done
    
    # Créer les fichiers par défaut
    local files=(
        "$base_path/Desktop/Bienvenue.txt|welcome|644"
        "$base_path/Documents/LISEZMOI.txt|readme|644"
    )
    
    for file_spec in "${files[@]}"; do
        IFS='|' read -r file_path template perms <<< "$file_spec"
        if enterprise_create_file "$file_path" "$template" "$perms"; then
            log_operation "INFO" "Fichier utilisateur créé : $file_path"
        fi
    done
    
    log_operation "SUCCESS" "Espace de travail utilisateur créé pour : $username"
}

# Générer un rapport de création
generate_creation_report() {
    local report_file="/tmp/roundfleet_creation_report_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport des Opérations de Création Roundfleet"
        echo "Généré : $(date)"
        echo "Nom d'hôte : $(hostname)"
        echo "Utilisateur : $(whoami)"
        echo "================================="
        echo ""
        
        echo "Opérations de Création Récentes (Dernières 24 heures) :"
        if [[ -f "$LOG_FILE" ]]; then
            local yesterday=$(date -v-1d '+%Y-%m-%d')
            grep "$yesterday\|$(date '+%Y-%m-%d')" "$LOG_FILE" | grep -E "(AUDIT|SUCCESS)" | tail -50
        else
            echo "Aucun fichier de log trouvé"
        fi
        
        echo ""
        echo "Statistiques de Création :"
        if [[ -f "$LOG_FILE" ]]; then
            echo "Total d'Opérations : $(grep -c "opération de création" "$LOG_FILE" 2>/dev/null || echo "0")"
            echo "Fichiers Créés : $(grep -c "Fichier créé :" "$LOG_FILE" 2>/dev/null || echo "0")"
            echo "Répertoires Créés : $(grep -c "Répertoire créé :" "$LOG_FILE" 2>/dev/null || echo "0")"
            echo "Opérations Échouées : $(grep -c "ERROR.*Échec" "$LOG_FILE" 2>/dev/null || echo "0")"
        fi
        
        echo ""
        echo "Utilisation des Modèles :"
        if [[ -d "$TEMPLATE_DIR" ]]; then
            echo "Modèles Disponibles :"
            find "$TEMPLATE_DIR" -name "*.template" -exec basename {} .template \; | sort
        fi
        
        echo ""
        echo "Informations Système :"
        echo "Espace Disponible :"
        df -h | grep -E "^/dev/"
        
    } > "$report_file"
    
    echo "Rapport des opérations de création sauvegardé à : $report_file"
    log_operation "INFO" "Rapport de création généré : $report_file"
}

# Gestion des modèles
manage_templates() {
    local action="$1"
    local template_name="$2"
    local template_content="$3"
    
    case "$action" in
        "create")
            if [[ -z "$template_name" || -z "$template_content" ]]; then
                echo "Usage : manage_templates create <nom> <contenu>"
                return 1
            fi
            
            local template_file="$TEMPLATE_DIR/$template_name.template"
            echo "$template_content" > "$template_file"
            log_operation "INFO" "Modèle créé : $template_name"
            ;;
        "list")
            echo "Modèles Disponibles :"
            find "$TEMPLATE_DIR" -name "*.template" -exec basename {} .template \;
            ;;
        "show")
            if [[ -z "$template_name" ]]; then
                echo "Usage : manage_templates show <nom>"
                return 1
            fi
            
            local template_file="$TEMPLATE_DIR/$template_name.template"
            if [[ -f "$template_file" ]]; then
                cat "$template_file"
            else
                echo "Modèle non trouvé : $template_name"
                return 1
            fi
            ;;
        "delete")
            if [[ -z "$template_name" ]]; then
                echo "Usage : manage_templates delete <nom>"
                return 1
            fi
            
            local template_file="$TEMPLATE_DIR/$template_name.template"
            if [[ -f "$template_file" ]]; then
                rm "$template_file"
                log_operation "INFO" "Modèle supprimé : $template_name"
            else
                echo "Modèle non trouvé : $template_name"
                return 1
            fi
            ;;
    esac
}

# Fonction principale de gestion de création
main() {
    local action="${1:-help}"
    
    case "$action" in
        "create-file")
            local file_path="$2"
            local template_name="$3"
            local permissions="${4:-$DEFAULT_FILE_PERMISSIONS}"
            local variables="$5"
            
            if [[ -z "$file_path" ]]; then
                echo "Usage : $0 create-file <chemin_fichier> [nom_modèle] [permissions] [variables]"
                exit 1
            fi
            
            enterprise_create_file "$file_path" "$template_name" "$permissions" "$variables"
            ;;
        "create-directory")
            local dir_path="$2"
            local template_name="$3"
            local permissions="${4:-$DEFAULT_DIR_PERMISSIONS}"
            local create_parents="${5:-true}"
            
            if [[ -z "$dir_path" ]]; then
                echo "Usage : $0 create-directory <chemin_répertoire> [nom_modèle] [permissions] [créer_parents]"
                exit 1
            fi
            
            enterprise_create_directory "$dir_path" "$template_name" "$permissions" "$create_parents"
            ;;
        "bulk-files")
            local items_file="$2"
            local template_name="$3"
            
            if [[ -z "$items_file" ]]; then
                echo "Usage : $0 bulk-files <fichier_éléments> [nom_modèle]"
                exit 1
            fi
            
            bulk_create_operation "file" "$items_file" "$template_name"
            ;;
        "bulk-directories")
            local items_file="$2"
            local template_name="$3"
            
            if [[ -z "$items_file" ]]; then
                echo "Usage : $0 bulk-directories <fichier_éléments> [nom_modèle]"
                exit 1
            fi
            
            bulk_create_operation "directory" "$items_file" "$template_name"
            ;;
        "user-workspace")
            local username="$2"
            local user_type="${3:-standard}"
            
            if [[ -z "$username" ]]; then
                echo "Usage : $0 user-workspace <nom_utilisateur> [type_utilisateur]"
                exit 1
            fi
            
            create_user_workspace "$username" "$user_type"
            ;;
        "template")
            local template_action="$2"
            local template_name="$3"
            local template_content="$4"
            
            manage_templates "$template_action" "$template_name" "$template_content"
            ;;
        "report")
            generate_creation_report
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Gestion Entreprise de Création de Fichiers et Dossiers"
            echo ""
            echo "Usage : $0 <action> [options]"
            echo ""
            echo "Actions :"
            echo "  create-file <chemin> [modèle] [permissions] [variables]     - Créer un fichier unique"
            echo "  create-directory <chemin> [modèle] [permissions] [parents]  - Créer un répertoire"
            echo "  bulk-files <fichier_éléments> [modèle]                      - Créer plusieurs fichiers"
            echo "  bulk-directories <fichier_éléments> [modèle]               - Créer plusieurs répertoires"
            echo "  user-workspace <nom_utilisateur> [type_utilisateur]        - Créer un espace de travail utilisateur"
            echo "  template <action> [nom] [contenu]                           - Gérer les modèles"
            echo "  report                                                       - Générer un rapport d'opérations"
            echo "  help                                                         - Afficher ce message d'aide"
            echo ""
            echo "Actions de Modèles :"
            echo "  create <nom> <contenu>  - Créer un nouveau modèle"
            echo "  list                    - Lister les modèles disponibles"
            echo "  show <nom>              - Afficher le contenu du modèle"
            echo "  delete <nom>            - Supprimer un modèle"
            echo ""
            echo "Types d'Utilisateurs :"
            echo "  standard    - Espace de travail utilisateur de base"
            echo "  developer   - Espace de travail développeur avec répertoires de projet"
            echo "  admin       - Espace de travail administratif avec répertoires système"
            echo ""
            echo "Fonctionnalités :"
            echo "  • Création de fichiers et répertoires basée sur des modèles"
            echo "  • Gestion des permissions et de la propriété"
            echo "  • Validation des conventions de nommage"
            echo "  • Validation de profondeur de chemin et de sécurité"
            echo "  • Opérations en lot avec surveillance du progrès"
            echo "  • Automatisation de l'espace de travail utilisateur"
            echo "  • Journalisation d'audit complète"
            ;;
    esac
}

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

Commandes de Référence Rapide

Opérations de Fichier Unique

# Créer un fichier vide
./creation_manager.sh create-file "/Users/admin/document.txt"

# Créer un fichier depuis un modèle
./creation_manager.sh create-file "/Users/admin/rapport.txt" "modele_rapport"

# Créer un fichier avec permissions spécifiques
./creation_manager.sh create-file "/Users/admin/script.sh" "" "755"

# Créer un fichier avec variables de modèle
./creation_manager.sh create-file "/Users/admin/config.json" "modele_config" "644" '{"projet":"MonApp"}'

Opérations de Répertoire

# Créer un répertoire
./creation_manager.sh create-directory "/Users/admin/projet"

# Créer un répertoire avec permissions spécifiques
./creation_manager.sh create-directory "/Users/admin/securise" "" "700"

# Créer une structure de répertoire depuis un modèle
./creation_manager.sh create-directory "/Users/admin/webapp" "structure_webapp"

Opérations en Lot

# Créer une spécification de fichiers en lot
cat > /tmp/fichiers_a_creer.txt << EOF
/Users/admin/doc1.txt|644|
/Users/admin/doc2.txt|644|
/Users/admin/config.json|600|{"env":"prod"}
EOF

# Exécuter la création de fichiers en lot
./creation_manager.sh bulk-files "/tmp/fichiers_a_creer.txt" "modele_defaut"

# Créer une spécification de répertoires en lot
cat > /tmp/repertoires_a_creer.txt << EOF
/Users/admin/projets|755|
/Users/admin/scripts|755|
/Users/admin/logs|750|
EOF

# Exécuter la création de répertoires en lot
./creation_manager.sh bulk-directories "/tmp/repertoires_a_creer.txt"

Gestion des Modèles

# Créer un nouveau modèle
./creation_manager.sh template create "readme" "# {{NOM_PROJET}}

Créé par : {{USER}}
Date : {{DATE}}
Heure : {{TIME}}

## Description
Ceci est un fichier README pour le projet.
"

# Lister les modèles disponibles
./creation_manager.sh template list

# Afficher le contenu d'un modèle
./creation_manager.sh template show "readme"

# Supprimer un modèle
./creation_manager.sh template delete "ancien_modele"

Création d'Espace de Travail Utilisateur

# Créer un espace de travail utilisateur standard
./creation_manager.sh user-workspace "jean.dupont" "standard"

# Créer un espace de travail développeur
./creation_manager.sh user-workspace "marie.martin" "developer"

# Créer un espace de travail admin
./creation_manager.sh user-workspace "admin.utilisateur" "admin"

Exemples d'Intégration

Intégration JAMF Pro

#!/bin/bash

# Script JAMF Pro pour création de fichiers entreprise
# Paramètres : $4 = type_operation, $5 = chemin, $6 = nom_modele, $7 = permissions

TYPE_OPERATION="$4"
CHEMIN="$5"
NOM_MODELE="$6"
PERMISSIONS="$7"

# Télécharger le gestionnaire de création s'il n'est pas présent
if [[ ! -f "/usr/local/bin/roundfleet_creation_manager.sh" ]]; then
    curl -o "/usr/local/bin/roundfleet_creation_manager.sh" "https://scripts.roundfleet.com/creation_manager.sh"
    chmod +x "/usr/local/bin/roundfleet_creation_manager.sh"
fi

# Exécuter l'opération de création
case "$TYPE_OPERATION" in
    "file")
        /usr/local/bin/roundfleet_creation_manager.sh create-file "$CHEMIN" "$NOM_MODELE" "$PERMISSIONS"
        ;;
    "directory")
        /usr/local/bin/roundfleet_creation_manager.sh create-directory "$CHEMIN" "$NOM_MODELE" "$PERMISSIONS"
        ;;
    "workspace")
        local username=$(basename "$CHEMIN")
        /usr/local/bin/roundfleet_creation_manager.sh user-workspace "$username" "$NOM_MODELE"
        ;;
    *)
        echo "Type d'opération invalide : $TYPE_OPERATION"
        exit 1
        ;;
esac

# Générer un rapport
/usr/local/bin/roundfleet_creation_manager.sh report

exit $?

Profil de Configuration pour Politiques de Création

<?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>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.roundfleet.creation.policy</string>
            <key>PayloadIdentifier</key>
            <string>com.roundfleet.creation.policy.main</string>
            <key>PayloadDisplayName</key>
            <string>Politique de Création Roundfleet</string>
            <key>AllowedExtensions</key>
            <array>
                <string>.txt</string>
                <string>.md</string>
                <string>.pdf</string>
                <string>.docx</string>
            </array>
            <key>DefaultFilePermissions</key>
            <string>644</string>
            <key>DefaultDirectoryPermissions</key>
            <string>755</string>
            <key>MaxFilenameLength</key>
            <integer>255</integer>
            <key>MaxPathDepth</key>
            <integer>20</integer>
            <key>EnforceNamingConventions</key>
            <true/>
        </dict>
    </array>
</dict>
</plist>

Exemples de Modèles

Modèle de Structure de Projet

{
  "name": "structure_webapp",
  "type": "directory_structure",
  "structure": {
    "src": {
      "type": "directory",
      "permissions": "755",
      "files": {
        "index.js": {
          "template": "javascript_main",
          "permissions": "644"
        },
        "package.json": {
          "template": "package_json",
          "permissions": "644"
        }
      },
      "subdirectories": {
        "components": {
          "type": "directory",
          "permissions": "755"
        },
        "utils": {
          "type": "directory",
          "permissions": "755"
        }
      }
    },
    "docs": {
      "type": "directory",
      "permissions": "755",
      "files": {
        "README.md": {
          "template": "readme",
          "permissions": "644"
        }
      }
    }
  }
}

Modèles de Fichiers

# Créer des modèles par défaut
./creation_manager.sh template create "readme" "# {{NOM_PROJET}}

## Aperçu
Ce projet a été créé le {{DATE}} par {{USER}}.

## Démarrage
1. Lire cette documentation
2. Examiner la structure du code
3. Commencer le développement

## Contact
Pour toute question, contacter {{USER}}@entreprise.com
"

./creation_manager.sh template create "gitignore" "# Logs
logs
*.log
npm-debug.log*

# Données d'exécution
pids
*.pid
*.seed

# Répertoire pour les librairies instrumentées
lib-cov

# Répertoire de couverture
coverage

# Répertoires de dépendances
node_modules/

# Répertoire de cache npm optionnel
.npm

# Historique REPL optionnel
.node_repl_history
"

./creation_manager.sh template create "config_json" "{
  \"name\": \"{{NOM_PROJET}}\",
  \"version\": \"1.0.0\",
  \"description\": \"Projet créé le {{DATE}}\",
  \"author\": \"{{USER}}\",
  \"created\": \"{{DATE}} {{TIME}}\",
  \"environment\": \"development\"
}
"

Fonctionnalités de Sécurité et Conformité

Gestion des Permissions

# Définir des permissions sécurisées pour les fichiers sensibles
create_secure_file() {
    local file_path="$1"
    local content="$2"
    
    # Créer le fichier avec des permissions restrictives
    enterprise_create_file "$file_path" "" "600"
    
    # Ajouter le contenu de manière sécurisée
    echo "$content" > "$file_path"
    
    # S'assurer que seul le propriétaire peut accéder
    chmod 600 "$file_path"
}

Rapport de Conformité

# Générer un rapport de conformité pour les auditeurs
generate_compliance_report() {
    local report_file="/var/reports/creation_compliance_$(date +%Y%m%d).csv"
    
    echo "Horodatage,Utilisateur,Type,Chemin,Permissions,Modèle,Statut" > "$report_file"
    
    # Analyser le fichier de log pour les opérations de création
    grep "AUDIT.*créé :" "$LOG_FILE" | while read line; do
        # Extraire les informations pertinentes et formater en CSV
        echo "$line" | awk -F' - ' '{print $1","$2}' >> "$report_file"
    done
    
    echo "Rapport de conformité généré : $report_file"
}

Dépannage

Problèmes Courants et Solutions

ProblèmeCauseSolution
Permission refuséePrivilèges insuffisantsVérifier les permissions du répertoire parent
Le fichier existe déjàTentative de création en doubleUtiliser des noms uniques ou vérifier l'existence d'abord
Caractères invalidesCaractères spéciaux dans le nomUtiliser uniquement des caractères alphanumériques
Chemin trop profondDépasse la profondeur maximaleRéduire l'imbrication des répertoires
Modèle non trouvéFichier de modèle manquantCréer le modèle ou utiliser un nom différent

Analyse des Logs

# Voir les opérations de création récentes
tail -f /var/log/roundfleet_creation_operations.log

# Rechercher les opérations échouées
grep "ERROR" /var/log/roundfleet_creation_operations.log

# Compter les opérations par type
grep -c "Fichier créé" /var/log/roundfleet_creation_operations.log
grep -c "Répertoire créé" /var/log/roundfleet_creation_operations.log

Meilleures Pratiques

  1. Utiliser les modèles de manière cohérente pour des structures standardisées
  2. Définir des permissions appropriées selon la sensibilité des fichiers
  3. Valider les conventions de nommage avant la création
  4. Surveiller régulièrement les logs de création pour les violations de politique
  5. Tester minutieusement les modèles avant le déploiement en flotte
  6. Utiliser les opérations en lot pour l'efficacité à grande échelle
  7. Implémenter l'automatisation de l'espace de travail utilisateur pour l'intégration
  8. Mises à jour régulières des modèles pour maintenir les standards

Ce système de gestion de création entreprise fournit une gestion complète des modèles, une validation de sécurité et des capacités d'automatisation tout en maintenant la simplicité des opérations de création de fichiers et répertoires de base pour une gestion efficace de flotte.

Gestion d'Entreprise de Copie de Fichiers et Dossiers sur macOS

Gérez efficacement les opérations de copie de fichiers et dossiers à travers votre déploiement Roundfleet avec des fonctionnalités de sécurité de niveau entreprise, vérification d'intégrité et capacités d'audit complètes. Ce tutoriel transforme les commandes cp de base en solutions robustes de distribution de données.

Comprendre les Opérations de Copie d'Entreprise

La copie de fichiers d'entreprise va au-delà de la simple duplication, nécessitant :

  • Validation de sécurité pour prévenir les écrasements accidentels
  • Vérification d'intégrité pour assurer la cohérence des données
  • Préservation des permissions pour la conformité sécuritaire
  • Surveillance des progrès pour les opérations importantes
  • Capacités de retour en arrière pour les transferts échoués
  • Journalisation d'audit pour les exigences de conformité

Opérations de Copie de Base

Copie de Fichier Simple

#!/bin/bash

# Copie de fichier simple avec validation
copy_file() {
    local source="$1"
    local destination="$2"
    
    # Valider que la source existe
    if [[ ! -f "$source" ]]; then
        echo "Erreur: Fichier source '$source' introuvable"
        return 1
    fi
    
    # Créer le répertoire de destination si nécessaire
    local dest_dir=$(dirname "$destination")
    mkdir -p "$dest_dir"
    
    # Copier le fichier
    if cp "$source" "$destination"; then
        echo "Copie réussie de '$source' vers '$destination'"
        return 0
    else
        echo "Échec de la copie de '$source' vers '$destination'"
        return 1
    fi
}

# Exemple d'utilisation
# copy_file "/Users/admin/document.pdf" "/Users/shared/documents/document.pdf"

Copie de Répertoire de Base

#!/bin/bash

# Copie récursive de répertoire avec vérification
copy_directory() {
    local source="$1"
    local destination="$2"
    
    # Valider que le répertoire source existe
    if [[ ! -d "$source" ]]; then
        echo "Erreur: Répertoire source '$source' introuvable"
        return 1
    fi
    
    # Copier le répertoire récursivement
    if cp -R "$source" "$destination"; then
        echo "Copie réussie du répertoire '$source' vers '$destination'"
        return 0
    else
        echo "Échec de la copie du répertoire '$source' vers '$destination'"
        return 1
    fi
}

# Exemple d'utilisation
# copy_directory "/Users/admin/project" "/Users/shared/projects/"

Système de Gestion de Copie d'Entreprise

#!/bin/bash

# Système de Gestion de Copie de Fichiers d'Entreprise Roundfleet
# Copie complète de fichiers et dossiers avec fonctionnalités d'entreprise

# Configuration
SCRIPT_NAME="Gestionnaire de Copie Roundfleet"
VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_copy_operations.log"
TEMP_DIR="/tmp/roundfleet_copy"
MAX_FILE_SIZE="10G"
ALLOWED_EXTENSIONS=(".pdf" ".docx" ".xlsx" ".pptx" ".txt" ".png" ".jpg" ".gif" ".mp4" ".mov")
RESTRICTED_PATHS=("/System" "/usr/bin" "/usr/sbin" "/private/var")
BUSINESS_HOURS_START=9
BUSINESS_HOURS_END=17

# Créer les répertoires nécessaires
mkdir -p "$TEMP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"

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

# Vérifier si l'heure actuelle est dans les heures ouvrables
is_business_hours() {
    local current_hour=$(date +%H)
    if [[ $current_hour -ge $BUSINESS_HOURS_START && $current_hour -lt $BUSINESS_HOURS_END ]]; then
        return 0
    else
        return 1
    fi
}

# Valider l'extension de fichier
is_allowed_extension() {
    local file="$1"
    local extension="${file##*.}"
    extension=".$extension"
    
    for allowed in "${ALLOWED_EXTENSIONS[@]}"; do
        if [[ "$extension" == "$allowed" ]]; then
            return 0
        fi
    done
    return 1
}

# Vérifier si le chemin est restreint
is_restricted_path() {
    local path="$1"
    for restricted in "${RESTRICTED_PATHS[@]}"; do
        if [[ "$path" == "$restricted"* ]]; then
            return 0
        fi
    done
    return 1
}

# Obtenir la taille du fichier en format lisible
get_file_size() {
    local file="$1"
    if [[ -f "$file" ]]; then
        stat -f%z "$file" 2>/dev/null
    elif [[ -d "$file" ]]; then
        du -sk "$file" 2>/dev/null | awk '{print $1 * 1024}'
    else
        echo "0"
    fi
}

# Convertir les octets en format lisible
format_size() {
    local bytes="$1"
    local sizes=("O" "Ko" "Mo" "Go" "To")
    local unit=0
    
    while [[ $bytes -gt 1024 && $unit -lt 4 ]]; do
        bytes=$((bytes / 1024))
        ((unit++))
    done
    
    echo "${bytes}${sizes[$unit]}"
}

# Calculer la somme de contrôle pour la vérification d'intégrité
calculate_checksum() {
    local file="$1"
    if [[ -f "$file" ]]; then
        shasum -a 256 "$file" 2>/dev/null | awk '{print $1}'
    else
        echo ""
    fi
}

# Vérifier l'intégrité de la copie
verify_copy_integrity() {
    local source="$1"
    local destination="$2"
    
    if [[ -f "$source" && -f "$destination" ]]; then
        local source_checksum=$(calculate_checksum "$source")
        local dest_checksum=$(calculate_checksum "$destination")
        
        if [[ "$source_checksum" == "$dest_checksum" ]]; then
            log_operation "INFO" "Vérification d'intégrité réussie pour: $destination"
            return 0
        else
            log_operation "ERROR" "Vérification d'intégrité échouée pour: $destination"
            return 1
        fi
    elif [[ -d "$source" && -d "$destination" ]]; then
        # Pour les répertoires, comparer le nombre de fichiers et les tailles
        local source_count=$(find "$source" -type f | wc -l)
        local dest_count=$(find "$destination" -type f | wc -l)
        
        if [[ $source_count -eq $dest_count ]]; then
            log_operation "INFO" "Vérification d'intégrité de répertoire réussie pour: $destination"
            return 0
        else
            log_operation "ERROR" "Vérification d'intégrité de répertoire échouée pour: $destination"
            return 1
        fi
    else
        log_operation "ERROR" "Impossible de vérifier l'intégrité - source ou destination manquante"
        return 1
    fi
}

# Créer une sauvegarde avant écrasement
create_backup() {
    local file="$1"
    local backup_dir="/var/backups/roundfleet/copy_operations"
    local timestamp=$(date '+%Y%m%d_%H%M%S')
    
    mkdir -p "$backup_dir"
    
    if [[ -e "$file" ]]; then
        local filename=$(basename "$file")
        local backup_file="$backup_dir/${filename}_backup_$timestamp"
        
        if cp -R "$file" "$backup_file"; then
            log_operation "INFO" "Sauvegarde créée: $backup_file"
            echo "$backup_file"
            return 0
        else
            log_operation "ERROR" "Échec de création de sauvegarde pour: $file"
            return 1
        fi
    fi
}

# Copie de fichier améliorée avec fonctionnalités d'entreprise
enterprise_copy_file() {
    local source="$1"
    local destination="$2"
    local preserve_permissions="${3:-true}"
    local verify_integrity="${4:-true}"
    local create_backup_flag="${5:-true}"
    
    log_operation "INFO" "Début de l'opération de copie de fichier: $source -> $destination"
    
    # Validations préalables
    if [[ ! -f "$source" ]]; then
        log_operation "ERROR" "Fichier source introuvable: $source"
        return 1
    fi
    
    # Vérifier si la source est restreinte
    if is_restricted_path "$source"; then
        log_operation "ERROR" "Chemin source restreint: $source"
        return 1
    fi
    
    # Vérifier si la destination est restreinte
    if is_restricted_path "$destination"; then
        log_operation "ERROR" "Chemin de destination restreint: $destination"
        return 1
    fi
    
    # Valider l'extension de fichier
    if ! is_allowed_extension "$source"; then
        log_operation "WARNING" "Extension de fichier pas dans la liste autorisée: $source"
    fi
    
    # Vérifier la taille du fichier
    local file_size=$(get_file_size "$source")
    local max_size_bytes=$(echo "$MAX_FILE_SIZE" | sed 's/G//' | awk '{print $1 * 1024 * 1024 * 1024}')
    
    if [[ $file_size -gt $max_size_bytes ]]; then
        log_operation "ERROR" "Fichier trop volumineux: $(format_size $file_size) > $MAX_FILE_SIZE"
        return 1
    fi
    
    # Vérification des heures ouvrables pour les gros fichiers (>100Mo)
    if [[ $file_size -gt 104857600 ]] && ! is_business_hours; then
        log_operation "WARNING" "Copie de gros fichier hors heures ouvrables: $(format_size $file_size)"
    fi
    
    # Créer le répertoire de destination
    local dest_dir=$(dirname "$destination")
    if ! mkdir -p "$dest_dir"; then
        log_operation "ERROR" "Échec de création du répertoire de destination: $dest_dir"
        return 1
    fi
    
    # Créer une sauvegarde si la destination existe
    local backup_file=""
    if [[ -f "$destination" && "$create_backup_flag" == "true" ]]; then
        backup_file=$(create_backup "$destination")
        if [[ $? -ne 0 ]]; then
            log_operation "ERROR" "Échec de création de sauvegarde pour fichier existant: $destination"
            return 1
        fi
    fi
    
    # Effectuer l'opération de copie
    local copy_options=""
    if [[ "$preserve_permissions" == "true" ]]; then
        copy_options="-p"
    fi
    
    if cp $copy_options "$source" "$destination"; then
        log_operation "INFO" "Fichier copié avec succès: $(format_size $file_size)"
        
        # Vérifier l'intégrité si demandé
        if [[ "$verify_integrity" == "true" ]]; then
            if ! verify_copy_integrity "$source" "$destination"; then
                log_operation "ERROR" "Vérification d'intégrité de copie échouée, suppression de la destination"
                rm -f "$destination"
                
                # Restaurer la sauvegarde si elle existe
                if [[ -n "$backup_file" && -f "$backup_file" ]]; then
                    cp "$backup_file" "$destination"
                    log_operation "INFO" "Fichier de sauvegarde restauré: $destination"
                fi
                return 1
            fi
        fi
        
        # Journaliser l'opération réussie
        log_operation "SUCCESS" "Copie de fichier terminée: $source -> $destination"
        return 0
    else
        log_operation "ERROR" "Opération de copie échouée: $source -> $destination"
        
        # Restaurer la sauvegarde si elle existe
        if [[ -n "$backup_file" && -f "$backup_file" ]]; then
            cp "$backup_file" "$destination"
            log_operation "INFO" "Fichier de sauvegarde restauré: $destination"
        fi
        return 1
    fi
}

# Copie de répertoire améliorée avec fonctionnalités d'entreprise
enterprise_copy_directory() {
    local source="$1"
    local destination="$2"
    local preserve_permissions="${3:-true}"
    local verify_integrity="${4:-true}"
    local create_backup_flag="${5:-true}"
    
    log_operation "INFO" "Début de l'opération de copie de répertoire: $source -> $destination"
    
    # Validations préalables
    if [[ ! -d "$source" ]]; then
        log_operation "ERROR" "Répertoire source introuvable: $source"
        return 1
    fi
    
    # Vérifier si la source est restreinte
    if is_restricted_path "$source"; then
        log_operation "ERROR" "Chemin source restreint: $source"
        return 1
    fi
    
    # Vérifier si la destination est restreinte
    if is_restricted_path "$destination"; then
        log_operation "ERROR" "Chemin de destination restreint: $destination"
        return 1
    fi
    
    # Calculer la taille du répertoire
    local dir_size=$(get_file_size "$source")
    local file_count=$(find "$source" -type f | wc -l)
    
    log_operation "INFO" "Statistiques du répertoire - Taille: $(format_size $dir_size), Fichiers: $file_count"
    
    # Vérification des heures ouvrables pour gros répertoires (>1Go ou >1000 fichiers)
    if [[ $dir_size -gt 1073741824 || $file_count -gt 1000 ]] && ! is_business_hours; then
        log_operation "WARNING" "Copie de gros répertoire hors heures ouvrables"
    fi
    
    # Créer une sauvegarde si la destination existe
    local backup_dir=""
    if [[ -d "$destination" && "$create_backup_flag" == "true" ]]; then
        backup_dir=$(create_backup "$destination")
        if [[ $? -ne 0 ]]; then
            log_operation "ERROR" "Échec de création de sauvegarde pour répertoire existant: $destination"
            return 1
        fi
    fi
    
    # Effectuer l'opération de copie
    local copy_options="-R"
    if [[ "$preserve_permissions" == "true" ]]; then
        copy_options="-Rp"
    fi
    
    if cp $copy_options "$source" "$destination"; then
        log_operation "INFO" "Répertoire copié avec succès: $(format_size $dir_size)"
        
        # Vérifier l'intégrité si demandé
        if [[ "$verify_integrity" == "true" ]]; then
            if ! verify_copy_integrity "$source" "$destination"; then
                log_operation "ERROR" "Vérification d'intégrité de copie de répertoire échouée, suppression de la destination"
                rm -rf "$destination"
                
                # Restaurer la sauvegarde si elle existe
                if [[ -n "$backup_dir" && -d "$backup_dir" ]]; then
                    cp -R "$backup_dir" "$destination"
                    log_operation "INFO" "Répertoire de sauvegarde restauré: $destination"
                fi
                return 1
            fi
        fi
        
        # Journaliser l'opération réussie
        log_operation "SUCCESS" "Copie de répertoire terminée: $source -> $destination"
        return 0
    else
        log_operation "ERROR" "Opération de copie de répertoire échouée: $source -> $destination"
        
        # Restaurer la sauvegarde si elle existe
        if [[ -n "$backup_dir" && -d "$backup_dir" ]]; then
            cp -R "$backup_dir" "$destination"
            log_operation "INFO" "Répertoire de sauvegarde restauré: $destination"
        fi
        return 1
    fi
}

# Opérations de copie en lot avec surveillance des progrès
bulk_copy_operation() {
    local operation_type="$1"  # "file" ou "directory"
    local source_list="$2"     # Fichier contenant les chemins sources
    local destination_base="$3" # Répertoire de destination de base
    
    if [[ ! -f "$source_list" ]]; then
        log_operation "ERROR" "Fichier de liste source introuvable: $source_list"
        return 1
    fi
    
    local total_items=$(wc -l < "$source_list")
    local current_item=0
    local success_count=0
    local failure_count=0
    
    log_operation "INFO" "Début de l'opération de copie en lot - Total d'éléments: $total_items"
    
    while IFS= read -r source_path; do
        ((current_item++))
        
        # Ignorer les lignes vides et commentaires
        [[ -z "$source_path" || "$source_path" =~ ^#.* ]] && continue
        
        local filename=$(basename "$source_path")
        local destination="$destination_base/$filename"
        
        echo "Traitement [$current_item/$total_items]: $filename"
        
        if [[ "$operation_type" == "file" ]]; then
            if enterprise_copy_file "$source_path" "$destination"; then
                ((success_count++))
            else
                ((failure_count++))
            fi
        elif [[ "$operation_type" == "directory" ]]; then
            if enterprise_copy_directory "$source_path" "$destination"; then
                ((success_count++))
            else
                ((failure_count++))
            fi
        fi
        
        # Mise à jour des progrès
        local progress=$((current_item * 100 / total_items))
        echo "Progrès: $progress% ($success_count réussis, $failure_count échoués)"
        
    done < "$source_list"
    
    log_operation "SUCCESS" "Copie en lot terminée - Succès: $success_count, Échecs: $failure_count"
    return $failure_count
}

# Générer un rapport d'opérations de copie
generate_copy_report() {
    local report_file="/tmp/roundfleet_copy_report_$(date +%Y%m%d_%H%M%S).txt"
    
    {
        echo "Rapport des Opérations de Copie Roundfleet"
        echo "Généré: $(date)"
        echo "Nom d'hôte: $(hostname)"
        echo "==============================="
        echo ""
        
        echo "Opérations de Copie Récentes (Dernières 24 heures):"
        if [[ -f "$LOG_FILE" ]]; then
            local yesterday=$(date -v-1d '+%Y-%m-%d')
            grep "$yesterday\|$(date '+%Y-%m-%d')" "$LOG_FILE" | tail -50
        else
            echo "Aucun fichier de journal trouvé"
        fi
        
        echo ""
        echo "Informations Système:"
        echo "Espace Disponible:"
        df -h | grep -E "^/dev/"
        
        echo ""
        echo "Statistiques d'Opérations de Copie:"
        if [[ -f "$LOG_FILE" ]]; then
            echo "Total des Opérations: $(grep -c "copy operation" "$LOG_FILE" 2>/dev/null || echo "0")"
            echo "Réussis: $(grep -c "SUCCESS.*copy completed" "$LOG_FILE" 2>/dev/null || echo "0")"
            echo "Échecs: $(grep -c "ERROR.*copy.*failed" "$LOG_FILE" 2>/dev/null || echo "0")"
        fi
        
    } > "$report_file"
    
    echo "Rapport d'opérations de copie sauvegardé dans: $report_file"
    log_operation "INFO" "Rapport de copie généré: $report_file"
}

# Fonction principale de gestion de copie
main() {
    local action="${1:-help}"
    
    case "$action" in
        "copy-file")
            local source="$2"
            local destination="$3"
            local preserve_perms="${4:-true}"
            local verify="${5:-true}"
            local backup="${6:-true}"
            
            if [[ -z "$source" || -z "$destination" ]]; then
                echo "Usage: $0 copy-file <source> <destination> [preserve_permissions] [verify_integrity] [create_backup]"
                exit 1
            fi
            
            enterprise_copy_file "$source" "$destination" "$preserve_perms" "$verify" "$backup"
            ;;
        "copy-directory")
            local source="$2"
            local destination="$3"
            local preserve_perms="${4:-true}"
            local verify="${5:-true}"
            local backup="${6:-true}"
            
            if [[ -z "$source" || -z "$destination" ]]; then
                echo "Usage: $0 copy-directory <source> <destination> [preserve_permissions] [verify_integrity] [create_backup]"
                exit 1
            fi
            
            enterprise_copy_directory "$source" "$destination" "$preserve_perms" "$verify" "$backup"
            ;;
        "bulk-files")
            local source_list="$2"
            local destination="$3"
            
            if [[ -z "$source_list" || -z "$destination" ]]; then
                echo "Usage: $0 bulk-files <source_list_file> <destination_directory>"
                exit 1
            fi
            
            bulk_copy_operation "file" "$source_list" "$destination"
            ;;
        "bulk-directories")
            local source_list="$2"
            local destination="$3"
            
            if [[ -z "$source_list" || -z "$destination" ]]; then
                echo "Usage: $0 bulk-directories <source_list_file> <destination_directory>"
                exit 1
            fi
            
            bulk_copy_operation "directory" "$source_list" "$destination"
            ;;
        "report")
            generate_copy_report
            ;;
        "help"|*)
            echo "$SCRIPT_NAME v$VERSION"
            echo "Gestion d'Entreprise de Copie de Fichiers et Dossiers"
            echo ""
            echo "Usage: $0 <action> [options]"
            echo ""
            echo "Actions:"
            echo "  copy-file <source> <destination>       - Copier un fichier unique"
            echo "  copy-directory <source> <destination>  - Copier un répertoire récursivement"
            echo "  bulk-files <list_file> <destination>   - Copie en lot de fichiers depuis une liste"
            echo "  bulk-directories <list_file> <dest>    - Copie en lot de répertoires depuis une liste"
            echo "  report                                  - Générer un rapport d'opérations"
            echo "  help                                    - Afficher ce message d'aide"
            echo ""
            echo "Fonctionnalités:"
            echo "  • Validation de sécurité et vérification d'intégrité"
            echo "  • Création automatique de sauvegarde avant écrasement"
            echo "  • Vérification de conformité aux heures ouvrables"
            echo "  • Journalisation d'audit complète"
            echo "  • Préservation des permissions"
            echo "  • Surveillance des progrès pour opérations en lot"
            ;;
    esac
}

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

Commandes de Référence Rapide

Opérations de Fichier Unique

# Copier un fichier avec toutes les fonctionnalités d'entreprise
./copy_manager.sh copy-file "/Users/admin/document.pdf" "/Users/shared/documents/document.pdf"

# Copier un fichier sans création de sauvegarde
./copy_manager.sh copy-file "/source/file.txt" "/destination/file.txt" true true false

# Copier un fichier sans vérification d'intégrité (plus rapide)
./copy_manager.sh copy-file "/source/file.txt" "/destination/file.txt" true false true

Opérations de Répertoire

# Copier un répertoire avec tous ses sous-répertoires
./copy_manager.sh copy-directory "/Users/admin/project" "/Users/shared/projects/"

# Copier un répertoire en préservant les permissions
./copy_manager.sh copy-directory "/source/folder" "/destination/" true true true

Opérations en Lot

# Créer une liste de fichiers pour les opérations en lot
echo "/Users/admin/doc1.pdf" > /tmp/files_to_copy.txt
echo "/Users/admin/doc2.pdf" >> /tmp/files_to_copy.txt
echo "/Users/admin/doc3.pdf" >> /tmp/files_to_copy.txt

# Exécuter la copie en lot de fichiers
./copy_manager.sh bulk-files "/tmp/files_to_copy.txt" "/Users/shared/documents/"

# Exécuter la copie en lot de répertoires
./copy_manager.sh bulk-directories "/tmp/dirs_to_copy.txt" "/Users/shared/projects/"

Exemples d'Intégration

Intégration JAMF Pro

#!/bin/bash

# Script JAMF Pro pour la distribution de fichiers d'entreprise
# Paramètres: $4 = source_path, $5 = destination_path, $6 = operation_type

SOURCE_PATH="$4"
DESTINATION_PATH="$5"
OPERATION_TYPE="$6"

# Télécharger le gestionnaire de copie s'il n'est pas présent
if [[ ! -f "/usr/local/bin/roundfleet_copy_manager.sh" ]]; then
    curl -o "/usr/local/bin/roundfleet_copy_manager.sh" "https://scripts.roundfleet.com/copy_manager.sh"
    chmod +x "/usr/local/bin/roundfleet_copy_manager.sh"
fi

# Exécuter l'opération de copie
case "$OPERATION_TYPE" in
    "file")
        /usr/local/bin/roundfleet_copy_manager.sh copy-file "$SOURCE_PATH" "$DESTINATION_PATH"
        ;;
    "directory")
        /usr/local/bin/roundfleet_copy_manager.sh copy-directory "$SOURCE_PATH" "$DESTINATION_PATH"
        ;;
    *)
        echo "Type d'opération invalide: $OPERATION_TYPE"
        exit 1
        ;;
esac

# Générer un rapport
/usr/local/bin/roundfleet_copy_manager.sh report

exit $?

Profil de Configuration pour Politiques de Copie

<?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>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.roundfleet.copy.policy</string>
            <key>PayloadIdentifier</key>
            <string>com.roundfleet.copy.policy.main</string>
            <key>PayloadDisplayName</key>
            <string>Politique de Copie Roundfleet</string>
            <key>MaxFileSize</key>
            <string>10G</string>
            <key>AllowedExtensions</key>
            <array>
                <string>.pdf</string>
                <string>.docx</string>
                <string>.xlsx</string>
                <string>.pptx</string>
            </array>
            <key>BusinessHoursOnly</key>
            <true/>
            <key>RequireIntegrityCheck</key>
            <true/>
            <key>CreateBackups</key>
            <true/>
        </dict>
    </array>
</dict>
</plist>

Fonctionnalités de Sécurité et Conformité

Surveillance du Système de Fichiers

# Surveiller les opérations de copie avec FSEvents
fswatch -r /Users/shared/ | while read event; do
    if [[ "$event" =~ "CREATED" ]]; then
        log_operation "MONITOR" "Fichier créé: $event"
    fi
done

Rapport de Conformité

# Générer un rapport de conformité pour les auditeurs
generate_compliance_report() {
    local report_file="/var/reports/copy_compliance_$(date +%Y%m%d).csv"
    
    echo "Horodatage,Utilisateur,Source,Destination,Taille,Statut,Somme_controle" > "$report_file"
    
    # Analyser le fichier de journal pour les opérations de copie
    grep "copy completed\|copy.*failed" "$LOG_FILE" | while read line; do
        # Extraire les informations pertinentes et formater en CSV
        echo "$line" | awk -F' - ' '{print $1","$2}' >> "$report_file"
    done
    
    echo "Rapport de conformité généré: $report_file"
}

Dépannage

Problèmes Courants et Solutions

ProblèmeCauseSolution
Permission refuséePrivilèges insuffisantsExécuter avec sudo ou vérifier les permissions de fichier
Erreur d'espace disqueDestination pleineVérifier l'espace disponible avec df -h
Vérification d'intégrité échouéeCopie corrompueRelancer l'opération de copie, vérifier la santé du disque
Source introuvableChemin incorrectVérifier que le chemin source existe
Délai d'expiration d'opérationGros fichier/disque lentAugmenter le délai ou diviser l'opération

Analyse des Journaux

# Voir les opérations de copie récentes
tail -f /var/log/roundfleet_copy_operations.log

# Rechercher les opérations échouées
grep "ERROR" /var/log/roundfleet_copy_operations.log

# Compter les opérations par statut
grep -c "SUCCESS" /var/log/roundfleet_copy_operations.log
grep -c "ERROR" /var/log/roundfleet_copy_operations.log

Meilleures Pratiques

  1. Toujours tester sur un appareil unique avant le déploiement en flotte
  2. Surveiller l'espace disque avant les grosses opérations de copie
  3. Utiliser les restrictions d'heures ouvrables pour les opérations consommant des ressources
  4. Activer la vérification d'intégrité pour les données critiques
  5. Maintenir des sauvegardes régulières des destinations importantes
  6. Réviser les journaux régulièrement pour les opérations échouées
  7. Définir des limites appropriées de taille de fichier basées sur la capacité réseau
  8. Utiliser les opérations en lot pour l'efficacité à grande échelle

Ce système de gestion de copie d'entreprise fournit des fonctionnalités complètes de sécurité, surveillance et conformité tout en maintenant la simplicité des opérations de copie de base pour les tâches quotidiennes de gestion de flotte.

Récupérer les Journaux d'Appareils sur macOS

macOS fournit un système de journalisation unifié puissant qui capture des informations détaillées sur les processus système, applications et activités utilisateur. Ce tutoriel montre comment collecter et analyser efficacement les journaux d'appareils dans votre Roundfleet pour le dépannage, la surveillance de sécurité et l'analyse de performance.

Comprendre la Journalisation macOS

macOS utilise le système de journalisation unifié introduit dans macOS 10.12, qui consolide diverses sources de journaux :

  • Journaux système - Noyau, services système et démons
  • Journaux d'applications - Applications utilisateur et processus d'arrière-plan
  • Journaux de sécurité - Authentification, autorisation et événements de sécurité
  • Journaux réseau - Activité réseau et connectivité

Commandes de Journal de Base

Voir les Journaux Système Récents

#!/bin/bash

# Afficher les journaux de la dernière minute
sudo log show --last 1m

# Afficher les journaux de la dernière heure
sudo log show --last 1h

# Afficher les journaux du dernier jour
sudo log show --last 1d

Diffusion de Journaux en Direct

#!/bin/bash

# Diffuser les journaux en direct
sudo log stream

# Diffuser avec horodatage
sudo log stream --info --debug

Journaux Spécifiques aux Applications

Obtenir les Journaux pour une Application Spécifique

#!/bin/bash

# Requête de journal d'app basique
log show --predicate 'processImagePath CONTAINS[c] "safari"'

# Requête avec plage de temps
log show --predicate 'processImagePath CONTAINS[c] "Finder"' --last 30m

# Sauvegarder les journaux d'app dans un fichier
log show --predicate 'processImagePath CONTAINS[c] "Mail"' --last 1h > ~/Desktop/mail_logs.txt

Script de Collection de Journaux Entreprise

#!/bin/bash

# Script de Collection de Journaux d'Appareils pour Roundfleet
# Compatible avec macOS 10.14+

# Configuration
LOG_DIR="/var/log/roundfleet_logs"
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
HOSTNAME=$(hostname -s)
OUTPUT_DIR="$LOG_DIR/${HOSTNAME}_${TIMESTAMP}"
ARCHIVE_NAME="${HOSTNAME}_logs_${TIMESTAMP}.tar.gz"

# Fonction pour enregistrer les messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_DIR/collection.log"
}

# Fonction pour créer le répertoire de sortie
setup_directories() {
    if mkdir -p "$OUTPUT_DIR"; then
        log_message "✓ Répertoire de sortie créé : $OUTPUT_DIR"
        return 0
    else
        log_message "✗ Échec de la création du répertoire de sortie"
        return 1
    fi
}

# Fonction pour collecter les journaux système
collect_system_logs() {
    log_message "Collecte des journaux système..."
    
    # Journaux système récents (dernières 24 heures)
    if log show --last 24h > "$OUTPUT_DIR/system_logs_24h.log"; then
        log_message "✓ Journaux système collectés (24h)"
    else
        log_message "✗ Échec de la collecte des journaux système"
    fi
    
    # Journaux critiques et d'erreur uniquement
    if log show --last 24h --predicate 'messageType == 16 OR messageType == 17' > "$OUTPUT_DIR/critical_errors.log"; then
        log_message "✓ Journaux critiques/erreurs collectés"
    else
        log_message "✗ Échec de la collecte des journaux critiques"
    fi
    
    # Journaux de démarrage
    if log show --predicate 'process == "kernel"' --last 7d > "$OUTPUT_DIR/kernel_logs.log"; then
        log_message "✓ Journaux du noyau collectés"
    else
        log_message "✗ Échec de la collecte des journaux du noyau"
    fi
}

# Fonction pour collecter les journaux d'applications
collect_app_logs() {
    log_message "Collecte des journaux d'applications..."
    
    # Applications communes à surveiller
    local apps=("Safari" "Finder" "Mail" "Calendar" "Contacts" "Notes" "Spotlight" "WindowServer")
    
    for app in "${apps[@]}"; do
        local output_file="$OUTPUT_DIR/${app,,}_logs.log"
        if log show --predicate "processImagePath CONTAINS[c] \"$app\"" --last 24h > "$output_file" 2>/dev/null; then
            # Garder le fichier seulement s'il a du contenu
            if [[ -s "$output_file" ]]; then
                log_message "✓ Journaux $app collectés"
            else
                rm -f "$output_file"
                log_message "! Aucun journal trouvé pour $app"
            fi
        else
            log_message "✗ Échec de la collecte des journaux $app"
        fi
    done
}

# Fonction pour collecter les journaux de sécurité
collect_security_logs() {
    log_message "Collecte des journaux de sécurité..."
    
    # Journaux d'authentification
    if log show --predicate 'category == "authorization" OR process == "authd"' --last 7d > "$OUTPUT_DIR/auth_logs.log"; then
        log_message "✓ Journaux d'authentification collectés"
    else
        log_message "✗ Échec de la collecte des journaux d'auth"
    fi
    
    # Événements de connexion/déconnexion
    if log show --predicate 'eventMessage CONTAINS "login" OR eventMessage CONTAINS "logout"' --last 7d > "$OUTPUT_DIR/login_events.log"; then
        log_message "✓ Événements de connexion collectés"
    else
        log_message "✗ Échec de la collecte des événements de connexion"
    fi
}

# Fonction pour collecter les informations système
collect_system_info() {
    log_message "Collecte des informations système..."
    
    {
        echo "=== Informations Système ==="
        echo "Nom d'hôte : $(hostname)"
        echo "Version macOS : $(sw_vers -productVersion)"
        echo "Build : $(sw_vers -buildVersion)"
        echo "Uptime : $(uptime)"
        echo "Date : $(date)"
        echo ""
        
        echo "=== Informations Matériel ==="
        system_profiler SPHardwareDataType
        echo ""
        
        echo "=== Usage Disque ==="
        df -h
        echo ""
        
        echo "=== Usage Mémoire ==="
        vm_stat
        echo ""
        
        echo "=== Processus en Cours ==="
        ps aux | head -20
        
    } > "$OUTPUT_DIR/system_info.txt"
    
    log_message "✓ Informations système collectées"
}

# Fonction pour créer une archive
create_archive() {
    log_message "Création de l'archive..."
    
    cd "$LOG_DIR" || return 1
    
    if tar -czf "$ARCHIVE_NAME" "$(basename "$OUTPUT_DIR")"; then
        log_message "✓ Archive créée : $LOG_DIR/$ARCHIVE_NAME"
        
        # Nettoyer le répertoire temporaire
        rm -rf "$OUTPUT_DIR"
        log_message "✓ Fichiers temporaires nettoyés"
        
        # Afficher la taille de l'archive
        local size
        size=$(du -h "$LOG_DIR/$ARCHIVE_NAME" | cut -f1)
        log_message "Taille de l'archive : $size"
        
        return 0
    else
        log_message "✗ Échec de la création de l'archive"
        return 1
    fi
}

# Fonction pour télécharger l'archive (placeholder pour intégration entreprise)
upload_archive() {
    local archive_path="$LOG_DIR/$ARCHIVE_NAME"
    
    # Exemple : Télécharger vers serveur de journalisation central
    # Remplacer par votre mécanisme de téléchargement actuel
    log_message "Archive prête pour collecte : $archive_path"
    
    # Placeholder pour logique de téléchargement
    # scp "$archive_path" user@logserver:/logs/
    # curl -F "file=@$archive_path" https://logserver.company.com/upload
    
    return 0
}

# Fonction d'exécution principale
main() {
    log_message "=== Début de la collecte de journaux Roundfleet ==="
    
    # Configuration
    if ! setup_directories; then
        exit 1
    fi
    
    # Collecter les journaux
    collect_system_logs
    collect_app_logs
    collect_security_logs
    collect_system_info
    
    # Créer l'archive
    if create_archive; then
        upload_archive
        log_message "=== Collecte de journaux terminée avec succès ==="
        exit 0
    else
        log_message "=== Échec de la collecte de journaux ==="
        exit 1
    fi
}

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

Scripts de Collection de Journaux Rapide

Collecter les Journaux pour une Période Spécifique

#!/bin/bash

# Collecter les journaux entre des dates spécifiques
START_DATE="2025-01-01"
END_DATE="2025-01-02"
OUTPUT_FILE="~/Desktop/logs_${START_DATE}_to_${END_DATE}.txt"

log show --start "$START_DATE" --end "$END_DATE" > "$OUTPUT_FILE"
echo "Journaux sauvegardés dans : $OUTPUT_FILE"

Collecter les Journaux de Crash d'Applications

#!/bin/bash

# Collecter les rapports de crash
CRASH_DIR="~/Library/Logs/DiagnosticReports"
OUTPUT_DIR="~/Desktop/crash_logs"

mkdir -p "$OUTPUT_DIR"
find "$CRASH_DIR" -name "*.crash" -mtime -7 -exec cp {} "$OUTPUT_DIR/" \;

echo "Journaux de crash récents copiés dans : $OUTPUT_DIR"

Surveiller des Événements Spécifiques

#!/bin/bash

# Surveiller les connexions de périphériques USB
log stream --predicate 'eventMessage CONTAINS "USB"' --info

# Surveiller les changements réseau
log stream --predicate 'subsystem == "com.apple.network"' --info

# Surveiller les événements du système de fichiers
log stream --predicate 'subsystem == "com.apple.filesystem"' --debug

Scripts d'Analyse de Journaux

Analyser les Événements d'Authentification

#!/bin/bash

# Extraire les tentatives de connexion échouées
log show --predicate 'eventMessage CONTAINS "authentication failure"' --last 7d \
    | grep -E "(authentication failure|failed)" \
    | sort | uniq -c | sort -nr > ~/Desktop/failed_logins.txt

echo "Analyse des connexions échouées sauvegardée dans ~/Desktop/failed_logins.txt"

Statistiques d'Usage d'Applications

#!/bin/bash

# Analyser les lancements d'applications
log show --predicate 'process == "launchd" AND eventMessage CONTAINS "spawn"' --last 24h \
    | grep -oE '"[^"]*\.app"' \
    | sort | uniq -c | sort -nr > ~/Desktop/app_usage.txt

echo "Statistiques d'usage d'applications sauvegardées dans ~/Desktop/app_usage.txt"

Gestion des Archives de Journaux

Créer une Archive de Journal Système

#!/bin/bash

# Créer une archive complète des journaux système
ARCHIVE_PATH="~/Desktop/SystemLogs_$(date +%Y%m%d_%H%M%S).logarchive"

log collect --output "$ARCHIVE_PATH" --last 24h

echo "Archive des journaux système créée : $ARCHIVE_PATH"

Voir les Journaux Archivés

#!/bin/bash

# Voir les journaux depuis l'archive
ARCHIVE_PATH="~/Desktop/SystemLogs.logarchive"

if [[ -f "$ARCHIVE_PATH" ]]; then
    log show --archive "$ARCHIVE_PATH" --last 1h
else
    echo "Archive non trouvée : $ARCHIVE_PATH"
fi

Dépannage des Problèmes Courants

ProblèmeSolution
Permission refuséeExécuter avec sudo pour les journaux système
Aucun journal trouvéVérifier la plage de dates et les prédicats
Gros fichiers de journauxUtiliser des filtres de temps et prédicats spécifiques
Timeouts de scriptRéduire la plage de temps ou utiliser la collecte asynchrone
Corruption d'archiveVérifier l'espace disque et les permissions

Exemples de Filtrage de Journaux

Filtrer par Niveau de Journal

# Messages d'erreur uniquement
log show --predicate 'messageType == 16' --last 1h

# Messages info et debug
log show --predicate 'messageType >= 1' --last 30m

# Erreurs critiques uniquement
log show --predicate 'messageType == 17' --last 24h

Filtrer par Processus

# Processus système
log show --predicate 'process == "kernel" OR process == "launchd"' --last 1h

# Processus utilisateur
log show --predicate 'processImagePath BEGINSWITH "/Applications"' --last 1h

# Démons d'arrière-plan
log show --predicate 'processImagePath CONTAINS "daemon"' --last 1h

Considérations de Sécurité

  • Confidentialité - Être attentif aux données utilisateur dans les journaux
  • Rétention - Implémenter la rotation et le nettoyage des journaux
  • Contrôle d'accès - Restreindre l'accès aux journaux au personnel autorisé
  • Chiffrement - Chiffrer les archives de journaux avant transmission
  • Conformité - Suivre les politiques de rétention des données

Conseils de Performance

  • Utiliser des plages de temps spécifiques pour limiter le volume de données
  • Filtrer par processus ou catégorie pour réduire le bruit
  • Diffuser les journaux en temps réel pour une analyse immédiate
  • Compresser les archives pour économiser l'espace de stockage
  • Programmer la collecte régulière de journaux pendant les heures creuses

Notes Importantes

  • Les journaux système peuvent contenir des informations sensibles
  • Les grandes plages de temps peuvent générer des fichiers de journaux massifs
  • Certains journaux nécessitent des privilèges admin pour l'accès
  • La collecte de journaux peut impacter les performances système
  • Tester les scripts sur des appareils individuels avant le déploiement de flotte

Vider la Corbeille sur macOS

Apprenez à vider à distance les corbeilles sur Mac à l'aide de scripts. Cela aide à libérer de l'espace disque et gérer le stockage efficacement sur votre flotte Mac.

Vider la Corbeille d'un Utilisateur Spécifique

Supprimer tous les éléments de la corbeille d'un utilisateur spécifique :

#!/bin/bash

# Spécifier le nom d'utilisateur
USERNAME="john"

# Vider la corbeille pour un utilisateur spécifique
sudo rm -rf /Users/"${USERNAME}"/.Trash/*

echo "Corbeille vidée pour l'utilisateur : ${USERNAME}"

Vider la Corbeille de l'Utilisateur Actuel

Détecter automatiquement et vider la corbeille de l'utilisateur actuellement connecté :

#!/bin/bash

# Obtenir l'utilisateur actuel
CURRENT_USER=$(stat -f "%Su" /dev/console)

# Vider la corbeille pour l'utilisateur actuel
su "$CURRENT_USER" -c "rm -rf ~/.Trash/*"

echo "Corbeille vidée pour l'utilisateur actuel : ${CURRENT_USER}"

Script Avancé avec Validation

Script avec gestion d'erreur et journalisation :

#!/bin/bash

# Fonction pour journaliser les messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $1"
}

# Obtenir l'utilisateur actuel
CURRENT_USER=$(stat -f "%Su" /dev/console)

if [[ -z "$CURRENT_USER" ]]; then
    log_message "Erreur : Impossible de déterminer l'utilisateur actuel"
    exit 1
fi

log_message "Vidage de la corbeille pour l'utilisateur : ${CURRENT_USER}"

# Vérifier si le répertoire corbeille existe
TRASH_DIR="/Users/${CURRENT_USER}/.Trash"
if [[ ! -d "$TRASH_DIR" ]]; then
    log_message "Répertoire corbeille non trouvé : ${TRASH_DIR}"
    exit 1
fi

# Compter les éléments avant suppression
ITEM_COUNT=$(find "$TRASH_DIR" -mindepth 1 -maxdepth 1 | wc -l)
log_message "Trouvé ${ITEM_COUNT} éléments dans la corbeille"

if [[ $ITEM_COUNT -eq 0 ]]; then
    log_message "La corbeille est déjà vide"
    exit 0
fi

# Vider la corbeille
if su "$CURRENT_USER" -c "rm -rf ~/.Trash/*"; then
    log_message "Corbeille vidée avec succès pour ${CURRENT_USER}"
else
    log_message "Échec du vidage de la corbeille"
    exit 1
fi

Gestion Corbeille Multi-Utilisateurs

Vider la corbeille pour tous les utilisateurs du système :

#!/bin/bash

# Fonction pour journaliser les messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $1"
}

log_message "Démarrage du nettoyage corbeille multi-utilisateurs"

# Trouver tous les répertoires utilisateurs
for USER_DIR in /Users/*; do
    if [[ -d "$USER_DIR" && ! "$USER_DIR" =~ /Users/(Shared|Guest) ]]; then
        USERNAME=$(basename "$USER_DIR")
        TRASH_DIR="$USER_DIR/.Trash"
        
        if [[ -d "$TRASH_DIR" ]]; then
            ITEM_COUNT=$(find "$TRASH_DIR" -mindepth 1 -maxdepth 1 2>/dev/null | wc -l)
            
            if [[ $ITEM_COUNT -gt 0 ]]; then
                log_message "Vidage corbeille pour utilisateur : ${USERNAME} (${ITEM_COUNT} éléments)"
                sudo rm -rf "$TRASH_DIR"/*
                log_message "Nettoyage corbeille terminé pour : ${USERNAME}"
            else
                log_message "Corbeille déjà vide pour utilisateur : ${USERNAME}"
            fi
        fi
    fi
done

log_message "Nettoyage corbeille multi-utilisateurs terminé"

Utilisation avec Roundfleet

  1. Choisissez le script approprié selon vos besoins
  2. Pour des utilisateurs spécifiques, modifiez la variable USERNAME
  3. Déployez via l'exécution de script distant Roundfleet
  4. Surveillez les résultats dans l'historique des actions

Prérequis

  • Accès Disque Complet : Accordez l'accès disque complet à l'agent Roundfleet dans Réglages Système > Confidentialité et Sécurité > Accès Disque Complet
  • Privilèges administrateur : Les scripts nécessitent un accès sudo pour les opérations système

Considérations de Sécurité

  • Vérifiez les permissions utilisateur avant d'exécuter les scripts
  • Considérez sauvegarder les fichiers importants avant suppression de corbeille en masse
  • Testez sur un nombre limité d'appareils avant déploiement flotte

Dépannage

Permission refusée : Assurez-vous que l'agent Roundfleet a l'Accès Disque Complet Utilisateur non trouvé : Vérifiez que le nom d'utilisateur existe sur l'appareil cible Échec du script : Vérifiez si l'utilisateur est actuellement connecté pour les opérations spécifiques


Note : Les éléments supprimés ne peuvent pas être récupérés après exécution de ces scripts. Validez toujours sur des systèmes de test d'abord.

Gestion d'Entreprise du Dock et Personnalisation d'Interface sur macOS

Optimisez la productivité des utilisateurs et maintenez des standards d'interface cohérents sur vos appareils Roundfleet avec une gestion complète du dock et la personnalisation d'interface. Ce tutoriel couvre la configuration du dock d'entreprise, le déploiement à l'échelle de la flotte, l'optimisation de l'expérience utilisateur et la gestion automatisée d'interface pour une productivité organisationnelle améliorée.

Comprendre la Gestion du Dock macOS

Le Dock macOS sert de lanceur d'applications principal et d'organisateur d'espace de travail :

  • Lanceur d'Applications - Accès rapide aux applications fréquemment utilisées
  • Indicateur d'Applications Actives - Représentation visuelle des applications en cours d'exécution
  • Accès Fichiers & Dossiers - Accès direct aux documents et répertoires
  • Gestion Corbeille - Interface de suppression et récupération de fichiers
  • Hub Productivité - Navigation centralisée de l'espace de travail

Configuration Basique du Dock

Définir un Arrangement d'Applications Personnalisé

#!/bin/bash

# Configurer les applications personnalisées du dock
configure_basic_dock() {
    echo "=== Configuration Basique du Dock ==="
    
    local logged_user=$(stat -f%Su /dev/console)
    
    if [[ -z "$logged_user" || "$logged_user" == "root" ]]; then
        echo "❌ Aucun utilisateur connecté ou utilisateur invalide"
        return 1
    fi
    
    echo "Configuration du dock pour l'utilisateur: $logged_user"
    
    # Définir un ensemble d'applications standard
    local standard_apps=(
        "/Applications/Safari.app"
        "/Applications/Mail.app"
        "/System/Applications/Messages.app"
        "/Applications/Calendar.app"
        "/Applications/Notes.app"
        "/System/Applications/System Preferences.app"
        "/Applications/Google Chrome.app"
        "/Applications/Microsoft Outlook.app"
        "/Applications/Slack.app"
        "/Applications/Zoom.app"
    )
    
    # Construire la configuration du dock
    local dock_config="<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>PLACEHOLDER</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"
    local dock_array=""
    
    for app in "${standard_apps[@]}"; do
        if [[ -d "$app" ]]; then
            local app_entry="${dock_config/PLACEHOLDER/$app}"
            if [[ -n "$dock_array" ]]; then
                dock_array="$dock_array "
            fi
            dock_array="$dock_array'$app_entry'"
            echo "✅ Ajouté au dock: $(basename "$app" .app)"
        else
            echo "⚠️  Application non trouvée: $app"
        fi
    done
    
    # Appliquer la configuration du dock
    if [[ -n "$dock_array" ]]; then
        sudo su "$logged_user" -c "defaults write com.apple.dock persistent-apps -array $dock_array"
        sudo su "$logged_user" -c "killall Dock"
        echo "✅ Configuration basique du dock appliquée"
    else
        echo "❌ Aucune application trouvée à configurer"
        return 1
    fi
    
    return 0
}

# Exécuter la fonction
configure_basic_dock

Réinitialiser le Dock à l'État par Défaut

#!/bin/bash

# Réinitialiser le dock à la configuration par défaut de macOS
reset_dock_default() {
    echo "=== Réinitialisation du Dock à l'État par Défaut ==="
    
    local logged_user=$(stat -f%Su /dev/console)
    
    if [[ -z "$logged_user" || "$logged_user" == "root" ]]; then
        echo "❌ Aucun utilisateur connecté ou utilisateur invalide"
        return 1
    fi
    
    echo "Réinitialisation du dock pour l'utilisateur: $logged_user"
    
    # Créer une sauvegarde de la configuration actuelle du dock
    local backup_file="/tmp/dock_backup_$(date '+%Y%m%d_%H%M%S').plist"
    sudo su "$logged_user" -c "defaults export com.apple.dock '$backup_file'"
    
    if [[ -f "$backup_file" ]]; then
        echo "✅ Configuration du dock sauvegardée dans: $backup_file"
    fi
    
    # Réinitialiser les préférences du dock
    sudo su "$logged_user" -c "defaults delete com.apple.dock"
    
    # Redémarrer le dock
    killall Dock
    
    echo "✅ Dock réinitialisé à l'état par défaut"
    return 0
}

# Exécuter la fonction
reset_dock_default

Configurer l'Apparence Visuelle

#!/bin/bash

# Configurer l'apparence visuelle et le comportement du dock
configure_dock_appearance() {
    local logged_user=$(stat -f%Su /dev/console)
    local dock_size="${1:-48}"
    local magnification="${2:-true}"
    local autohide="${3:-false}"
    local position="${4:-bottom}"
    
    echo "=== Configuration de l'Apparence du Dock ==="
    echo "Utilisateur: $logged_user"
    echo "Taille: $dock_size"
    echo "Agrandissement: $magnification"
    echo "Masquage automatique: $autohide"
    echo "Position: $position"
    
    if [[ -z "$logged_user" || "$logged_user" == "root" ]]; then
        echo "❌ Aucun utilisateur connecté"
        return 1
    fi
    
    # Configurer la taille du dock
    sudo su "$logged_user" -c "defaults write com.apple.dock tilesize -int $dock_size"
    
    # Configurer l'agrandissement
    if [[ "$magnification" == "true" ]]; then
        sudo su "$logged_user" -c "defaults write com.apple.dock magnification -bool true"
        sudo su "$logged_user" -c "defaults write com.apple.dock largesize -int 128"
    else
        sudo su "$logged_user" -c "defaults write com.apple.dock magnification -bool false"
    fi
    
    # Configurer le masquage automatique
    sudo su "$logged_user" -c "defaults write com.apple.dock autohide -bool $autohide"
    
    # Configurer la position du dock
    sudo su "$logged_user" -c "defaults write com.apple.dock orientation -string $position"
    
    # Configurer l'effet de minimisation
    sudo su "$logged_user" -c "defaults write com.apple.dock mineffect -string genie"
    
    # Afficher les indicateurs d'applications masquées
    sudo su "$logged_user" -c "defaults write com.apple.dock showhidden -bool true"
    
    # Redémarrer le dock pour appliquer les changements
    killall Dock
    
    echo "✅ Apparence du dock configurée avec succès"
    return 0
}

# Exemple d'utilisation
# configure_dock_appearance 64 true false bottom

Système de Gestion d'Entreprise du Dock

#!/bin/bash

# Système de Gestion d'Entreprise du Dock Roundfleet
# Personnalisation d'interface complète, optimisation de productivité et déploiement à l'échelle de la flotte

# Configuration
LOG_FILE="/var/log/roundfleet_dock_management.log"
CONFIG_DIR="/etc/roundfleet/dock_management"
POLICIES_DIR="$CONFIG_DIR/policies"
TEMPLATES_DIR="$CONFIG_DIR/templates"
PROFILES_DIR="$CONFIG_DIR/profiles"
REPORTS_DIR="$CONFIG_DIR/reports"
BACKUP_DIR="$CONFIG_DIR/backups"
COMPLIANCE_DIR="$CONFIG_DIR/compliance"
DEPLOYMENT_DIR="$CONFIG_DIR/deployment"

# Modèles de configuration du dock
declare -A DOCK_TEMPLATES=(
    ["developer"]="Xcode,Terminal,Visual Studio Code,GitHub Desktop,Docker,Postman,Simulator,Activity Monitor"
    ["designer"]="Adobe Creative Suite,Figma,Sketch,Affinity Designer,ColorSync Utility,Digital Color Meter,Preview"
    ["business"]="Microsoft Office Suite,Slack,Zoom,Teams,Outlook,OneNote,Salesforce,Tableau"
    ["executive"]="Mail,Calendar,Contacts,Safari,Numbers,Keynote,Pages,Messages,FaceTime"
    ["support"]="Remote Desktop,TeamViewer,Console,Activity Monitor,Network Utility,Disk Utility,Terminal"
    ["education"]="Safari,Mail,Classroom,Pages,Numbers,Keynote,GarageBand,iMovie,Books"
    ["finance"]="Excel,QuickBooks,Sage,TaxAct,Calculator,Numbers,Banking Apps,PDF Expert"
    ["healthcare"]="Epic,Cerner,MEDITECH,DICOM Viewer,Medical Calculator,Secure Messaging,Telemedicine Apps"
)

# Configurations de rôles utilisateur
declare -A USER_ROLES=(
    ["admin"]="developer,support"
    ["power_user"]="business,developer"
    ["standard_user"]="business"
    ["guest"]="executive"
    ["kiosk"]="education"
)

# Préréglages de taille du dock
declare -A DOCK_SIZES=(
    ["small"]="32"
    ["medium"]="48"
    ["large"]="64"
    ["extra_large"]="80"
    ["jumbo"]="128"
)

# Politiques d'entreprise
declare -A ENTERPRISE_POLICIES=(
    ["corporate_standard"]="consistent_layout,security_apps,productivity_focused,compliance_enabled"
    ["byod_friendly"]="user_customizable,personal_apps_allowed,flexible_layout"
    ["kiosk_mode"]="locked_layout,essential_apps_only,no_customization"
    ["developer_optimized"]="development_tools,large_dock,custom_shortcuts"
    ["executive_minimal"]="essential_apps,clean_interface,quick_access"
)

# Optimisations de productivité
declare -A PRODUCTIVITY_FEATURES=(
    ["hot_corners"]="mission_control,desktop,dashboard,screen_saver"
    ["gestures"]="swipe_navigation,expose,spaces"
    ["shortcuts"]="application_switching,dock_navigation,quick_launch"
    ["organization"]="folder_stacks,recent_items,favorites"
)

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

# Configuration des répertoires
setup_directories() {
    for dir in "$CONFIG_DIR" "$POLICIES_DIR" "$TEMPLATES_DIR" "$PROFILES_DIR" "$REPORTS_DIR" "$BACKUP_DIR" "$COMPLIANCE_DIR" "$DEPLOYMENT_DIR"; do
        if [[ ! -d "$dir" ]]; then
            mkdir -p "$dir"
            log_action "Répertoire créé: $dir"
        fi
    done
}

# Installer les dépendances de gestion du dock
install_dock_dependencies() {
    echo "🔧 Installation des Dépendances de Gestion du Dock"
    
    local dockutil_version="3.0.2"
    local dockutil_pkg="/tmp/dockutil-${dockutil_version}.pkg"
    
    # Vérifier si dockutil est déjà installé
    if command -v dockutil &>/dev/null; then
        echo "✅ dockutil déjà installé"
        return 0
    fi
    
    # Télécharger et installer dockutil
    echo "📥 Téléchargement de dockutil ${dockutil_version}..."
    if curl -sL "https://github.com/kcrawford/dockutil/releases/download/${dockutil_version}/dockutil-${dockutil_version}.pkg" -o "$dockutil_pkg"; then
        echo "📦 Installation de dockutil..."
        if sudo installer -pkg "$dockutil_pkg" -target /; then
            echo "✅ dockutil installé avec succès"
            rm -f "$dockutil_pkg"
        else
            echo "❌ Échec de l'installation de dockutil"
            return 1
        fi
    else
        echo "❌ Échec du téléchargement de dockutil"
        return 1
    fi
    
    # Installer des outils de productivité supplémentaires
    install_productivity_tools
    
    return 0
}

# Créer une configuration de dock à partir d'un modèle
create_dock_from_template() {
    local template_name="$1"
    local username="$2"
    local customize_options="$3"
    
    log_action "Création de la configuration du dock à partir du modèle: $template_name pour l'utilisateur: $username"
    
    local template_apps="${DOCK_TEMPLATES[$template_name]}"
    if [[ -z "$template_apps" ]]; then
        log_action "❌ Modèle de dock inconnu: $template_name"
        return 1
    fi
    
    local logged_user=$(stat -f%Su /dev/console)
    local target_user="${username:-$logged_user}"
    
    if [[ -z "$target_user" || "$target_user" == "root" ]]; then
        log_action "❌ Utilisateur cible invalide: $target_user"
        return 1
    fi
    
    echo "🎨 Création de la configuration du dock à partir du modèle: $template_name"
    echo "Utilisateur cible: $target_user"
    
    # Sauvegarder la configuration actuelle du dock
    backup_dock_configuration "$target_user"
    
    # Analyser les applications du modèle
    IFS=',' read -ra TEMPLATE_APPS <<< "$template_apps"
    
    # Vider le dock actuel
    sudo su "$target_user" -c "defaults write com.apple.dock persistent-apps -array"
    
    # Ajouter les applications du modèle
    for app_name in "${TEMPLATE_APPS[@]}"; do
        add_application_to_dock "$app_name" "$target_user"
    done
    
    # Appliquer les options de personnalisation
    if [[ -n "$customize_options" ]]; then
        apply_dock_customizations "$customize_options" "$target_user"
    fi
    
    # Sauvegarder la configuration du modèle
    save_dock_template_config "$template_name" "$target_user"
    
    # Redémarrer le dock
    killall Dock
    
    log_action "✅ Configuration du dock créée à partir du modèle: $template_name"
    return 0
}

# Ajouter une application au dock intelligemment
add_application_to_dock() {
    local app_name="$1"
    local username="$2"
    
    # Mappage des chemins d'applications
    local app_paths=(
        "/Applications/${app_name}.app"
        "/System/Applications/${app_name}.app"
        "/Applications/Utilities/${app_name}.app"
        "/Applications/Microsoft Office 2011/${app_name}.app"
        "/Applications/Adobe Creative Suite/${app_name}.app"
        "/Applications/Google Chrome.app"
        "/Applications/Microsoft Outlook.app"
        "/Applications/Microsoft Word.app"
        "/Applications/Microsoft Excel.app"
        "/Applications/Microsoft PowerPoint.app"
        "/Applications/Slack.app"
        "/Applications/Zoom.app"
        "/Applications/Figma.app"
        "/Applications/Visual Studio Code.app"
        "/Applications/Xcode.app"
    )
    
    # Trouver le chemin de l'application
    local app_path=""
    for path in "${app_paths[@]}"; do
        if [[ -d "$path" ]]; then
            app_path="$path"
            break
        fi
    done
    
    # Gérer les noms d'applications spéciaux
    case "$app_name" in
        "Microsoft Office Suite")
            add_application_to_dock "Microsoft Word" "$username"
            add_application_to_dock "Microsoft Excel" "$username"
            add_application_to_dock "Microsoft PowerPoint" "$username"
            add_application_to_dock "Microsoft Outlook" "$username"
            return 0
            ;;
        "Adobe Creative Suite")
            add_application_to_dock "Adobe Photoshop" "$username"
            add_application_to_dock "Adobe Illustrator" "$username"
            add_application_to_dock "Adobe InDesign" "$username"
            return 0
            ;;
        "Terminal")
            app_path="/System/Applications/Utilities/Terminal.app"
            ;;
        "Activity Monitor")
            app_path="/System/Applications/Utilities/Activity Monitor.app"
            ;;
        "System Preferences")
            app_path="/System/Applications/System Preferences.app"
            ;;
    esac
    
    if [[ -n "$app_path" && -d "$app_path" ]]; then
        # Utiliser dockutil si disponible
        if command -v dockutil &>/dev/null; then
            dockutil --add "$app_path" --allhomes 2>/dev/null
            echo "✅ Ajouté au dock: $app_name"
        else
            # Solution de rechange avec la commande defaults
            local dock_entry="<dict><key>tile-data</key><dict><key>file-data</key><dict><key>_CFURLString</key><string>$app_path</string><key>_CFURLStringType</key><integer>0</integer></dict></dict></dict>"
            sudo su "$username" -c "defaults write com.apple.dock persistent-apps -array-add '$dock_entry'"
            echo "✅ Ajouté au dock: $app_name"
        fi
    else
        echo "⚠️  Application non trouvée: $app_name"
    fi
}

# Surveiller la conformité du dock
monitor_dock_compliance() {
    log_action "Démarrage de la surveillance de conformité du dock"
    
    local compliance_report="$COMPLIANCE_DIR/dock_compliance_$(date '+%Y%m%d_%H%M%S').json"
    local logged_user=$(stat -f%Su /dev/console)
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "logged_user": "$logged_user",
        "monitor_type": "dock_compliance"
    },
    "dock_assessment": {
        "current_configuration": $(get_current_dock_config "$logged_user"),
        "policy_compliance": $(assess_policy_compliance "$logged_user"),
        "security_compliance": $(assess_dock_security "$logged_user"),
        "productivity_metrics": $(calculate_productivity_metrics "$logged_user")
    },
    "compliance_status": {
        "overall_score": $(calculate_compliance_score),
        "violations": $(detect_policy_violations "$logged_user"),
        "recommendations": $(generate_compliance_recommendations),
        "remediation_actions": $(generate_remediation_actions)
    }
}
EOF

    log_action "✅ Surveillance de conformité du dock terminée: $compliance_report"
    echo "$compliance_report"
}

# Optimiser le dock pour la productivité
optimize_dock_productivity() {
    local optimization_level="$1"
    local username="$2"
    local role="$3"
    
    log_action "Optimisation du dock pour la productivité: niveau=$optimization_level, utilisateur=$username, rôle=$role"
    
    local logged_user=$(stat -f%Su /dev/console)
    local target_user="${username:-$logged_user}"
    
    echo "🚀 Optimisation du Dock pour la Productivité"
    echo "Niveau d'optimisation: $optimization_level"
    echo "Utilisateur cible: $target_user"
    echo "Rôle utilisateur: $role"
    
    case "$optimization_level" in
        "basic")
            apply_basic_productivity_optimizations "$target_user" "$role"
            ;;
        "advanced")
            apply_advanced_productivity_optimizations "$target_user" "$role"
            ;;
        "expert")
            apply_expert_productivity_optimizations "$target_user" "$role"
            ;;
        *)
            log_action "⚠️  Niveau d'optimisation inconnu: $optimization_level"
            return 1
            ;;
    esac
    
    # Configurer les coins actifs pour la productivité
    configure_hot_corners "$target_user"
    
    # Configurer les raccourcis du dock
    configure_dock_shortcuts "$target_user"
    
    # Appliquer les optimisations spécifiques au rôle
    apply_role_specific_optimizations "$role" "$target_user"
    
    # Redémarrer le dock
    killall Dock
    
    log_action "✅ Optimisation de la productivité du dock terminée"
    return 0
}

# Fonction d'exécution principale
main() {
    local action="${1:-status}"
    local parameter="$2"
    local additional_param="$3"
    local extra_param="$4"
    
    log_action "=== Gestion du Dock Roundfleet Démarrée ==="
    log_action "Action: $action"
    log_action "Paramètre: ${parameter:-N/A}"
    
    setup_directories
    
    case "$action" in
        "install")
            install_dock_dependencies
            ;;
        "template")
            if [[ -z "$parameter" ]]; then
                echo "Modèles de dock disponibles:"
                for template in "${!DOCK_TEMPLATES[@]}"; do
                    echo "  - $template: ${DOCK_TEMPLATES[$template]}"
                done
                echo ""
                echo "Usage: $0 template <nom_modèle> [nom_utilisateur] [personnalisations]"
                exit 1
            fi
            create_dock_from_template "$parameter" "$additional_param" "$extra_param"
            ;;
        "optimize")
            if [[ -z "$parameter" ]]; then
                echo "Niveaux d'optimisation: basic, advanced, expert"
                echo "Rôles utilisateur: ${!USER_ROLES[*]}"
                echo ""
                echo "Usage: $0 optimize <niveau> [nom_utilisateur] [rôle]"
                exit 1
            fi
            optimize_dock_productivity "$parameter" "$additional_param" "$extra_param"
            ;;
        "monitor")
            monitor_dock_compliance
            ;;
        "reset")
            reset_dock_default
            ;;
        "appearance")
            if [[ -z "$parameter" ]]; then
                echo "Tailles de dock disponibles: ${!DOCK_SIZES[*]}"
                echo ""
                echo "Usage: $0 appearance <taille> [agrandissement] [masquage_auto] [position]"
                echo "Exemple: $0 appearance medium true false bottom"
                exit 1
            fi
            local size="${DOCK_SIZES[$parameter]:-$parameter}"
            configure_dock_appearance "$size" "$additional_param" "$extra_param" "${5:-bottom}"
            ;;
        *)
            echo "Usage: $0 {install|template|optimize|monitor|reset|appearance}"
            echo "  install     - Installer les dépendances de gestion du dock"
            echo "  template    - Appliquer la configuration du dock à partir d'un modèle"
            echo "  optimize    - Optimiser le dock pour la productivité"
            echo "  monitor     - Surveiller la conformité du dock"
            echo "  reset       - Réinitialiser le dock à l'état par défaut"
            echo "  appearance  - Configurer l'apparence visuelle du dock"
            exit 1
            ;;
    esac
    
    log_action "=== Opération de gestion du dock terminée ==="
}

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

Fonctionnalités Avancées de Gestion du Dock

Organisation Intelligente des Applications

#!/bin/bash

# Organisation intelligente des applications basée sur les modèles d'utilisation
smart_dock_organization() {
    local username="$1"
    local analysis_period="${2:-30}"  # jours
    
    echo "🧠 Organisation Intelligente du Dock"
    echo "Analyse des modèles d'utilisation pour $analysis_period jours"
    
    local usage_data="$REPORTS_DIR/app_usage_${username}.json"
    
    # Analyser l'utilisation des applications
    cat > "$usage_data" << EOF
{
    "analysis_period": $analysis_period,
    "usage_patterns": $(analyze_app_usage "$username" "$analysis_period"),
    "frequency_ranking": $(rank_apps_by_frequency "$username"),
    "time_based_usage": $(analyze_time_based_usage "$username"),
    "productivity_score": $(calculate_app_productivity_score "$username")
}
EOF

    # Réorganiser le dock basé sur les modèles d'utilisation
    reorganize_dock_by_usage "$username" "$usage_data"
    
    echo "✅ Organisation intelligente du dock terminée"
}

# Adaptation dynamique du dock
dynamic_dock_adaptation() {
    echo "🔄 Adaptation Dynamique du Dock"
    
    local adaptation_script="$DEPLOYMENT_DIR/dynamic_adaptation.sh"
    
    cat > "$adaptation_script" << 'EOF'
#!/bin/bash

# Adaptation dynamique du dock basée sur le contexte

while true; do
    CURRENT_HOUR=$(date +%H)
    CURRENT_USER=$(stat -f%Su /dev/console)
    
    # Adapter le dock selon l'heure de la journée
    if [[ $CURRENT_HOUR -ge 9 && $CURRENT_HOUR -le 17 ]]; then
        # Heures de bureau - focus productivité
        apply_business_hours_dock "$CURRENT_USER"
    elif [[ $CURRENT_HOUR -ge 18 && $CURRENT_HOUR -le 22 ]]; then
        # Soirée - travail créatif/personnel
        apply_evening_dock "$CURRENT_USER"
    else
        # Heures creuses - dock minimal
        apply_minimal_dock "$CURRENT_USER"
    fi
    
    # Vérifier toutes les 30 minutes
    sleep 1800
done
EOF

    chmod +x "$adaptation_script"
    echo "🤖 Script d'adaptation dynamique créé"
}

Fonctionnalités d'Intégration d'Entreprise

🔗 Intégration Système

  • Intégration Active Directory avec mappage des rôles utilisateur
  • Authentification LDAP pour l'attribution de politiques de dock
  • Intégration de gestion de configuration (Puppet, Ansible, Chef)
  • Synchronisation de politiques MDM (Mobile Device Management)

📱 Gestion de Flotte

  • Déploiement centralisé sur des milliers d'appareils
  • Héritage de politiques avec mappage d'unités organisationnelles
  • Mises à jour de configuration en lot avec capacités de rollback
  • Surveillance de santé avec vérification automatisée de conformité

🎯 Optimisation de l'Expérience Utilisateur

  • Adaptation contextuelle basée sur l'heure, la localisation, le rôle
  • Insights d'apprentissage automatique pour des recommandations personnalisées
  • Analytics de productivité avec insights actionnables
  • Tests A/B pour l'efficacité de la configuration du dock

🛡️ Sécurité et Conformité

  • Application de politiques avec protection contre la falsification
  • Intégration d'applications de sécurité dans les configurations de dock
  • Rapports de conformité pour les exigences réglementaires
  • Pistes d'audit pour toutes les modifications du dock

Notes Importantes

  • Permissions utilisateur requises pour les modifications du dock à l'échelle de l'entreprise
  • Considérations de licence d'application pour les modèles de dock d'entreprise
  • Impact sur les performances minimal avec stratégies de déploiement optimisées
  • Stratégies de sauvegarde essentielles avant les reconfigurations majeures du dock
  • Formation utilisateur importante pour l'adoption de l'optimisation de productivité
  • Surveillance régulière nécessaire pour maintenir la conformité et l'efficacité du dock

Configuration des paramètres DNS pour le Wi-Fi sur Mac

Le système de nom de domaine (DNS) est l'épine dorsale d'Internet, convertissant les noms de domaine lisibles par l'homme en adresses IP qui permettent une communication transparente entre les appareils. Une configuration DNS appropriée peut impacter significativement votre expérience Internet, affectant la vitesse, la sécurité et la confidentialité. Ce guide complet fournit des méthodes pour configurer les paramètres DNS pour le Wi-Fi sur les appareils macOS.

Comprendre le DNS et son importance

Les serveurs DNS agissent comme des traducteurs entre les noms de domaine (comme google.com) et les adresses IP (comme 142.250.80.14). Lorsque vous tapez une adresse web, votre appareil interroge un serveur DNS pour trouver l'adresse IP correspondante, puis se connecte à ce serveur.

Pourquoi changer les paramètres DNS ?

Il y a plusieurs raisons convaincantes de modifier votre configuration DNS :

  • Performance améliorée : Des serveurs DNS plus rapides peuvent réduire les temps de chargement des sites web
  • Sécurité renforcée : Le filtrage DNS peut bloquer les sites web malveillants et les tentatives de phishing
  • Protection de la vie privée : Certains fournisseurs DNS n'enregistrent pas vos activités de navigation
  • Accès au contenu : Contourner les restrictions géographiques et la censure
  • Contrôle parental : Filtrer le contenu inapproprié pour les réseaux familiaux
  • Blocage des publicités : Certains services DNS bloquent les publicités au niveau DNS

Fournisseurs DNS populaires

Avant de configurer les paramètres DNS, considérez ces fournisseurs DNS populaires :

Google Public DNS

  • Primaire : 8.8.8.8
  • Secondaire : 8.8.4.4
  • Caractéristiques : Rapide, fiable, journalisation minimale

Cloudflare DNS

  • Primaire : 1.1.1.1
  • Secondaire : 1.0.0.1
  • Caractéristiques : Axé sur la confidentialité, très rapide, fonctionnalités de sécurité

OpenDNS

  • Primaire : 208.67.222.222
  • Secondaire : 208.67.220.220
  • Caractéristiques : Filtrage de contenu, protection contre les malwares

Quad9

  • Primaire : 9.9.9.9
  • Secondaire : 149.112.112.112
  • Caractéristiques : Axé sur la sécurité, bloque les domaines malveillants

Prérequis

Avant de configurer les paramètres DNS, assurez-vous d'avoir :

  • Privilèges administrateur sur le Mac
  • Accès au Terminal ou aux Préférences Système
  • Connaissance de votre configuration réseau actuelle
  • Sauvegarde des paramètres DNS actuels (optionnel mais recommandé)

Méthode 1 : Utilisation de scripts shell

Script de configuration DNS de base

Ce script configure les paramètres de serveur DNS pour le Wi-Fi sur macOS :

#!/bin/bash

# Configurer les serveurs DNS pour le Wi-Fi
sudo networksetup -setdnsservers "Wi-Fi" 8.8.8.8 8.8.4.4

# Vérifier la configuration
output=$(networksetup -getdnsservers "Wi-Fi")
echo "Serveurs DNS actuels: $output"

# Vider le cache DNS
sudo dscacheutil -flushcache
echo "Cache DNS vidé"

Script de configuration DNS avancé

Un script plus complet avec plusieurs options DNS :

#!/bin/bash

# Script de configuration DNS avancé pour macOS Wi-Fi
# Usage: ./dns_config.sh [fournisseur]
# Fournisseurs: google, cloudflare, opendns, quad9, reset

PROVIDER=${1:-google}
INTERFACE="Wi-Fi"

# Fonction pour définir les serveurs DNS
set_dns_servers() {
    local primary=$1
    local secondary=$2
    local provider_name=$3
    
    echo "Configuration des serveurs DNS vers $provider_name..."
    sudo networksetup -setdnsservers "$INTERFACE" "$primary" "$secondary"
    
    # Vérifier la configuration
    current_dns=$(networksetup -getdnsservers "$INTERFACE")
    echo "Serveurs DNS actuels: $current_dns"
    
    # Vider le cache DNS
    sudo dscacheutil -flushcache
    echo "Cache DNS vidé"
    
    # Tester la résolution DNS
    echo "Test de résolution DNS..."
    nslookup google.com "$primary" | head -5
}

# Fonction pour réinitialiser vers DNS automatique
reset_dns() {
    echo "Réinitialisation DNS vers automatique (DHCP)..."
    sudo networksetup -setdnsservers "$INTERFACE" "Empty"
    current_dns=$(networksetup -getdnsservers "$INTERFACE")
    echo "Serveurs DNS actuels: $current_dns"
}

# Logique de configuration principale
case $PROVIDER in
    google)
        set_dns_servers "8.8.8.8" "8.8.4.4" "Google Public DNS"
        ;;
    cloudflare)
        set_dns_servers "1.1.1.1" "1.0.0.1" "Cloudflare DNS"
        ;;
    opendns)
        set_dns_servers "208.67.222.222" "208.67.220.220" "OpenDNS"
        ;;
    quad9)
        set_dns_servers "9.9.9.9" "149.112.112.112" "Quad9"
        ;;
    reset)
        reset_dns
        ;;
    *)
        echo "Usage: $0 [google|cloudflare|opendns|quad9|reset]"
        echo "Par défaut: google"
        exit 1
        ;;
esac

echo "Configuration DNS terminée!"

Configuration DNS par lot pour plusieurs Mac

Pour gérer les paramètres DNS sur plusieurs appareils Mac :

#!/bin/bash

# Configuration DNS par lot pour plusieurs Mac
HOSTS=(
    "mac1.local"
    "mac2.local"
    "mac3.local"
)

DNS_PRIMARY="1.1.1.1"
DNS_SECONDARY="1.0.0.1"
INTERFACE="Wi-Fi"

echo "Configuration DNS sur plusieurs Mac..."
echo "DNS primaire: $DNS_PRIMARY"
echo "DNS secondaire: $DNS_SECONDARY"
echo ""

for host in "${HOSTS[@]}"; do
    echo "Configuration de $host..."
    
    if ping -c 1 -W 1000 "$host" >/dev/null 2>&1; then
        # Créer un script à exécuter sur l'hôte distant
        remote_script="sudo networksetup -setdnsservers '$INTERFACE' '$DNS_PRIMARY' '$DNS_SECONDARY' && sudo dscacheutil -flushcache"
        
        if ssh -o ConnectTimeout=5 -o BatchMode=yes "$host" "$remote_script" 2>/dev/null; then
            echo "  ✓ $host - DNS configuré avec succès"
        else
            echo "  ✗ $host - Échec de la configuration DNS"
        fi
    else
        echo "  ✗ $host - Hôte inaccessible"
    fi
done

echo ""
echo "Configuration DNS par lot terminée!"

Méthode 2 : Configuration manuelle via les Préférences Système

Configuration GUI étape par étape

  1. Ouvrir les Préférences Système

    • Cliquer sur le menu Apple > Préférences Système
    • Ou utiliser Spotlight : Presser Cmd+Espace, taper "Préférences Système"
  2. Accéder aux paramètres réseau

    • Cliquer sur "Réseau"
    • Sélectionner "Wi-Fi" dans la barre latérale gauche
    • Cliquer sur le bouton "Avancé..."
  3. Configurer DNS

    • Cliquer sur l'onglet "DNS"
    • Cliquer sur le bouton "+" pour ajouter des serveurs DNS
    • Entrer vos serveurs DNS préférés (ex: 1.1.1.1, 1.0.0.1)
    • Faire glisser les serveurs pour les réorganiser par priorité
  4. Appliquer les paramètres

    • Cliquer sur "OK" pour fermer la fenêtre Avancé
    • Cliquer sur "Appliquer" pour sauvegarder les changements

Vérification en ligne de commande

Après la configuration manuelle, vérifiez les paramètres en utilisant Terminal :

# Vérifier les serveurs DNS actuels
networksetup -getdnsservers "Wi-Fi"

# Tester la résolution DNS
nslookup google.com
dig google.com

# Vérifier le temps de réponse DNS
time nslookup google.com

Scripts de gestion DNS

Script d'information DNS actuel

Script pour recueillir des informations DNS complètes :

#!/bin/bash

# Script de collecte d'informations DNS
echo "Rapport de configuration DNS"
echo "============================"
echo "Date: $(date)"
echo "Nom d'hôte: $(hostname)"
echo ""

# Obtenir toutes les interfaces réseau
interfaces=$(networksetup -listallnetworkservices | grep -v "denotes")

echo "Interfaces réseau et paramètres DNS:"
echo "-----------------------------------"

while IFS= read -r interface; do
    if [[ "$interface" != "" ]]; then
        echo "Interface: $interface"
        dns_servers=$(networksetup -getdnsservers "$interface")
        
        if [[ "$dns_servers" == "There aren't any DNS Servers set on"* ]]; then
            echo "  DNS: Automatique (DHCP)"
        else
            echo "  Serveurs DNS:"
            echo "$dns_servers" | while read -r server; do
                echo "    - $server"
            done
        fi
        echo ""
    fi
done <<< "$interfaces"

# Tester les performances de résolution DNS
echo "Test de résolution DNS:"
echo "----------------------"
test_domains=("google.com" "cloudflare.com" "github.com")

for domain in "${test_domains[@]}"; do
    echo "Test de $domain..."
    time_result=$(time (nslookup "$domain" >/dev/null 2>&1) 2>&1 | grep real | awk '{print $2}')
    echo "  Temps de résolution: $time_result"
done

Script de sauvegarde et restauration DNS

#!/bin/bash

# Script de sauvegarde et restauration DNS
BACKUP_DIR="$HOME/dns_backups"
BACKUP_FILE="$BACKUP_DIR/dns_backup_$(date +%Y%m%d_%H%M%S).txt"

# Créer le répertoire de sauvegarde
mkdir -p "$BACKUP_DIR"

# Fonction pour sauvegarder les paramètres DNS
backup_dns() {
    echo "Sauvegarde des paramètres DNS..."
    
    {
        echo "Sauvegarde DNS - $(date)"
        echo "======================="
        echo ""
        
        # Obtenir toutes les interfaces réseau
        interfaces=$(networksetup -listallnetworkservices | grep -v "denotes")
        
        while IFS= read -r interface; do
            if [[ "$interface" != "" ]]; then
                echo "Interface: $interface"
                networksetup -getdnsservers "$interface"
                echo ""
            fi
        done <<< "$interfaces"
        
    } > "$BACKUP_FILE"
    
    echo "Paramètres DNS sauvegardés dans: $BACKUP_FILE"
}

# Fonction pour restaurer les paramètres DNS
restore_dns() {
    local backup_file=$1
    
    if [[ ! -f "$backup_file" ]]; then
        echo "Fichier de sauvegarde introuvable: $backup_file"
        return 1
    fi
    
    echo "Restauration des paramètres DNS depuis: $backup_file"
    echo "Note: Restauration manuelle requise - le fichier de sauvegarde contient la configuration pour référence"
    cat "$backup_file"
}

# Logique principale du script
case "${1:-backup}" in
    backup)
        backup_dns
        ;;
    restore)
        restore_dns "$2"
        ;;
    list)
        echo "Sauvegardes disponibles:"
        ls -la "$BACKUP_DIR"
        ;;
    *)
        echo "Usage: $0 [backup|restore <fichier>|list]"
        exit 1
        ;;
esac

Dépannage des problèmes DNS

Problèmes DNS courants et solutions

  1. Navigation Internet lente

    # Tester les temps de réponse DNS
    time nslookup google.com 8.8.8.8
    time nslookup google.com 1.1.1.1
    
    # Passer à un serveur DNS plus rapide
    sudo networksetup -setdnsservers "Wi-Fi" 1.1.1.1 1.0.0.1
  2. Impossible d'accéder à certains sites web

    # Vérifier si le DNS résout le domaine
    nslookup site-problematique.com
    
    # Essayer un serveur DNS différent
    nslookup site-problematique.com 8.8.8.8
  3. Problèmes de cache DNS

    # Vider le cache DNS
    sudo dscacheutil -flushcache
    sudo killall -HUP mDNSResponder

Script de diagnostic DNS

#!/bin/bash

# Script de diagnostic DNS
echo "Rapport de diagnostic DNS"
echo "========================"
echo "Date: $(date)"
echo ""

# Vérifier la configuration DNS actuelle
echo "1. Configuration DNS actuelle:"
echo "-----------------------------"
networksetup -getdnsservers "Wi-Fi"
echo ""

# Tester la connectivité aux serveurs DNS courants
echo "2. Test de connectivité aux serveurs DNS:"
echo "----------------------------------------"
dns_servers=("8.8.8.8" "1.1.1.1" "208.67.222.222" "9.9.9.9")

for server in "${dns_servers[@]}"; do
    if ping -c 1 -W 1000 "$server" >/dev/null 2>&1; then
        echo "✓ $server - Accessible"
    else
        echo "✗ $server - Inaccessible"
    fi
done
echo ""

# Tester la résolution DNS
echo "3. Test de résolution DNS:"
echo "-------------------------"
test_domains=("google.com" "cloudflare.com" "github.com")

for domain in "${test_domains[@]}"; do
    if nslookup "$domain" >/dev/null 2>&1; then
        echo "✓ $domain - Résolu correctement"
    else
        echo "✗ $domain - Échec de résolution"
    fi
done
echo ""

# Vérifier les fuites DNS
echo "4. Vérification des fuites DNS:"
echo "-------------------------------"
echo "Résolveur DNS actuel:"
nslookup myip.opendns.com resolver1.opendns.com | grep "Address" | tail -1
echo ""

echo "Diagnostic terminé!"

Bonnes pratiques pour la configuration DNS

1. Considérations de sécurité

  • Utiliser des fournisseurs DNS réputés avec des fonctionnalités de sécurité
  • Mettre à jour régulièrement les paramètres DNS basés sur la veille des menaces
  • Considérer DNS-over-HTTPS (DoH) pour une confidentialité renforcée
  • Surveiller les requêtes DNS pour détecter les activités suspectes

2. Optimisation des performances

  • Tester plusieurs fournisseurs DNS pour trouver le plus rapide pour votre localisation
  • Utiliser des serveurs DNS primaires et secondaires pour la redondance
  • Considérer la proximité géographique lors de la sélection des serveurs DNS
  • Surveiller régulièrement les temps de résolution DNS

3. Gestion d'entreprise

  • Standardiser les paramètres DNS sur tous les appareils organisationnels
  • Documenter les configurations DNS pour la récupération après sinistre
  • Implémenter le filtrage DNS pour la sécurité et la conformité
  • Utiliser des scripts automatisés pour les changements de configuration en masse

4. Sauvegarde et récupération

  • Toujours sauvegarder les paramètres DNS actuels avant de faire des changements
  • Tester les nouvelles configurations DNS dans un environnement contrôlé
  • Avoir un plan de retour en arrière pour les changements DNS
  • Documenter tous les changements de configuration DNS

Configuration DNS avancée

Configuration DNS-over-HTTPS (DoH)

Pour une confidentialité renforcée, configurez DNS-over-HTTPS :

#!/bin/bash

# Configurer DNS-over-HTTPS (DoH) sur macOS
# Note: Cela nécessite macOS 11.0 ou ultérieur

# Activer DoH avec Cloudflare
sudo networksetup -setdnsservers "Wi-Fi" 1.1.1.1 1.0.0.1
sudo defaults write /Library/Preferences/com.apple.networkd.plist DoHServers -dict-add "1.1.1.1" "https://cloudflare-dns.com/dns-query"
sudo defaults write /Library/Preferences/com.apple.networkd.plist DoHServers -dict-add "1.0.0.1" "https://cloudflare-dns.com/dns-query"

# Redémarrer les services réseau
sudo launchctl unload /System/Library/LaunchDaemons/com.apple.networkd.plist
sudo launchctl load /System/Library/LaunchDaemons/com.apple.networkd.plist

echo "DNS-over-HTTPS configuré avec Cloudflare"

Configuration DNS personnalisée pour des domaines spécifiques

#!/bin/bash

# Configurer DNS personnalisé pour des domaines spécifiques
# Utilise /etc/resolver pour DNS spécifique au domaine

# Créer le répertoire resolver
sudo mkdir -p /etc/resolver

# Configurer un domaine spécifique pour utiliser DNS personnalisé
echo "nameserver 8.8.8.8" | sudo tee /etc/resolver/entreprise.local
echo "nameserver 8.8.4.4" | sudo tee -a /etc/resolver/entreprise.local

# Vider le cache DNS
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

echo "DNS personnalisé configuré pour le domaine entreprise.local"

Surveillance et maintenance

Script de surveillance DNS

#!/bin/bash

# Script de surveillance DNS
LOG_FILE="/var/log/dns_monitor.log"

# Fonction pour enregistrer avec horodatage
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Surveiller les performances DNS
monitor_dns() {
    local dns_server=$1
    local test_domain=$2
    
    start_time=$(date +%s%N)
    if nslookup "$test_domain" "$dns_server" >/dev/null 2>&1; then
        end_time=$(date +%s%N)
        duration=$((($end_time - $start_time) / 1000000))
        log_message "DNS $dns_server: $test_domain résolu en ${duration}ms"
    else
        log_message "DNS $dns_server: Échec de résolution de $test_domain"
    fi
}

# Surveiller plusieurs serveurs DNS
dns_servers=("8.8.8.8" "1.1.1.1" "208.67.222.222")
test_domain="google.com"

log_message "Début de la surveillance DNS"

for server in "${dns_servers[@]}"; do
    monitor_dns "$server" "$test_domain"
done

log_message "Surveillance DNS terminée"

Conclusion

Une configuration DNS appropriée est cruciale pour des performances Internet optimales, la sécurité et la confidentialité. Les scripts et méthodes fournis dans ce guide offrent des solutions complètes pour gérer les paramètres DNS sur les appareils macOS, des configurations simples aux déploiements d'entreprise avancés.

Points clés à retenir :

  • Choisir des fournisseurs DNS qui s'alignent sur vos exigences de performance et de confidentialité
  • Tester et surveiller régulièrement les performances DNS
  • Implémenter des procédures de sauvegarde et de récupération appropriées
  • Considérer les implications de sécurité de la configuration DNS
  • Utiliser l'automatisation pour les déploiements à grande échelle

N'oubliez pas de tester tous les changements DNS dans un environnement contrôlé avant de les déployer sur votre flotte Mac. Une gestion DNS appropriée peut considérablement améliorer votre expérience réseau tout en renforçant la sécurité et la confidentialité.

Gestion de la Luminosité d'Écran et Optimisation Énergétique sur macOS

Gérez la luminosité d'affichage et la consommation d'énergie sur vos appareils Roundfleet avec un contrôle complet de la luminosité, des politiques d'éclairage adaptatif et des outils d'optimisation énergétique d'entreprise. Ce tutoriel couvre l'ajustement de luminosité, la planification automatisée et la gestion d'affichage à l'échelle de la flotte.

Comprendre la Gestion de la Luminosité d'Affichage

Le contrôle de la luminosité d'affichage sur macOS affecte à la fois l'expérience utilisateur et la consommation d'énergie. La gestion d'entreprise inclut :

  • Contrôle de Luminosité - Ajustement direct des niveaux de luminosité d'affichage
  • Éclairage Adaptatif - Ajustement automatique basé sur l'environnement et l'heure
  • Optimisation Énergétique - Conservation de batterie grâce à la gestion intelligente d'affichage
  • Expérience Utilisateur - Paramètres d'affichage cohérents sur les appareils d'entreprise

Avantages d'Entreprise

Une gestion appropriée de la luminosité d'affichage offre des avantages d'entreprise :

  • Conservation d'Énergie - Réduction de la consommation d'énergie et prolongation de la durée de vie de la batterie
  • Confort Utilisateur - Conditions de visualisation optimales pour différents environnements de travail
  • Amélioration de Sécurité - Affichages atténués dans les espaces publics pour la confidentialité
  • Bénéfices Santé - Réduction de la fatigue oculaire grâce à un éclairage approprié
  • Standardisation - Expérience d'affichage cohérente sur toute la flotte d'appareils

Contrôle de Luminosité de Base

Prérequis et Configuration

#!/bin/bash

# Installer Homebrew et l'outil de contrôle de luminosité
install_brightness_tools() {
    echo "=== Installation des Outils de Contrôle de Luminosité ==="
    
    # Vérifier si Homebrew est installé
    if ! command -v brew >/dev/null 2>&1; then
        echo "Installation de Homebrew..."
        /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
        
        # Ajouter Homebrew au PATH pour la session actuelle
        eval "$(/opt/homebrew/bin/brew shellenv)" 2>/dev/null || eval "$(/usr/local/bin/brew shellenv)" 2>/dev/null
    else
        echo "✓ Homebrew déjà installé"
    fi
    
    # Installer l'outil de contrôle de luminosité
    if ! command -v brightness >/dev/null 2>&1; then
        echo "Installation de l'outil de contrôle de luminosité..."
        brew install brightness
    else
        echo "✓ Outil de luminosité déjà installé"
    fi
    
    echo "✓ Installation des outils de contrôle de luminosité terminée"
}

# Usage
install_brightness_tools

Commandes de Luminosité de Base

#!/bin/bash

# Définir la luminosité à des niveaux spécifiques
set_brightness() {
    local level="$1"
    
    if [[ -z "$level" ]]; then
        echo "Usage : set_brightness <niveau>"
        echo "Le niveau doit être entre 0.0 (sombre) et 1.0 (plus lumineux)"
        return 1
    fi
    
    # Valider le niveau de luminosité
    if ! [[ "$level" =~ ^[0-9]*\.?[0-9]+$ ]] || (( $(echo "$level > 1.0" | bc -l) )) || (( $(echo "$level < 0.0" | bc -l) )); then
        echo "Erreur : Le niveau de luminosité doit être entre 0.0 et 1.0"
        return 1
    fi
    
    echo "Définition de la luminosité à ${level} ($(echo "$level * 100" | bc)%)"
    
    # Essayer différents emplacements de commande de luminosité
    if command -v brightness >/dev/null 2>&1; then
        brightness "$level"
    elif [[ -x "/usr/local/bin/brightness" ]]; then
        /usr/local/bin/brightness "$level"
    elif [[ -x "/opt/homebrew/bin/brightness" ]]; then
        /opt/homebrew/bin/brightness "$level"
    elif [[ -x "/usr/local/Cellar/brightness/1.2/bin/brightness" ]]; then
        /usr/local/Cellar/brightness/1.2/bin/brightness "$level"
    else
        echo "Erreur : Outil de contrôle de luminosité non trouvé"
        return 1
    fi
    
    echo "✓ Luminosité définie à ${level}"
}

# Niveaux de luminosité prédéfinis
set_brightness_full() {
    echo "Définition de la luminosité à 100%"
    set_brightness "1.0"
}

set_brightness_high() {
    echo "Définition de la luminosité à 75%"
    set_brightness "0.75"
}

set_brightness_medium() {
    echo "Définition de la luminosité à 50%"
    set_brightness "0.5"
}

set_brightness_low() {
    echo "Définition de la luminosité à 25%"
    set_brightness "0.25"
}

set_brightness_dim() {
    echo "Définition de la luminosité à 10%"
    set_brightness "0.1"
}

# Exemples d'utilisation
set_brightness_medium

Obtenir le Niveau de Luminosité Actuel

#!/bin/bash

# Obtenir le niveau de luminosité actuel
get_current_brightness() {
    echo "=== Luminosité d'Affichage Actuelle ==="
    
    # Essayer d'obtenir la luminosité en utilisant différentes méthodes
    local current_brightness=""
    
    # Méthode 1 : Utiliser la commande brightness
    if command -v brightness >/dev/null 2>&1; then
        current_brightness=$(brightness -l 2>/dev/null | grep -o '[0-9]*\.[0-9]*' | head -1)
    fi
    
    # Méthode 2 : Utiliser system_profiler (solution de repli)
    if [[ -z "$current_brightness" ]]; then
        current_brightness=$(system_profiler SPDisplaysDataType | grep -i "brightness" | awk '{print $2}' | head -1)
    fi
    
    # Méthode 3 : Utiliser ioreg (solution de repli alternative)
    if [[ -z "$current_brightness" ]]; then
        local brightness_raw=$(ioreg -c AppleBacklightDisplay | grep brightness | head -1)
        if [[ -n "$brightness_raw" ]]; then
            current_brightness=$(echo "$brightness_raw" | grep -o '[0-9]*\.[0-9]*')
        fi
    fi
    
    if [[ -n "$current_brightness" ]]; then
        local percentage=$(echo "$current_brightness * 100" | bc)
        echo "Luminosité Actuelle : $current_brightness (${percentage}%)"
        return 0
    else
        echo "Impossible de déterminer le niveau de luminosité actuel"
        return 1
    fi
}

# Usage
get_current_brightness

Gestion Avancée de la Luminosité

Contrôle de Luminosité Adaptatif

#!/bin/bash

# Luminosité adaptative basée sur l'heure du jour et les conditions
adaptive_brightness_control() {
    local mode="${1:-auto}"
    local location_lat="${2:-}"
    local location_lon="${3:-}"
    
    echo "=== Contrôle de Luminosité Adaptatif ==="
    echo "Mode : $mode"
    echo "Date : $(date)"
    echo ""
    
    case "$mode" in
        "auto")
            automatic_brightness_adjustment
            ;;
        "schedule")
            scheduled_brightness_adjustment
            ;;
        "ambient")
            ambient_light_brightness "$location_lat" "$location_lon"
            ;;
        "work_hours")
            work_hours_brightness
            ;;
        "battery_saver")
            battery_aware_brightness
            ;;
        *)
            echo "Mode inconnu : $mode"
            echo "Modes disponibles : auto, schedule, ambient, work_hours, battery_saver"
            return 1
            ;;
    esac
}

# Ajustement automatique de luminosité basé sur l'heure du jour
automatic_brightness_adjustment() {
    local current_hour=$(date +%H)
    local current_minute=$(date +%M)
    local time_decimal=$(echo "$current_hour + $current_minute / 60" | bc -l)
    
    echo "--- Ajustement Automatique de Luminosité ---"
    echo "Heure actuelle : $current_hour:$(printf "%02d" $current_minute)"
    
    local brightness_level
    
    if (( $(echo "$time_decimal >= 6 && $time_decimal < 9" | bc -l) )); then
        # Matin : Augmentation graduelle
        brightness_level="0.4"
        echo "Période : Matin (6:00-9:00) - Définition luminosité modérée"
    elif (( $(echo "$time_decimal >= 9 && $time_decimal < 17" | bc -l) )); then
        # Heures de travail : Luminosité complète
        brightness_level="0.8"
        echo "Période : Heures de travail (9:00-17:00) - Définition luminosité élevée"
    elif (( $(echo "$time_decimal >= 17 && $time_decimal < 20" | bc -l) )); then
        # Soirée : Luminosité moyenne
        brightness_level="0.6"
        echo "Période : Soirée (17:00-20:00) - Définition luminosité moyenne"
    elif (( $(echo "$time_decimal >= 20 && $time_decimal < 22" | bc -l) )); then
        # Nuit : Luminosité faible
        brightness_level="0.3"
        echo "Période : Nuit (20:00-22:00) - Définition luminosité faible"
    else
        # Tard dans la nuit/tôt le matin : Très faible
        brightness_level="0.1"
        echo "Période : Tard dans la nuit/Tôt le matin - Définition luminosité très faible"
    fi
    
    set_brightness "$brightness_level"
}

# Changements de luminosité programmés
scheduled_brightness_adjustment() {
    echo "--- Ajustement de Luminosité Programmé ---"
    
    # Définir l'horaire (heure:niveau_luminosité)
    local schedule=(
        "06:00:0.3"  # Aube
        "08:00:0.6"  # Matin
        "09:00:0.8"  # Début travail
        "12:00:0.9"  # Midi
        "17:00:0.7"  # Fin travail
        "19:00:0.5"  # Soirée
        "21:00:0.3"  # Nuit
        "23:00:0.1"  # Tard dans la nuit
    )
    
    local current_time=$(date +%H:%M)
    echo "Heure actuelle : $current_time"
    
    # Trouver le niveau de luminosité approprié pour l'heure actuelle
    local target_brightness="0.5"  # Par défaut
    
    for schedule_entry in "${schedule[@]}"; do
        IFS=':' read -r schedule_time schedule_brightness <<< "$schedule_entry"
        
        if [[ "$current_time" > "$schedule_time" ]] || [[ "$current_time" == "$schedule_time" ]]; then
            target_brightness="$schedule_brightness"
        fi
    done
    
    echo "Niveau de luminosité programmé : $target_brightness"
    set_brightness "$target_brightness"
}

# Gestion de luminosité consciente de la batterie
battery_aware_brightness() {
    echo "--- Gestion de Luminosité Consciente de la Batterie ---"
    
    # Obtenir les informations de batterie
    local battery_info=$(pmset -g batt)
    local battery_percentage=$(echo "$battery_info" | grep -o '[0-9]*%' | head -1 | tr -d '%')
    local power_source=$(echo "$battery_info" | grep -o "AC Power\|Battery Power" | head -1)
    
    echo "Niveau de batterie : ${battery_percentage}%"
    echo "Source d'alimentation : $power_source"
    
    local brightness_level
    
    if [[ "$power_source" == "AC Power" ]]; then
        # Sur alimentation secteur - luminosité normale
        brightness_level="0.8"
        echo "Sur alimentation secteur - Définition luminosité normale"
    else
        # Sur batterie - ajuster selon le niveau de batterie
        if [[ $battery_percentage -gt 50 ]]; then
            brightness_level="0.6"
            echo "Batterie > 50% - Définition luminosité moyenne"
        elif [[ $battery_percentage -gt 20 ]]; then
            brightness_level="0.4"
            echo "Batterie 20-50% - Définition luminosité faible"
        else
            brightness_level="0.2"
            echo "Batterie < 20% - Définition luminosité très faible"
        fi
    fi
    
    set_brightness "$brightness_level"
}

# Usage
adaptive_brightness_control "auto"

Système de Gestion d'Affichage d'Entreprise

#!/bin/bash

# Outil de Gestion de Luminosité d'Affichage Roundfleet
# Contrôle d'affichage complet, optimisation énergétique et gestion de flotte

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/roundfleet_display_management.log"
REPORT_DIR="/etc/roundfleet/reports/display"
CONFIG_DIR="/etc/roundfleet/display"
POLICY_DIR="/etc/roundfleet/policies/display"
SCHEDULE_DIR="/etc/roundfleet/schedules/display"

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

# Modèles de politiques de gestion d'affichage
declare -A DISPLAY_POLICIES=(
    ["enterprise_standard"]="adaptive_brightness,battery_optimization,work_hours_profile,user_override_limited"
    ["energy_saver"]="aggressive_dimming,battery_priority,low_brightness_default,power_aware_scheduling"
    ["presentation_mode"]="high_brightness,stable_settings,no_auto_dimming,optimal_visibility"
    ["kiosk_display"]="fixed_brightness,no_user_control,scheduled_adjustments,energy_optimized"
    ["healthcare"]="eye_strain_reduction,shift_appropriate,patient_privacy,energy_conscious"
    ["financial"]="security_dimming,privacy_protection,energy_compliance,professional_display"
    ["education"]="classroom_optimized,energy_teaching,adaptive_learning,student_friendly"
    ["retail"]="customer_facing,bright_displays,brand_consistency,operational_hours"
    ["manufacturing"]="industrial_visibility,safety_priority,harsh_environment,energy_efficient"
    ["government"]="security_compliant,energy_mandates,accessibility_aware,audit_ready"
)

# Profils de luminosité pour différents cas d'usage
declare -A BRIGHTNESS_PROFILES=(
    ["work_day"]="morning:0.4,work_start:0.8,lunch:0.9,afternoon:0.8,work_end:0.6"
    ["energy_saver"]="morning:0.3,work_start:0.6,lunch:0.7,afternoon:0.6,work_end:0.4"
    ["presentation"]="all_day:0.9,constant_high:1.0"
    ["night_shift"]="evening:0.4,night:0.2,late_night:0.1,dawn:0.3"
    ["retail_hours"]="open:0.9,peak:1.0,closing:0.7,after_hours:0.2"
    ["healthcare_24"]="day_shift:0.7,evening_shift:0.5,night_shift:0.3,emergency:0.8"
)

# Seuils d'optimisation énergétique
declare -A ENERGY_THRESHOLDS=(
    ["battery_critical"]="20:0.2"      # Sous 20% batterie : 20% luminosité
    ["battery_low"]="30:0.4"           # Sous 30% batterie : 40% luminosité
    ["battery_medium"]="50:0.6"        # Sous 50% batterie : 60% luminosité
    ["battery_high"]="80:0.8"          # Au-dessus 80% batterie : 80% luminosité
    ["ac_power"]="100:0.9"             # Sur alimentation secteur : 90% luminosité
)

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

# Contrôle de luminosité amélioré avec validation
set_brightness_enhanced() {
    local brightness_level="$1"
    local reason="${2:-Ajustement manuel}"
    local user="${3:-$(whoami)}"
    
    log_action "Définition luminosité à $brightness_level pour utilisateur $user - Raison : $reason"
    
    # Valider le niveau de luminosité
    if ! [[ "$brightness_level" =~ ^[0-9]*\.?[0-9]+$ ]] || 
       (( $(echo "$brightness_level > 1.0" | bc -l) )) || 
       (( $(echo "$brightness_level < 0.0" | bc -l) )); then
        log_action "ERREUR : Niveau de luminosité invalide : $brightness_level"
        return 1
    fi
    
    # Stocker la luminosité précédente pour capacité de retour en arrière
    local previous_brightness=$(get_current_brightness_value)
    
    # Appliquer le changement de luminosité
    local brightness_cmd=""
    if command -v brightness >/dev/null 2>&1; then
        brightness_cmd="brightness"
    elif [[ -x "/opt/homebrew/bin/brightness" ]]; then
        brightness_cmd="/opt/homebrew/bin/brightness"
    elif [[ -x "/usr/local/bin/brightness" ]]; then
        brightness_cmd="/usr/local/bin/brightness"
    elif [[ -x "/usr/local/Cellar/brightness/1.2/bin/brightness" ]]; then
        brightness_cmd="/usr/local/Cellar/brightness/1.2/bin/brightness"
    else
        log_action "ERREUR : Commande de contrôle de luminosité non trouvée"
        return 1
    fi
    
    if $brightness_cmd "$brightness_level" 2>/dev/null; then
        local percentage=$(echo "$brightness_level * 100" | bc)
        log_action "SUCCÈS : Luminosité définie à $brightness_level (${percentage}%)"
        
        # Enregistrer le changement dans l'historique
        echo "$(date '+%Y-%m-%d %H:%M:%S'),$user,$previous_brightness,$brightness_level,$reason" >> "$CONFIG_DIR/brightness_history.csv"
        
        return 0
    else
        log_action "ERREUR : Échec de définition de luminosité à $brightness_level"
        return 1
    fi
}

# Obtenir la luminosité actuelle comme valeur numérique
get_current_brightness_value() {
    local current_brightness=""
    
    if command -v brightness >/dev/null 2>&1; then
        current_brightness=$(brightness -l 2>/dev/null | grep -o '[0-9]*\.[0-9]*' | head -1)
    fi
    
    if [[ -n "$current_brightness" ]]; then
        echo "$current_brightness"
    else
        echo "0.5"  # Valeur par défaut de repli
    fi
}

# Appliquer un profil de luminosité
apply_brightness_profile() {
    local profile_name="$1"
    local override_time="${2:-}"
    
    log_action "Application du profil de luminosité : $profile_name"
    
    if [[ -z "${BRIGHTNESS_PROFILES[$profile_name]}" ]]; then
        log_action "ERREUR : Profil de luminosité inconnu : $profile_name"
        echo "Profils disponibles : ${!BRIGHTNESS_PROFILES[*]}"
        return 1
    fi
    
    local profile_settings="${BRIGHTNESS_PROFILES[$profile_name]}"
    local current_time="${override_time:-$(date +%H:%M)}"
    local current_hour=$(echo "$current_time" | cut -d: -f1)
    
    echo "=== Application du Profil de Luminosité : $profile_name ==="
    echo "Heure actuelle : $current_time"
    echo "Paramètres de profil : $profile_settings"
    
    # Analyser les paramètres de profil et trouver la luminosité appropriée
    local target_brightness="0.5"  # Par défaut
    local matched_period="default"
    
    IFS=',' read -ra SETTINGS <<< "$profile_settings"
    for setting in "${SETTINGS[@]}"; do
        IFS=':' read -ra TIME_BRIGHTNESS <<< "$setting"
        local time_period="${TIME_BRIGHTNESS[0]}"
        local brightness_value="${TIME_BRIGHTNESS[1]}"
        
        case "$time_period" in
            "morning")
                if [[ $current_hour -ge 6 && $current_hour -lt 9 ]]; then
                    target_brightness="$brightness_value"
                    matched_period="morning"
                fi
                ;;
            "work_start"|"work")
                if [[ $current_hour -ge 9 && $current_hour -lt 12 ]]; then
                    target_brightness="$brightness_value"
                    matched_period="work_start"
                fi
                ;;
            "lunch"|"midday")
                if [[ $current_hour -ge 12 && $current_hour -lt 14 ]]; then
                    target_brightness="$brightness_value"
                    matched_period="lunch"
                fi
                ;;
            "afternoon")
                if [[ $current_hour -ge 14 && $current_hour -lt 17 ]]; then
                    target_brightness="$brightness_value"
                    matched_period="afternoon"
                fi
                ;;
            "work_end"|"evening")
                if [[ $current_hour -ge 17 && $current_hour -lt 20 ]]; then
                    target_brightness="$brightness_value"
                    matched_period="evening"
                fi
                ;;
            "night")
                if [[ $current_hour -ge 20 && $current_hour -lt 23 ]]; then
                    target_brightness="$brightness_value"
                    matched_period="night"
                fi
                ;;
            "late_night")
                if [[ $current_hour -ge 23 || $current_hour -lt 6 ]]; then
                    target_brightness="$brightness_value"
                    matched_period="late_night"
                fi
                ;;
            "all_day"|"constant_high")
                target_brightness="$brightness_value"
                matched_period="all_day"
                ;;
        esac
    done
    
    echo "Période correspondante : $matched_period"
    echo "Luminosité cible : $target_brightness"
    
    # Appliquer la luminosité
    set_brightness_enhanced "$target_brightness" "Profil : $profile_name ($matched_period)"
}

# Gestion de luminosité consciente de l'énergie
energy_aware_brightness() {
    local policy="${1:-balanced}"
    
    log_action "Démarrage gestion luminosité consciente énergie avec politique : $policy"
    
    echo "=== Gestion de Luminosité Consciente de l'Énergie ==="
    echo "Politique : $policy"
    echo ""
    
    # Obtenir le statut d'alimentation
    local battery_info=$(pmset -g batt)
    local battery_percentage=$(echo "$battery_info" | grep -o '[0-9]*%' | head -1 | tr -d '%')
    local power_source=$(echo "$battery_info" | grep -o "AC Power\|Battery Power" | head -1)
    local charging_status=$(echo "$battery_info" | grep -o "charging\|charged\|discharging" | head -1)
    
    echo "--- Statut d'Alimentation ---"
    echo "Source d'Alimentation : $power_source"
    echo "Niveau de Batterie : ${battery_percentage}%"
    echo "Statut de Charge : $charging_status"
    
    # Déterminer la luminosité basée sur la politique énergétique
    local target_brightness=""
    local energy_reason=""
    
    case "$policy" in
        "aggressive")
            if [[ "$power_source" == "AC Power" ]]; then
                target_brightness="0.8"
                energy_reason="Alimentation secteur - luminosité normale"
            else
                if [[ $battery_percentage -lt 20 ]]; then
                    target_brightness="0.15"
                    energy_reason="Batterie critique - luminosité minimale"
                elif [[ $battery_percentage -lt 40 ]]; then
                    target_brightness="0.25"
                    energy_reason="Batterie faible - luminosité très faible"
                else
                    target_brightness="0.4"
                    energy_reason="Alimentation batterie - luminosité faible"
                fi
            fi
            ;;
        "balanced")
            if [[ "$power_source" == "AC Power" ]]; then
                target_brightness="0.8"
                energy_reason="Alimentation secteur - luminosité normale"
            else
                if [[ $battery_percentage -lt 20 ]]; then
                    target_brightness="0.2"
                    energy_reason="Batterie faible - luminosité réduite"
                elif [[ $battery_percentage -lt 50 ]]; then
                    target_brightness="0.4"
                    energy_reason="Batterie moyenne - luminosité modérée"
                else
                    target_brightness="0.6"
                    energy_reason="Bonne batterie - luminosité normale"
                fi
            fi
            ;;
        "performance")
            if [[ "$power_source" == "AC Power" ]]; then
                target_brightness="0.9"
                energy_reason="Alimentation secteur - luminosité élevée"
            else
                if [[ $battery_percentage -lt 15 ]]; then
                    target_brightness="0.3"
                    energy_reason="Batterie critique - économie d'énergie"
                else
                    target_brightness="0.7"
                    energy_reason="Alimentation batterie - maintenir visibilité"
                fi
            fi
            ;;
    esac
    
    echo ""
    echo "--- Décision Énergétique ---"
    echo "Politique : $policy"
    echo "Décision : $energy_reason"
    echo "Luminosité Cible : $target_brightness"
    
    # Appliquer le changement de luminosité
    set_brightness_enhanced "$target_brightness" "$energy_reason"
    
    # Journaliser l'estimation d'économie d'énergie
    local current_brightness=$(get_current_brightness_value)
    local energy_savings=$(echo "($current_brightness - $target_brightness) * 20" | bc)  # Estimation approximative
    
    if (( $(echo "$energy_savings > 0" | bc -l) )); then
        echo "Économies d'énergie estimées : ${energy_savings}% réduction puissance affichage"
        log_action "Économies d'énergie estimées : ${energy_savings}% réduction puissance affichage"
    fi
}

# Gestion de luminosité de flotte
manage_fleet_brightness() {
    local operation="$1"
    local target_brightness="$2"
    local fleet_scope="${3:-local}"
    
    log_action "Gestion luminosité flotte : $operation (portée : $fleet_scope)"
    
    echo "=== Gestion de Luminosité de Flotte ==="
    echo "Opération : $operation"
    echo "Luminosité Cible : $target_brightness"
    echo "Portée Flotte : $fleet_scope"
    echo ""
    
    case "$operation" in
        "set_all")
            echo "Définition luminosité à $target_brightness sur toute la flotte..."
            set_brightness_enhanced "$target_brightness" "Ajustement à l'échelle de la flotte"
            ;;
        "energy_optimize")
            echo "Optimisation de la luminosité pour l'efficacité énergétique..."
            energy_aware_brightness "balanced"
            ;;
        "sync_profiles")
            echo "Synchronisation des profils de luminosité sur la flotte..."
            apply_brightness_profile "work_day"
            ;;
        "emergency_dim")
            echo "Application atténuation d'urgence pour conservation énergie..."
            set_brightness_enhanced "0.1" "Conservation d'énergie d'urgence"
            ;;
        "restore_normal")
            echo "Restauration des niveaux de luminosité normaux..."
            apply_brightness_profile "work_day"
            ;;
        *)
            log_action "ERREUR : Opération de flotte inconnue : $operation"
            return 1
            ;;
    esac
    
    # Générer le rapport de statut de flotte
    generate_brightness_status_report
}

# Générer un rapport de statut de luminosité
generate_brightness_status_report() {
    local report_file="$REPORT_DIR/brightness_status_$(date +%Y%m%d_%H%M%S).json"
    
    local current_brightness=$(get_current_brightness_value)
    local battery_info=$(pmset -g batt)
    local battery_percentage=$(echo "$battery_info" | grep -o '[0-9]*%' | head -1 | tr -d '%')
    local power_source=$(echo "$battery_info" | grep -o "AC Power\|Battery Power" | head -1)
    
    cat > "$report_file" << EOF
{
    "brightness_status_report": {
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "script_version": "$SCRIPT_VERSION",
        "display_status": {
            "current_brightness": $current_brightness,
            "brightness_percentage": $(echo "$current_brightness * 100" | bc),
            "power_source": "$power_source",
            "battery_level": $battery_percentage
        },
        "system_info": {
            "os_version": "$(sw_vers -productVersion)",
            "hardware_model": "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk '{print $3}')",
            "display_count": $(system_profiler SPDisplaysDataType | grep "Display Type" | wc -l | tr -d ' ')
        }
    }
}
EOF
    
    echo "Rapport de statut de luminosité généré : $report_file"
    log_action "Rapport de statut généré : $report_file"
}

# Fonction d'exécution principale
main() {
    local action="${1:-help}"
    local param1="${2:-}"
    local param2="${3:-}"
    local param3="${4:-}"
    local param4="${5:-}"
    
    log_action "=== Gestion de Luminosité d'Affichage Roundfleet Démarrée ==="
    log_action "Action : $action"
    
    case "$action" in
        "set")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 set <niveau_luminosité> [raison]"
                echo "Niveau de luminosité : 0.0-1.0 (0-100%)"
                exit 1
            fi
            set_brightness_enhanced "$param1" "${param2:-Définition manuelle}"
            ;;
        "get")
            echo "Luminosité actuelle : $(get_current_brightness_value)"
            ;;
        "profile")
            if [[ -z "$param1" ]]; then
                echo "Profils disponibles : ${!BRIGHTNESS_PROFILES[*]}"
                exit 1
            fi
            apply_brightness_profile "$param1" "$param2"
            ;;
        "energy")
            energy_aware_brightness "${param1:-balanced}"
            ;;
        "fleet")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 fleet <opération> [luminosité] [portée]"
                echo "Opérations : set_all, energy_optimize, sync_profiles, emergency_dim, restore_normal"
                exit 1
            fi
            manage_fleet_brightness "$param1" "$param2" "$param3"
            ;;
        "adaptive")
            adaptive_brightness_control "${param1:-auto}"
            ;;
        "install")
            install_brightness_tools
            ;;
        "help")
            echo "Usage : $0 [action] [options...]"
            echo "Actions :"
            echo "  set <niveau> [raison] - Définir niveau luminosité (0.0-1.0)"
            echo "  get - Obtenir niveau luminosité actuel"
            echo "  profile <nom> [heure] - Appliquer profil luminosité"
            echo "  energy [politique] - Gestion luminosité consciente énergie"
            echo "  fleet <opération> [params] - Gestion luminosité flotte"
            echo "  adaptive [mode] - Contrôle luminosité adaptatif"
            echo "  install - Installer outils contrôle luminosité"
            echo "  help - Afficher cette aide"
            echo ""
            echo "Profils : ${!BRIGHTNESS_PROFILES[*]}"
            echo "Politiques : ${!DISPLAY_POLICIES[*]}"
            ;;
        *)
            log_action "ERREUR : Action inconnue : $action"
            echo "Utilisez '$0 help' pour les informations d'utilisation"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion de luminosité d'affichage terminée ==="
}

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

Notes Importantes

  • Homebrew Requis - L'outil de contrôle de luminosité nécessite l'installation de Homebrew
  • Support Mac Intel - Certaines commandes de luminosité fonctionnent uniquement sur les Mac basés Intel
  • Conscience Batterie - La luminosité doit être ajustée selon la source d'alimentation et le niveau de batterie
  • Expérience Utilisateur - Les changements soudains de luminosité peuvent être dérangeants ; implémenter des transitions graduelles
  • Politiques d'Entreprise - Différents environnements de travail nécessitent différentes stratégies de luminosité
  • Conservation d'Énergie - Une luminosité plus faible prolonge significativement la durée de vie de la batterie
  • Considérations Santé - Une luminosité appropriée réduit la fatigue et la tension oculaires

Gestion d'Utilitaire de Disque d'Entreprise sur macOS

Gérez le stockage et les opérations de disque sur vos appareils Roundfleet en utilisant des commandes diskutil avancées et des outils de gestion de stockage d'entreprise. Ce tutoriel couvre la gestion de disque, la sécurité de stockage, la surveillance de conformité et la gestion du cycle de vie de stockage d'entreprise.

Comprendre la Gestion de Disque macOS

macOS fournit plusieurs outils en ligne de commande pour la gestion de disque et de stockage :

  • diskutil - Utilitaire de disque principal pour la gestion de volumes et partitions
  • df - Afficher l'utilisation d'espace disque du système de fichiers
  • du - Afficher l'utilisation d'espace répertoire
  • fsck - Utilitaire de vérification et réparation du système de fichiers
  • APFS - Système de fichiers Apple avec fonctionnalités avancées

Opérations de Disque de Base

Lister Tous les Disques

#!/bin/bash

# Liste de disques de base
diskutil list

echo "Inventaire de disques terminé avec succès"

Informations de Disque Améliorées

#!/bin/bash

# Informations de disque améliorées avec analyse détaillée
get_comprehensive_disk_info() {
    echo "=== Analyse Complète de Disque ==="
    
    # Liste de disques de base
    echo "Inventaire de Disques :"
    diskutil list
    
    echo -e "\nRésumé d'Utilisation de Disque :"
    df -h
    
    echo -e "\nInformations de Conteneur APFS :"
    diskutil apfs list
    
    echo -e "\nInformations de Disque Physique :"
    system_profiler SPStorageDataType
    
    echo -e "\nStatut SMART :"
    for disk in $(diskutil list | grep "^/dev/disk[0-9]" | awk '{print $1}'); do
        echo "Statut SMART pour $disk :"
        smartctl -H "$disk" 2>/dev/null || echo "  Données SMART non disponibles"
    done
}

# Exécuter l'analyse complète
get_comprehensive_disk_info

Catégories de Gestion de Stockage

Classifications de Types de Stockage

#!/bin/bash

# Catégories de stockage d'entreprise pour gestion et application de politiques
declare -A STORAGE_CATEGORIES=(
    ["systeme_critique"]="Volumes système, partitions de démarrage, partitions de récupération"
    ["donnees_utilisateur"]="Répertoires home utilisateur, documents personnels, données d'application"
    ["stockage_application"]="Binaires d'application, frameworks, bibliothèques système"
    ["espace_developpement"]="Environnements de développement, code source, artefacts de build"
    ["contenu_media"]="Vidéos, images, fichiers audio, ressources créatives"
    ["archives_sauvegarde"]="Time Machine, sauvegardes système, stockage d'archives"
    ["cache_temporaire"]="Fichiers cache, données temporaires, journaux système"
    ["volumes_securite"]="Volumes chiffrés, conteneurs sécurisés, stockage de clés"
    ["stockage_reseau"]="Lecteurs réseau montés, stockage cloud, volumes distants"
    ["peripheriques_externes"]="Clés USB, disques durs externes, stockage amovible"
)

# Niveaux de risque de stockage
declare -A RISK_LEVELS=(
    ["systeme_critique"]="critique"
    ["donnees_utilisateur"]="eleve"
    ["stockage_application"]="moyen"
    ["espace_developpement"]="moyen"
    ["contenu_media"]="faible"
    ["archives_sauvegarde"]="eleve"
    ["cache_temporaire"]="faible"
    ["volumes_securite"]="critique"
    ["stockage_reseau"]="moyen"
    ["peripheriques_externes"]="eleve"
)

# Priorités de gestion
declare -A MANAGEMENT_PRIORITIES=(
    ["systeme_critique"]="protection_maximale"
    ["donnees_utilisateur"]="protection_elevee"
    ["stockage_application"]="protection_standard"
    ["espace_developpement"]="protection_standard"
    ["contenu_media"]="protection_basique"
    ["archives_sauvegarde"]="protection_maximale"
    ["cache_temporaire"]="priorite_nettoyage"
    ["volumes_securite"]="protection_maximale"
    ["stockage_reseau"]="priorite_surveillance"
    ["peripheriques_externes"]="verification_securite"
)

print_storage_categories() {
    echo "=== Catégories de Gestion de Stockage ==="
    for category in "${!STORAGE_CATEGORIES[@]}"; do
        echo "Catégorie : $category"
        echo "  Description : ${STORAGE_CATEGORIES[$category]}"
        echo "  Niveau de Risque : ${RISK_LEVELS[$category]}"
        echo "  Priorité de Gestion : ${MANAGEMENT_PRIORITIES[$category]}"
        echo ""
    done
}

# Afficher les catégories disponibles
print_storage_categories

Politiques de Gestion de Disque

Moteur de Politique de Stockage

#!/bin/bash

# Politiques de gestion de stockage pour différentes exigences organisationnelles
declare -A STORAGE_POLICIES=(
    ["entreprise_standard"]="Stockage d'entreprise standard avec sauvegarde et surveillance"
    ["securite_elevee_financiere"]="Stockage haute sécurité pour données financières et sensibles"
    ["flux_creatif"]="Optimisé pour équipes créatives avec gros fichiers média"
    ["environnement_developpement"]="Axé développement avec contrôle de version et optimisation de build"
    ["conformite_stricte"]="Conformité stricte avec exigences de rétention et audit des données"
    ["optimise_performance"]="Axé performance avec optimisation SSD et mise en cache"
    ["efficace_cout"]="Stockage rentable avec hiérarchisation intelligente et nettoyage"
)

# Configurations de politique
get_storage_policy() {
    local policy_type="$1"
    
    case "$policy_type" in
        "entreprise_standard")
            cat << EOF
{
    "chiffrement_requis": true,
    "frequence_sauvegarde": "quotidienne",
    "periode_retention": "90_jours",
    "compression_activee": true,
    "deduplication": true,
    "niveau_surveillance": "standard",
    "analyse_securite": true,
    "nettoyage_automatique": false,
    "optimisation_performance": "equilibree",
    "cadres_conformite": ["iso27001"],
    "surveillance_sante_disque": true,
    "quotas_stockage": {
        "donnees_utilisateur": "100GB",
        "stockage_application": "50GB",
        "cache_temporaire": "10GB"
    }
}
EOF
            ;;
        "securite_elevee_financiere")
            cat << EOF
{
    "chiffrement_requis": true,
    "niveau_chiffrement": "aes256",
    "frequence_sauvegarde": "continue",
    "periode_retention": "2555_jours",
    "compression_activee": false,
    "deduplication": false,
    "niveau_surveillance": "complet",
    "analyse_securite": true,
    "nettoyage_automatique": false,
    "optimisation_performance": "securite_prioritaire",
    "cadres_conformite": ["sox", "pci_dss", "nist"],
    "surveillance_sante_disque": true,
    "sauvegardes_immuables": true,
    "journalisation_acces": "detaillee",
    "verification_integrite": "continue",
    "quotas_stockage": {
        "donnees_utilisateur": "50GB",
        "stockage_application": "25GB",
        "cache_temporaire": "5GB",
        "journaux_audit": "illimite"
    }
}
EOF
            ;;
        "flux_creatif")
            cat << EOF
{
    "chiffrement_requis": false,
    "frequence_sauvegarde": "basee_projet",
    "periode_retention": "365_jours",
    "compression_activee": false,
    "deduplication": false,
    "niveau_surveillance": "performance",
    "analyse_securite": false,
    "nettoyage_automatique": true,
    "optimisation_performance": "vitesse_prioritaire",
    "cadres_conformite": ["confidentialite_client"],
    "surveillance_sante_disque": true,
    "optimisation_gros_fichiers": true,
    "acceleration_cache": true,
    "quotas_stockage": {
        "donnees_utilisateur": "500GB",
        "contenu_media": "2TB",
        "archives_projet": "1TB",
        "cache_temporaire": "100GB"
    }
}
EOF
            ;;
        *)
            echo "Politique de stockage inconnue : $policy_type"
            return 1
            ;;
    esac
}

# Appliquer une politique de stockage
apply_storage_policy() {
    local policy="$1"
    local config_file="/tmp/politique_stockage.json"
    
    echo "Application de la politique de stockage : $policy"
    
    get_storage_policy "$policy" > "$config_file"
    
    if [[ ! -f "$config_file" ]]; then
        echo "❌ Échec de génération de la configuration de politique"
        return 1
    fi
    
    echo "✅ Politique de stockage appliquée avec succès"
    echo "Configuration : $config_file"
    
    # Afficher les paramètres clés de la politique
    echo "=== Résumé de Politique ==="
    echo "Chiffrement Requis : $(jq -r '.chiffrement_requis' "$config_file")"
    echo "Fréquence Sauvegarde : $(jq -r '.frequence_sauvegarde' "$config_file")"
    echo "Période Rétention : $(jq -r '.periode_retention' "$config_file")"
    echo "Niveau Surveillance : $(jq -r '.niveau_surveillance' "$config_file")"
    echo "Optimisation Performance : $(jq -r '.optimisation_performance' "$config_file")"
    
    return 0
}

Opérations de Disque Avancées

Effacement Sécurisé de Disque

#!/bin/bash

# Effacement sécurisé de disque amélioré avec vérification
secure_erase_volume() {
    local identifier="$1"
    local security_level="$2"
    local new_name="$3"
    local filesystem_type="${4:-APFS}"
    
    echo "=== Effacement Sécurisé de Volume ==="
    echo "Cible : $identifier"
    echo "Niveau de Sécurité : $security_level"
    echo "Nouveau Nom : $new_name"
    echo "Système de Fichiers : $filesystem_type"
    
    # Vérifier que le disque existe
    if ! diskutil info "$identifier" &>/dev/null; then
        echo "❌ Erreur : Identifiant de disque '$identifier' non trouvé"
        return 1
    fi
    
    # Obtenir les informations de disque avant effacement
    local disk_info
    disk_info=$(diskutil info "$identifier")
    echo "Informations de Disque :"
    echo "$disk_info"
    
    # Invite de confirmation
    echo ""
    echo "⚠️  ATTENTION : Ceci effacera définitivement toutes les données sur $identifier"
    echo "Volume actuel : $(echo "$disk_info" | grep "Volume Name:" | awk -F': ' '{print $2}')"
    echo "Taille : $(echo "$disk_info" | grep "Disk Size:" | awk -F': ' '{print $2}')"
    
    read -p "Tapez 'CONFIRMER' pour procéder à l'effacement : " confirmation
    if [[ "$confirmation" != "CONFIRMER" ]]; then
        echo "❌ Opération annulée par l'utilisateur"
        return 1
    fi
    
    # Effectuer l'effacement sécurisé basé sur le niveau de sécurité
    case "$security_level" in
        "basique")
            echo "Effacement basique en cours..."
            diskutil eraseVolume "$filesystem_type" "$new_name" "$identifier"
            ;;
        "securise")
            echo "Effacement sécurisé en cours (DoD 5220.22-M)..."
            diskutil secureErase freespace 3 "$identifier"
            diskutil eraseVolume "$filesystem_type" "$new_name" "$identifier"
            ;;
        "militaire")
            echo "Effacement niveau militaire en cours (7 passes)..."
            diskutil secureErase freespace 4 "$identifier"
            diskutil eraseVolume "$filesystem_type" "$new_name" "$identifier"
            ;;
        *)
            echo "❌ Niveau de sécurité inconnu : $security_level"
            return 1
            ;;
    esac
    
    # Vérifier la completion de l'effacement
    if diskutil info "$identifier" | grep -q "Volume Name.*$new_name"; then
        echo "✅ Effacement sécurisé terminé avec succès"
        echo "Nouveau volume : $new_name"
        echo "Système de fichiers : $filesystem_type"
        
        # Journaliser l'opération
        audit_log "Effacement sécurisé terminé : $identifier -> $new_name (Sécurité : $security_level)"
        
        return 0
    else
        echo "❌ Échec de vérification d'effacement"
        return 1
    fi
}

# Exemple d'utilisation
# secure_erase_volume "disk2s1" "securise" "VolumeNettoyé" "APFS"

Système de Gestion de Stockage d'Entreprise

#!/bin/bash

# Système de Gestion de Stockage d'Entreprise Roundfleet
# Gestion complète de disque et stockage

# Configuration
CONFIG_DIR="/etc/roundfleet/stockage"
LOG_FILE="/var/log/roundfleet_gestion_stockage.log"
DATA_DIR="/var/data/roundfleet/stockage"
REPORTS_DIR="/var/reports/roundfleet/stockage"
AUDIT_LOG="/var/log/roundfleet_audit_stockage.log"
BACKUP_DIR="/var/backups/roundfleet/stockage"

# Créer les répertoires requis
create_directories() {
    local directories=("$CONFIG_DIR" "$DATA_DIR" "$REPORTS_DIR" "$BACKUP_DIR")
    
    for dir in "${directories[@]}"; do
        if [[ ! -d "$dir" ]]; then
            sudo mkdir -p "$dir"
            sudo chmod 755 "$dir"
        fi
    done
}

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

log_error() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') [ERREUR] $1" | tee -a "$LOG_FILE" >&2
}

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

# Gestion d'inventaire de stockage
initialize_storage_database() {
    local db_file="$DATA_DIR/inventaire_stockage.json"
    
    if [[ ! -f "$db_file" ]]; then
        cat > "$db_file" << EOF
{
    "version": "1.0",
    "cree": "$(date -Iseconds)",
    "peripheriques_stockage": {},
    "configurations_volume": {},
    "surveillance_sante": {},
    "metriques_performance": {},
    "evaluations_securite": {}
}
EOF
        log_action "Base de données de stockage initialisée : $db_file"
    fi
}

# Découverte complète de stockage
discover_storage_infrastructure() {
    local discovery_file="$DATA_DIR/decouverte_stockage_$(date +%Y%m%d_%H%M%S).json"
    
    log_action "Début de découverte complète d'infrastructure de stockage"
    
    echo "=== Découverte d'Infrastructure de Stockage ==="
    
    # Périphériques de stockage physiques
    echo "Découverte des périphériques de stockage physiques..."
    local physical_devices
    physical_devices=$(system_profiler SPStorageDataType -json)
    
    # Volumes et partitions logiques
    echo "Analyse des volumes logiques..."
    local logical_volumes
    logical_volumes=$(diskutil list -plist | plutil -convert json -o -)
    
    # Conteneurs et volumes APFS
    echo "Examen des conteneurs APFS..."
    local apfs_containers
    apfs_containers=$(diskutil apfs list -plist | plutil -convert json -o -)
    
    # Volumes montés réseau
    echo "Vérification des volumes réseau..."
    local network_volumes
    network_volumes=$(mount | grep -E "(nfs|smb|afp)" | jq -R . | jq -s .)
    
    # Périphériques externes
    echo "Détection des périphériques externes..."
    local external_devices
    external_devices=$(diskutil list external -plist | plutil -convert json -o -)
    
    # Statut de chiffrement
    echo "Évaluation du statut de chiffrement..."
    local encryption_status=()
    while IFS= read -r volume; do
        if [[ -n "$volume" ]]; then
            local encrypted="false"
            if diskutil info "$volume" | grep -q "FileVault.*Yes"; then
                encrypted="true"
            fi
            encryption_status+=("{\"volume\": \"$volume\", \"chiffre\": $encrypted}")
        fi
    done <<< "$(diskutil list | grep -E "^\s+[0-9]+:" | awk '{print $NF}')"
    
    # Générer rapport de découverte complet
    cat > "$discovery_file" << EOF
{
    "horodatage_decouverte": "$(date -Iseconds)",
    "nom_hote": "$(hostname)",
    "stockage_physique": $physical_devices,
    "volumes_logiques": $logical_volumes,
    "conteneurs_apfs": $apfs_containers,
    "volumes_reseau": $network_volumes,
    "peripheriques_externes": $external_devices,
    "statut_chiffrement": [$(IFS=,; echo "${encryption_status[*]}")],
    "info_systeme": {
        "version_os": "$(sw_vers -productVersion)",
        "stockage_total": "$(df -h / | tail -1 | awk '{print $2}')",
        "stockage_disponible": "$(df -h / | tail -1 | awk '{print $4}')"
    }
}
EOF
    
    log_action "Découverte de stockage terminée : $discovery_file"
    
    # Afficher le résumé
    echo ""
    echo "Résumé de Découverte :"
    echo "  Périphériques Physiques : $(echo "$physical_devices" | jq '.SPStorageDataType | length' 2>/dev/null || echo "0")"
    echo "  Volumes Logiques : $(echo "$logical_volumes" | jq '.AllDisks | length' 2>/dev/null || echo "0")"
    echo "  Conteneurs APFS : $(echo "$apfs_containers" | jq '.Containers | length' 2>/dev/null || echo "0")"
    echo "  Volumes Réseau : $(echo "$network_volumes" | jq '. | length' 2>/dev/null || echo "0")"
    echo "  Périphériques Externes : $(echo "$external_devices" | jq '.AllDisks | length' 2>/dev/null || echo "0")"
    echo "  Rapport de Découverte : $discovery_file"
    
    return 0
}

# Surveillance de santé de volume
monitor_volume_health() {
    local identifier="$1"
    local health_report="/tmp/sante_volume_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Surveillance de Santé de Volume ==="
    echo "Volume Cible : $identifier"
    
    # Initialiser le rapport de santé
    cat > "$health_report" << EOF
{
    "identifiant_volume": "$identifier",
    "horodatage_analyse": "$(date -Iseconds)",
    "nom_hote": "$(hostname)",
    "verifications_sante": {}
}
EOF
    
    # Vérification de volume
    echo "Exécution de vérification de volume..."
    local verify_output
    verify_output=$(diskutil verifyVolume "$identifier" 2>&1)
    local verify_status=$?
    
    # Analyser les résultats de vérification
    local verification_passed=false
    if [[ $verify_status -eq 0 ]] && echo "$verify_output" | grep -q "appears to be OK"; then
        verification_passed=true
    fi
    
    # Vérification statut SMART (si supporté)
    echo "Vérification du statut SMART..."
    local smart_status="inconnu"
    local physical_disk
    physical_disk=$(diskutil info "$identifier" | grep "Part of Whole" | awk '{print $4}')
    
    if [[ -n "$physical_disk" ]]; then
        if smartctl -H "$physical_disk" 2>/dev/null | grep -q "PASSED"; then
            smart_status="reussi"
        elif smartctl -H "$physical_disk" 2>/dev/null | grep -q "FAILED"; then
            smart_status="echec"
        fi
    fi
    
    # Analyse d'utilisation de disque
    echo "Analyse d'utilisation de disque..."
    local disk_usage
    disk_usage=$(df -h "$identifier" 2>/dev/null | tail -1)
    local usage_percent
    usage_percent=$(echo "$disk_usage" | awk '{print $5}' | tr -d '%')
    
    # Test de performance
    echo "Exécution de test de performance..."
    local write_speed read_speed
    local test_file="/Volumes/$(diskutil info "$identifier" | grep "Mount Point" | awk -F': ' '{print $2}' | xargs)/test_vitesse_$$"
    
    if [[ -w "$(dirname "$test_file")" ]]; then
        # Test d'écriture (10MB)
        write_speed=$(dd if=/dev/zero of="$test_file" bs=1m count=10 2>&1 | grep "bytes/sec" | awk '{print $(NF-1)}')
        
        # Test de lecture
        read_speed=$(dd if="$test_file" of=/dev/null bs=1m 2>&1 | grep "bytes/sec" | awk '{print $(NF-1)}')
        
        # Nettoyage
        rm -f "$test_file"
    else
        write_speed="non_disponible"
        read_speed="non_disponible"
    fi
    
    # Mettre à jour le rapport de santé
    jq --argjson verification "$verification_passed" \
       --arg smart_status "$smart_status" \
       --argjson usage_percent "${usage_percent:-0}" \
       --arg write_speed "$write_speed" \
       --arg read_speed "$read_speed" \
       '.verifications_sante = {
          "verification_systeme_fichiers": $verification,
          "statut_smart": $smart_status,
          "pourcentage_utilisation_disque": $usage_percent,
          "vitesse_ecriture_mbps": $write_speed,
          "vitesse_lecture_mbps": $read_speed
        }' "$health_report" > "${health_report}.tmp" && mv "${health_report}.tmp" "$health_report"
    
    # Évaluation de santé
    local health_score=100
    local issues=()
    
    if [[ "$verification_passed" != "true" ]]; then
        ((health_score -= 30))
        issues+=("corruption_systeme_fichiers")
    fi
    
    if [[ "$smart_status" == "echec" ]]; then
        ((health_score -= 50))
        issues+=("echec_smart")
    fi
    
    if [[ ${usage_percent:-0} -gt 90 ]]; then
        ((health_score -= 20))
        issues+=("espace_disque_critique")
    elif [[ ${usage_percent:-0} -gt 80 ]]; then
        ((health_score -= 10))
        issues+=("alerte_espace_disque")
    fi
    
    # Ajouter score de santé et problèmes au rapport
    jq --argjson health_score "$health_score" \
       --argjson issues "$(printf '%s\n' "${issues[@]}" | jq -R . | jq -s .)" \
       '.evaluation_sante = {
          "score_global": $health_score,
          "problemes_detectes": $issues,
          "recommandations": []
        }' "$health_report" > "${health_report}.tmp" && mv "${health_report}.tmp" "$health_report"
    
    # Afficher les résultats
    echo ""
    echo "Résultats d'Évaluation de Santé :"
    echo "  Score de Santé Global : $health_score/100"
    echo "  Vérification Système de Fichiers : $([ "$verification_passed" = "true" ] && echo "✅ RÉUSSI" || echo "❌ ÉCHEC")"
    echo "  Statut SMART : $smart_status"
    echo "  Utilisation Disque : ${usage_percent:-0}%"
    echo "  Vitesse Écriture : $write_speed"
    echo "  Vitesse Lecture : $read_speed"
    
    if [[ ${#issues[@]} -gt 0 ]]; then
        echo "  Problèmes Détectés :"
        for issue in "${issues[@]}"; do
            echo "    - $issue"
        done
    else
        echo "  ✅ Aucun problème détecté"
    fi
    
    echo "  Rapport de Santé : $health_report"
    
    # Journaliser la vérification de santé
    audit_log "Vérification santé volume terminée : $identifier (Score : $health_score/100)"
    
    return 0
}

# Fonction principale avec routage de commandes
main() {
    local command="$1"
    shift
    
    # Initialiser
    create_directories
    initialize_storage_database
    
    case "$command" in
        "lister")
            # Liste de disques améliorée
            get_comprehensive_disk_info
            ;;
        "verification_sante")
            monitor_volume_health "$@"
            ;;
        "effacement_securise")
            secure_erase_volume "$@"
            ;;
        "decouvrir")
            discover_storage_infrastructure
            ;;
        "appliquer_politique")
            apply_storage_policy "$@"
            ;;
        "afficher_categories")
            print_storage_categories
            ;;
        "afficher_politiques")
            for policy in entreprise_standard securite_elevee_financiere flux_creatif environnement_developpement conformite_stricte optimise_performance efficace_cout; do
                echo "Politique : $policy"
                get_storage_policy "$policy" | jq .
                echo ""
            done
            ;;
        *)
            echo "Système de Gestion de Stockage d'Entreprise Roundfleet"
            echo "Utilisation : $0 <commande> [options]"
            echo ""
            echo "Commandes :"
            echo "  lister                                       - Liste et analyse de disques améliorées"
            echo "  verification_sante <identifiant>             - Surveillance complète de santé de volume"
            echo "  effacement_securise <id> <niveau> <nom>      - Effacement sécurisé de volume"
            echo "  decouvrir                                    - Découverte d'infrastructure de stockage"
            echo "  appliquer_politique <politique>              - Appliquer politique de gestion de stockage"
            echo "  afficher_categories                          - Afficher catégories de stockage"
            echo "  afficher_politiques                          - Afficher politiques de stockage"
            echo ""
            echo "Exemples :"
            echo "  $0 lister"
            echo "  $0 verification_sante disk1s1"
            echo "  $0 effacement_securise disk2s1 securise DisqueNettoye"
            echo "  $0 decouvrir"
            echo "  $0 appliquer_politique entreprise_standard"
            ;;
    esac
}

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

Configuration de Déploiement en Flotte

Exemple de Configuration de Flotte

{
    "nom_flotte": "Stockage d'Entreprise Roundfleet",
    "date_deploiement": "2025-07-07",
    "hotes": [
        "mac-poste-01.entreprise.com",
        "mac-serveur-01.entreprise.com",
        "mac-dev-01.entreprise.com"
    ],
    "politiques_stockage": {
        "defaut": "entreprise_standard",
        "hotes_securises": "securite_elevee_financiere",
        "hotes_creatifs": "flux_creatif"
    },
    "planning_surveillance": {
        "verifications_sante": "quotidiennes",
        "surveillance_performance": "hebdomadaire",
        "audits_securite": "mensuels"
    }
}

Exemple de Liste de Volumes pour Opérations en Masse

# Liste de Volumes pour Opérations en Masse
# Format : identifiant|nom|systeme_fichiers
disk1s1|Macintosh HD|APFS
disk2s1|Volume Données|APFS
disk3s1|Disque Sauvegarde|APFS
disk4s1|Stockage Externe|ExFAT

Considérations de Sécurité

Sécurité de Stockage

  • Application de Chiffrement - S'assurer que tous les volumes sensibles sont chiffrés avec FileVault
  • Effacement Sécurisé - Plusieurs niveaux de sécurité pour destruction appropriée des données
  • Contrôles d'Accès - Surveiller et contrôler l'accès aux ressources de stockage
  • Surveillance d'Intégrité - Vérification continue de l'intégrité du stockage
  • Détection de Menaces - Analyser l'accès non autorisé et activités suspectes

Cadre de Conformité

  • Rétention de Données - Application automatisée des politiques de rétention de données
  • Pistes d'Audit - Journalisation complète de toutes les opérations de stockage
  • Standards de Chiffrement - Conformité avec AES-256 et autres exigences de chiffrement
  • Vérification de Sauvegarde - Vérification automatisée de l'intégrité des sauvegardes
  • Récupération après Sinistre - Procédures de récupération après sinistre axées stockage

Optimisation de Performance

Performance de Stockage

  • Optimisation SSD - Activation TRIM et optimisation d'usure
  • Optimisation APFS - Défragmentation de conteneur et gestion d'instantanés
  • Gestion de Cache - Mise en cache intelligente et optimisation mémoire
  • Surveillance I/O - Surveillance en temps réel de la performance I/O de stockage
  • Détection de Goulots d'Étranglement - Détection et résolution automatisées des problèmes de performance

Guide de Dépannage

Problèmes Courants

Échecs de Vérification de Disque

  • Exécuter First Aid depuis Utilitaire de Disque
  • Démarrer depuis Mode Récupération pour réparations de volume système
  • Vérifier problèmes matériels avec Diagnostics Apple

Dégradation de Performance

  • Surveiller statut SMART pour santé du lecteur
  • Vérifier fragmentation sur anciens systèmes de fichiers
  • Vérifier espace libre adéquat (maintenir 10-15% libre)

Problèmes de Montage/Démontage

  • Vérifier processus utilisant le volume : lsof /Volumes/NomVolume
  • Forcer le démontage si nécessaire : diskutil unmount force /dev/diskXsY
  • Vérifier intégrité système de fichiers avant remontage

Commandes de Diagnostic

# Vérifier santé de disque
diskutil verifyVolume disk1s1

# Surveiller I/O de disque
iostat -d 1

# Vérifier utilisation système de fichiers
df -h

# Voir statut SMART
smartctl -a /dev/disk0

Notes Importantes

  • Sécurité des Données - Toujours sauvegarder les données critiques avant d'effectuer des opérations de disque
  • Privilèges Administratifs - La plupart des opérations de disque nécessitent un accès sudo/administrateur
  • Tests - Tester tous les scripts sur systèmes non-production avant déploiement en flotte
  • Planification de Récupération - Maintenir des lecteurs de récupération amorçables et stratégies de sauvegarde
  • Surveillance - Implémenter surveillance continue pour détection précoce de problèmes
  • Documentation - Conserver des enregistrements détaillés de toutes les configurations et changements de stockage