Guide

Nouvelles mises à jour et améliorations de Macfleet.

Gestion Apple ID et Suivi d'Identité sur macOS

Gérez l'utilisation des Apple ID, surveillez les services iCloud et implémentez les politiques d'identité d'entreprise sur vos appareils MacFleet. Ce tutoriel couvre la découverte d'Apple ID, la surveillance des services, la conformité de confidentialité et la gestion d'identité complète pour les environnements d'entreprise.

Comprendre l'Intégration Apple ID sur macOS

L'intégration Apple ID fournit l'accès à divers services Apple :

  • Services iCloud - Stockage, synchronisation et sauvegarde
  • Réseau Localiser - Localisation d'appareils et fonctionnalités de sécurité
  • App Store - Téléchargements et mises à jour d'applications
  • Apple Pay - Traitement de paiement sécurisé
  • Trousseau - Synchronisation de mots de passe et d'identifiants

Détection Apple ID Basique

Découverte Simple d'Apple ID

#!/bin/bash

# Détection Apple ID basique pour tous les utilisateurs
check_apple_ids() {
    echo "=== Détection Apple ID ==="
    
    for user in $(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}'); do
        local userHome
        userHome=$(dscl . read /Users/"$user" NFSHomeDirectory | sed 's/NFSHomeDirectory://' | grep "/" | sed 's/^[ \t]*//')
        
        local appleid
        appleid=$(dscl . readpl "${userHome}" dsAttrTypeNative:LinkedIdentity appleid.apple.com:linked\ identities:0:full\ name 2>/dev/null | awk -F'full name: ' '{print $2}')
        
        if [[ "${appleid}" == "" ]]; then
            echo "👤 Utilisateur : ${user} - Aucun Apple ID connecté"
        else
            echo "🍎 Utilisateur : ${user} - Apple ID : ${appleid}"
        fi
    done
}

# Utilisation
check_apple_ids

Informations Apple ID Améliorées

#!/bin/bash

# Détection Apple ID améliorée avec détails supplémentaires
get_detailed_apple_id_info() {
    local username="$1"
    
    echo "=== Informations Apple ID Détaillées pour : $username ==="
    
    # Obtenir le répertoire utilisateur
    local userHome
    userHome=$(dscl . read /Users/"$username" NFSHomeDirectory | sed 's/NFSHomeDirectory://' | grep "/" | sed 's/^[ \t]*//')
    
    if [[ -z "$userHome" ]]; then
        echo "❌ Utilisateur non trouvé : $username"
        return 1
    fi
    
    # Vérifier l'Apple ID
    local appleid
    appleid=$(dscl . readpl "${userHome}" dsAttrTypeNative:LinkedIdentity appleid.apple.com:linked\ identities:0:full\ name 2>/dev/null | awk -F'full name: ' '{print $2}')
    
    if [[ -n "$appleid" ]]; then
        echo "🍎 Apple ID : $appleid"
        
        # Vérifier le statut iCloud
        local icloud_status
        if defaults read "${userHome}/Library/Preferences/MobileMeAccounts" Accounts &>/dev/null; then
            echo "☁️  iCloud : Configuré"
        else
            echo "☁️  iCloud : Non configuré"
        fi
        
        # Vérifier le statut Localiser
        if defaults read "${userHome}/Library/Preferences/com.apple.preferences.account" &>/dev/null; then
            echo "📍 Localiser : Disponible"
        else
            echo "📍 Localiser : Non disponible"
        fi
        
        # Vérifier le statut Trousseau
        if [[ -d "${userHome}/Library/Keychains" ]]; then
            local keychain_count
            keychain_count=$(find "${userHome}/Library/Keychains" -name "*.keychain*" | wc -l)
            echo "🔑 Trousseaux : $keychain_count trouvés"
        fi
        
    else
        echo "❌ Aucun Apple ID connecté"
    fi
}

# Exemple d'utilisation
# get_detailed_apple_id_info "john.doe"

Système de Gestion Apple ID d'Entreprise

#!/bin/bash

# Système de Gestion Apple ID d'Entreprise MacFleet
# Gestion d'identité complète, suivi de conformité et surveillance des services

# Configuration
LOG_FILE="/var/log/macfleet_apple_id.log"
CONFIG_DIR="/etc/macfleet/identity"
REPORTS_DIR="$CONFIG_DIR/reports"
POLICIES_DIR="$CONFIG_DIR/policies"
BACKUP_DIR="/var/backups/identity_configs"

# Configurations des services Apple
declare -A APPLE_SERVICES=(
    ["icloud"]="com.apple.bird,com.apple.iCloudHelper,MobileMeAccounts"
    ["localiser"]="com.apple.icloud.findmydeviced,com.apple.FindMyMacHelper"
    ["appstore"]="com.apple.appstore,com.apple.CommerceKit"
    ["trousseau"]="Security,Keychain"
    ["handoff"]="com.apple.coreservices.useractivityd"
)

# Modèles de politiques de confidentialité
declare -A PRIVACY_POLICIES=(
    ["strict"]="no_icloud,no_sync,audit_all"
    ["equilibre"]="limited_icloud,controlled_sync,audit_sensitive"
    ["permissif"]="full_icloud,full_sync,audit_minimal"
    ["education"]="edu_icloud,student_sync,audit_compliance"
    ["entreprise"]="corp_icloud,enterprise_sync,audit_comprehensive"
)

# Cadres de conformité
declare -A COMPLIANCE_FRAMEWORKS=(
    ["hipaa"]="healthcare,strict_audit,encrypted_only"
    ["sox"]="financial,comprehensive_audit,controlled_access"
    ["rgpd"]="privacy_first,consent_required,data_minimization"
    ["ferpa"]="education,student_privacy,limited_sharing"
    ["entreprise"]="business_use,managed_access,policy_enforcement"
)

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

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

# Découverte complète d'Apple ID
discover_apple_ids() {
    log_action "Démarrage de la découverte complète d'Apple ID"
    
    local discovery_report="$REPORTS_DIR/apple_id_discovery_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$discovery_report" << EOF
{
    "discovery_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)",
        "os_version": "$(sw_vers -productVersion)",
        "generator": "MacFleet Apple ID Manager"
    },
    "user_accounts": [
EOF

    local first=true
    local total_users=0
    local signed_in_users=0
    
    # Traiter chaque compte utilisateur
    for user in $(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}'); do
        total_users=$((total_users + 1))
        
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$discovery_report"
        fi
        
        local userHome uid gid realName
        userHome=$(dscl . read /Users/"$user" NFSHomeDirectory | sed 's/NFSHomeDirectory://' | grep "/" | sed 's/^[ \t]*//')
        uid=$(dscl . read /Users/"$user" UniqueID | awk '{print $2}')
        gid=$(dscl . read /Users/"$user" PrimaryGroupID | awk '{print $2}')
        realName=$(dscl . read /Users/"$user" RealName | sed 's/RealName://' | sed 's/^[ \t]*//' || echo "")
        
        # Obtenir les informations Apple ID
        local appleid=""
        if [[ -n "$userHome" ]]; then
            appleid=$(dscl . readpl "${userHome}" dsAttrTypeNative:LinkedIdentity appleid.apple.com:linked\ identities:0:full\ name 2>/dev/null | awk -F'full name: ' '{print $2}')
        fi
        
        local apple_id_status="not_signed_in"
        if [[ -n "$appleid" ]]; then
            apple_id_status="signed_in"
            signed_in_users=$((signed_in_users + 1))
        fi
        
        # Vérifier les services Apple
        local services_status
        services_status=$(check_apple_services "$user" "$userHome")
        
        # Générer l'enregistrement utilisateur
        cat >> "$discovery_report" << EOF
        {
            "username": "$user",
            "real_name": "$realName",
            "uid": $uid,
            "gid": $gid,
            "home_directory": "$userHome",
            "apple_id_status": "$apple_id_status",
            "apple_id": "${appleid:-null}",
            "services": $services_status,
            "last_login": "$(last -1 "$user" | head -1 | awk '{print $4, $5, $6, $7}' || echo 'Jamais')",
            "account_created": "$(stat -f %SB -t %Y-%m-%d "$userHome" 2>/dev/null || echo 'Inconnu')"
        }
EOF
        
        log_action "Utilisateur traité : $user (Apple ID : ${apple_id_status})"
    done
    
    cat >> "$discovery_report" << EOF
    ],
    "summary": {
        "total_users": $total_users,
        "users_with_apple_id": $signed_in_users,
        "users_without_apple_id": $((total_users - signed_in_users)),
        "apple_id_adoption_rate": $(awk "BEGIN {printf \"%.2f\", ($signed_in_users/$total_users)*100}")
    }
}
EOF

    log_action "✅ Découverte Apple ID terminée : $discovery_report"
    echo "$discovery_report"
}

# Vérifier les services Apple pour un utilisateur
check_apple_services() {
    local username="$1"
    local userHome="$2"
    
    cat << EOF
{
    "icloud": {
        "enabled": $(check_icloud_status "$userHome"),
        "drive": $(check_icloud_drive "$userHome"),
        "photos": $(check_icloud_photos "$userHome"),
        "mail": $(check_icloud_mail "$userHome")
    },
    "find_my": {
        "enabled": $(check_findmy_status "$userHome"),
        "device_registered": $(check_findmy_device "$userHome")
    },
    "app_store": {
        "signed_in": $(check_appstore_status "$userHome"),
        "automatic_downloads": $(check_auto_downloads "$userHome")
    },
    "keychain": {
        "sync_enabled": $(check_keychain_sync "$userHome"),
        "keychain_count": $(count_keychains "$userHome")
    },
    "handoff": {
        "enabled": $(check_handoff_status "$userHome")
    }
}
EOF
}

# Fonctions de vérification de service individuelles
check_icloud_status() {
    local userHome="$1"
    if defaults read "${userHome}/Library/Preferences/MobileMeAccounts" Accounts &>/dev/null; then
        echo "true"
    else
        echo "false"
    fi
}

check_icloud_drive() {
    local userHome="$1"
    if [[ -d "${userHome}/Library/Mobile Documents/com~apple~CloudDocs" ]]; then
        echo "true"
    else
        echo "false"
    fi
}

check_icloud_photos() {
    local userHome="$1"
    if defaults read "${userHome}/Library/Preferences/com.apple.photoanalysisd" &>/dev/null; then
        echo "true"
    else
        echo "false"
    fi
}

check_icloud_mail() {
    local userHome="$1"
    if defaults read "${userHome}/Library/Preferences/com.apple.mail" &>/dev/null | grep -q "icloud"; then
        echo "true"
    else
        echo "false"
    fi
}

check_findmy_status() {
    local userHome="$1"
    if defaults read "${userHome}/Library/Preferences/com.apple.preferences.account" &>/dev/null; then
        echo "true"
    else
        echo "false"
    fi
}

check_findmy_device() {
    local userHome="$1"
    if pgrep -f "FindMyMacHelper" >/dev/null; then
        echo "true"
    else
        echo "false"
    fi
}

check_appstore_status() {
    local userHome="$1"
    if defaults read "${userHome}/Library/Preferences/com.apple.appstore" &>/dev/null; then
        echo "true"
    else
        echo "false"
    fi
}

check_auto_downloads() {
    local userHome="$1"
    local auto_downloads
    auto_downloads=$(defaults read "${userHome}/Library/Preferences/com.apple.appstore" AutomaticallyDownloadApps 2>/dev/null || echo "0")
    if [[ "$auto_downloads" == "1" ]]; then
        echo "true"
    else
        echo "false"
    fi
}

check_keychain_sync() {
    local userHome="$1"
    if security list-keychains -d user | grep -q "iCloud"; then
        echo "true"
    else
        echo "false"
    fi
}

count_keychains() {
    local userHome="$1"
    if [[ -d "${userHome}/Library/Keychains" ]]; then
        find "${userHome}/Library/Keychains" -name "*.keychain*" | wc -l | tr -d ' '
    else
        echo "0"
    fi
}

check_handoff_status() {
    local userHome="$1"
    local handoff_enabled
    handoff_enabled=$(defaults read "${userHome}/Library/Preferences/com.apple.coreservices.useractivityd" ActivityAdvertisingAllowed 2>/dev/null || echo "0")
    if [[ "$handoff_enabled" == "1" ]]; then
        echo "true"
    else
        echo "false"
    fi
}

# Appliquer les politiques de confidentialité
apply_privacy_policy() {
    local policy_name="$1"
    local target_user="$2"
    
    log_action "Application de la politique de confidentialité : $policy_name pour l'utilisateur : ${target_user:-tous_utilisateurs}"
    
    local policy_config="${PRIVACY_POLICIES[$policy_name]}"
    if [[ -z "$policy_config" ]]; then
        log_action "❌ Politique de confidentialité inconnue : $policy_name"
        return 1
    fi
    
    # Analyser la configuration de politique
    IFS=',' read -ra POLICY_RULES <<< "$policy_config"
    
    for rule in "${POLICY_RULES[@]}"; do
        case "$rule" in
            "no_icloud")
                disable_icloud_services "$target_user"
                ;;
            "limited_icloud")
                configure_limited_icloud "$target_user"
                ;;
            "full_icloud")
                log_action "Accès iCloud complet autorisé"
                ;;
            "no_sync")
                disable_sync_services "$target_user"
                ;;
            "controlled_sync")
                configure_controlled_sync "$target_user"
                ;;
            "audit_all")
                enable_comprehensive_audit "$target_user"
                ;;
            "audit_sensitive")
                enable_sensitive_audit "$target_user"
                ;;
            "audit_minimal")
                enable_minimal_audit "$target_user"
                ;;
        esac
    done
    
    log_action "✅ Politique de confidentialité appliquée : $policy_name"
    return 0
}

# Désactiver les services iCloud
disable_icloud_services() {
    local target_user="$1"
    
    log_action "Désactivation des services iCloud pour l'utilisateur : ${target_user:-tous_utilisateurs}"
    
    if [[ -n "$target_user" ]]; then
        local userHome
        userHome=$(dscl . read /Users/"$target_user" NFSHomeDirectory | sed 's/NFSHomeDirectory://' | grep "/" | sed 's/^[ \t]*//')
        
        # Désactiver iCloud Drive
        defaults write "${userHome}/Library/Preferences/com.apple.bird" 'LastDisabledDate' -date "$(date)"
        
        # Désactiver iCloud Photos
        defaults write "${userHome}/Library/Preferences/com.apple.Photos" 'DisableiCloudPhotos' -bool true
        
        log_action "Services iCloud désactivés pour l'utilisateur : $target_user"
    else
        log_action "La désactivation iCloud en masse nécessite un traitement utilisateur individuel"
    fi
}

# Générer un rapport de conformité
generate_compliance_report() {
    local framework="$1"
    local report_type="${2:-summary}"
    
    log_action "Génération du rapport de conformité pour le cadre : $framework"
    
    local compliance_report="$REPORTS_DIR/compliance_${framework}_$(date '+%Y%m%d_%H%M%S').json"
    
    # Obtenir les données de découverte Apple ID actuelles
    local discovery_data
    discovery_data=$(discover_apple_ids)
    
    cat > "$compliance_report" << EOF
{
    "compliance_metadata": {
        "timestamp": "$(date -Iseconds)",
        "framework": "$framework",
        "report_type": "$report_type",
        "hostname": "$(hostname)",
        "generator": "MacFleet Compliance Manager"
    },
    "compliance_assessment": {
        "framework_requirements": $(get_framework_requirements "$framework"),
        "current_status": $(assess_compliance_status "$framework"),
        "recommendations": $(generate_compliance_recommendations "$framework"),
        "risk_level": "$(calculate_risk_level "$framework")"
    },
    "user_data": $(echo "$discovery_data" | jq '.user_accounts')
}
EOF

    log_action "✅ Rapport de conformité généré : $compliance_report"
    echo "$compliance_report"
}

# Obtenir les exigences du cadre
get_framework_requirements() {
    local framework="$1"
    
    case "$framework" in
        "hipaa")
            echo '{"encryption_required": true, "audit_required": true, "data_minimization": true, "access_controls": true}'
            ;;
        "rgpd")
            echo '{"consent_required": true, "data_portability": true, "right_to_erasure": true, "privacy_by_design": true}'
            ;;
        "sox")
            echo '{"financial_controls": true, "audit_trails": true, "segregation_of_duties": true, "data_integrity": true}'
            ;;
        "ferpa")
            echo '{"student_privacy": true, "parental_consent": true, "educational_purpose": true, "limited_disclosure": true}'
            ;;
        *)
            echo '{"general_security": true, "basic_audit": true}'
            ;;
    esac
}

# Évaluer le statut de conformité
assess_compliance_status() {
    local framework="$1"
    
    # Évaluation de conformité simplifiée
    local compliance_score=0
    local total_checks=0
    
    # Vérifier le chiffrement
    total_checks=$((total_checks + 1))
    if system_profiler SPStorageDataType | grep -q "Encrypted: Yes"; then
        compliance_score=$((compliance_score + 1))
    fi
    
    # Vérifier la journalisation d'audit
    total_checks=$((total_checks + 1))
    if [[ -f "$LOG_FILE" ]]; then
        compliance_score=$((compliance_score + 1))
    fi
    
    local compliance_percentage
    compliance_percentage=$(awk "BEGIN {printf \"%.0f\", ($compliance_score/$total_checks)*100}")
    
    echo "{\"score\": $compliance_score, \"total_checks\": $total_checks, \"percentage\": $compliance_percentage, \"status\": \"$([ $compliance_percentage -ge 80 ] && echo 'compliant' || echo 'non_compliant')\"}"
}

# Générer des recommandations de conformité
generate_compliance_recommendations() {
    local framework="$1"
    
    local recommendations=()
    
    # Vérifier les problèmes de conformité courants
    if ! system_profiler SPStorageDataType | grep -q "Encrypted: Yes"; then
        recommendations+=("Activer le chiffrement FileVault")
    fi
    
    if [[ ! -f "$LOG_FILE" ]]; then
        recommendations+=("Configurer la journalisation d'audit complète")
    fi
    
    # Recommandations spécifiques au cadre
    case "$framework" in
        "hipaa")
            recommendations+=("Implémenter les contrôles d'accès aux données" "Configurer la gestion des données PHI")
            ;;
        "rgpd")
            recommendations+=("Implémenter la gestion du consentement" "Configurer les politiques de rétention des données")
            ;;
    esac
    
    # Convertir en tableau JSON
    local json_recommendations="["
    local first=true
    for rec in "${recommendations[@]}"; do
        if [[ "$first" == true ]]; then
            first=false
        else
            json_recommendations+=","
        fi
        json_recommendations+="\"$rec\""
    done
    json_recommendations+="]"
    
    echo "$json_recommendations"
}

# Calculer le niveau de risque
calculate_risk_level() {
    local framework="$1"
    
    local risk_factors=0
    
    # Vérifier les configurations à haut risque
    if discover_apple_ids | jq -r '.summary.users_with_apple_id' | awk '$1 > 0 {exit 1}'; then
        risk_factors=$((risk_factors + 1))
    fi
    
    if [[ $risk_factors -ge 3 ]]; then
        echo "high"
    elif [[ $risk_factors -ge 1 ]]; then
        echo "medium"
    else
        echo "low"
    fi
}

# Fonction d'exécution principale
main() {
    local action="${1:-discover}"
    local parameter="$2"
    local additional_param="$3"
    
    log_action "=== Démarrage de la Gestion Apple ID MacFleet ==="
    log_action "Action : $action"
    log_action "Paramètre : ${parameter:-N/A}"
    
    # Configuration
    setup_directories
    
    case "$action" in
        "discover")
            discover_apple_ids
            ;;
        "policy")
            if [[ -z "$parameter" ]]; then
                echo "Politiques de confidentialité disponibles :"
                for policy in "${!PRIVACY_POLICIES[@]}"; do
                    echo "  - $policy : ${PRIVACY_POLICIES[$policy]}"
                done
                echo ""
                echo "Usage : $0 policy <nom_politique> [nom_utilisateur]"
                exit 1
            fi
            apply_privacy_policy "$parameter" "$additional_param"
            ;;
        "compliance")
            if [[ -z "$parameter" ]]; then
                echo "Cadres de conformité disponibles :"
                for framework in "${!COMPLIANCE_FRAMEWORKS[@]}"; do
                    echo "  - $framework : ${COMPLIANCE_FRAMEWORKS[$framework]}"
                done
                echo ""
                echo "Usage : $0 compliance <cadre> [type_rapport]"
                exit 1
            fi
            generate_compliance_report "$parameter" "$additional_param"
            ;;
        "user")
            if [[ -z "$parameter" ]]; then
                echo "Usage : $0 user <nom_utilisateur>"
                exit 1
            fi
            get_detailed_apple_id_info "$parameter"
            ;;
        *)
            echo "Usage : $0 {discover|policy|compliance|user}"
            echo "  discover    - Découvrir les Apple ID sur tous les utilisateurs"
            echo "  policy      - Appliquer les politiques de confidentialité"
            echo "  compliance  - Générer des rapports de conformité"
            echo "  user        - Obtenir des informations détaillées pour un utilisateur spécifique"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion Apple ID terminée ==="
}

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

Analyse Apple ID Avancée

Analytique d'Utilisation des Services

#!/bin/bash

# Analyser les modèles d'utilisation des services Apple
analyze_service_usage() {
    echo "=== Analytique d'Utilisation des Services Apple ==="
    
    local analytics_report="$REPORTS_DIR/service_analytics_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$analytics_report" << EOF
{
    "analytics_metadata": {
        "timestamp": "$(date -Iseconds)",
        "hostname": "$(hostname)"
    },
    "service_usage": {
EOF

    # Analyser l'utilisation iCloud
    local icloud_users=0
    local total_users=0
    
    for user in $(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}'); do
        total_users=$((total_users + 1))
        local userHome
        userHome=$(dscl . read /Users/"$user" NFSHomeDirectory | sed 's/NFSHomeDirectory://' | grep "/" | sed 's/^[ \t]*//')
        
        if [[ "$(check_icloud_status "$userHome")" == "true" ]]; then
            icloud_users=$((icloud_users + 1))
        fi
    done
    
    cat >> "$analytics_report" << EOF
        "icloud": {
            "users_enabled": $icloud_users,
            "total_users": $total_users,
            "adoption_rate": $(awk "BEGIN {printf \"%.2f\", ($icloud_users/$total_users)*100}")
        }
    }
}
EOF

    echo "📊 Analytique d'utilisation des services : $analytics_report"
}

Évaluation d'Impact sur la Confidentialité

#!/bin/bash

# Effectuer une évaluation d'impact sur la confidentialité
privacy_impact_assessment() {
    local assessment_type="${1:-standard}"
    
    echo "=== Évaluation d'Impact sur la Confidentialité ==="
    log_action "Démarrage de l'évaluation d'impact sur la confidentialité : $assessment_type"
    
    local pia_report="$REPORTS_DIR/privacy_assessment_$(date '+%Y%m%d_%H%M%S').json"
    
    cat > "$pia_report" << EOF
{
    "assessment_metadata": {
        "timestamp": "$(date -Iseconds)",
        "assessment_type": "$assessment_type",
        "hostname": "$(hostname)"
    },
    "privacy_risks": [
EOF

    local risks=()
    
    # Vérifier les risques de synchronisation de données
    local sync_users
    sync_users=$(discover_apple_ids | jq -r '.user_accounts[] | select(.services.icloud.enabled == true) | .username' | wc -l)
    
    if [[ $sync_users -gt 0 ]]; then
        risks+=("Synchronisation de données vers iCloud activée pour $sync_users utilisateurs")
    fi
    
    # Vérifier les services de localisation
    if pgrep -f "locationd" >/dev/null; then
        risks+=("Services de localisation actifs - préoccupation de confidentialité potentielle")
    fi
    
    # Ajouter les risques au rapport
    local first=true
    for risk in "${risks[@]}"; do
        if [[ "$first" == true ]]; then
            first=false
        else
            echo "," >> "$pia_report"
        fi
        echo "        \"$risk\"" >> "$pia_report"
    done
    
    cat >> "$pia_report" << EOF
    ],
    "recommendations": [
        "Implémenter les politiques de gouvernance des données",
        "Configurer les contrôles de confidentialité",
        "Audits de confidentialité réguliers"
    ]
}
EOF

    log_action "✅ Évaluation d'impact sur la confidentialité terminée : $pia_report"
    echo "$pia_report"
}

Meilleures Pratiques

🚀 Gestion d'Identité

  • Scans de découverte réguliers pour suivre l'utilisation des Apple ID dans la flotte
  • Application de politiques centralisées pour des contrôles de confidentialité cohérents
  • Surveillance automatisée pour les changements d'Apple ID non autorisés
  • Pistes d'audit complètes pour la conformité et la sécurité

🔐 Directives de Sécurité

  • Application de politiques de confidentialité basées sur les exigences organisationnelles
  • Principes de minimisation des données pour les environnements sensibles
  • Contrôles d'accès pour les configurations de services Apple
  • Évaluations de sécurité régulières des pratiques de gestion d'identité

📋 Gestion de Conformité

  • Politiques spécifiques au cadre (HIPAA, RGPD, SOX, FERPA)
  • Rapports de conformité réguliers avec évaluation automatisée
  • Approche basée sur les risques pour la gestion d'identité
  • Documentation et pistes d'audit pour les exigences réglementaires

🔍 Surveillance et Maintenance

  • Surveillance continue du statut Apple ID et de l'utilisation des services
  • Détection de changements avec alerte automatisée
  • Sauvegarde régulière des configurations d'identité
  • Optimisation des performances pour les déploiements à grande échelle

Notes Importantes

  • La conformité de confidentialité nécessite un équilibre soigneux entre fonctionnalité et protection des données
  • Le consentement de l'utilisateur peut être requis pour certaines activités de surveillance
  • La gestion Apple ID doit s'aligner avec les politiques de confidentialité organisationnelles
  • Mises à jour régulières nécessaires car Apple introduit de nouveaux services et fonctionnalités de confidentialité
  • Considérations légales varient selon la juridiction et le secteur industriel

Gestion d'Inventaire App Store sur macOS

Gérez et suivez efficacement les applications App Store sur vos appareils MacFleet avec des outils d'inventaire complets. Ce tutoriel couvre la découverte d'applications, la conformité des licences, l'analyse d'utilisation et les rapports de niveau entreprise pour les applications Mac App Store.

Comprendre la Gestion des Applications App Store

Les applications App Store sur macOS contiennent des identifiants uniques et des reçus qui permettent le suivi d'entreprise :

Composants Principaux

  • Reçus MAS - Reçus numériques stockés dans les bundles d'applications pour vérification
  • Identifiants Bundle - Identification unique d'application dans l'écosystème App Store
  • Suivi Version - Gestion version d'application et conformité mise à jour
  • Gestion Licence - Surveillance allocation et conformité licence d'entreprise
  • Analyse Utilisation - Modèles d'utilisation d'application et métriques d'adoption

Avantages Entreprise

  • Gestion Actifs Logiciels - Inventaire complet des applications App Store
  • Conformité Licence - Suivi licences et allocations d'applications d'entreprise
  • Surveillance Sécurité - Identifier applications non autorisées ou non conformes
  • Optimisation Coûts - Optimiser dépenses App Store et utilisation licences
  • Application Politique - Assurer conformité avec politiques d'applications d'entreprise

Découverte Basique des Applications App Store

Liste Simple Applications App Store

#!/bin/bash

# Découverte basique applications App Store
echo "📱 Découverte Applications App Store"
echo "===================================="
echo ""

app_store_apps=$(find /Applications -path '*Contents/_MASReceipt/receipt' -maxdepth 4 -print | \
    sed 's#.app/Contents/_MASReceipt/receipt#.app#g; s#/Applications/##')

if [[ -n "$app_store_apps" ]]; then
    echo "Applications App Store Trouvées :"
    echo "$app_store_apps" | sort
    
    local app_count=$(echo "$app_store_apps" | wc -l | xargs)
    echo ""
    echo "Total applications App Store : $app_count"
else
    echo "Aucune application App Store trouvée dans /Applications"
fi

Découverte Améliorée avec Détails

#!/bin/bash

# Découverte complète applications App Store avec métadonnées
discover_app_store_apps() {
    echo "🔍 Découverte Complète Applications App Store"
    echo "============================================="
    echo ""
    
    local apps_found=0
    local total_size=0
    
    # Trouver toutes applications App Store avec reçus
    while IFS= read -r -d '' app_path; do
        if [[ -n "$app_path" ]]; then
            local app_name=$(basename "$app_path" .app)
            local app_bundle_id=""
            local app_version=""
            local app_size=""
            local install_date=""
            
            # Obtenir identifiant bundle
            if [[ -f "$app_path/Contents/Info.plist" ]]; then
                app_bundle_id=$(defaults read "$app_path/Contents/Info.plist" CFBundleIdentifier 2>/dev/null || echo "Inconnu")
                app_version=$(defaults read "$app_path/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null || echo "Inconnue")
            fi
            
            # Obtenir taille application
            if [[ -d "$app_path" ]]; then
                app_size=$(du -sh "$app_path" 2>/dev/null | cut -f1 || echo "Inconnue")
                # Convertir taille en octets pour totalisation
                local size_bytes=$(du -s "$app_path" 2>/dev/null | cut -f1 || echo "0")
                total_size=$((total_size + size_bytes))
            fi
            
            # Obtenir date installation/modification
            if [[ -f "$app_path/Contents/_MASReceipt/receipt" ]]; then
                install_date=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M:%S" "$app_path/Contents/_MASReceipt/receipt" 2>/dev/null || echo "Inconnue")
            fi
            
            echo "App : $app_name"
            echo "  ID Bundle : $app_bundle_id"
            echo "  Version : $app_version"
            echo "  Taille : $app_size"
            echo "  Date Installation : $install_date"
            echo "  Chemin : $app_path"
            echo ""
            
            ((apps_found++))
        fi
    done < <(find /Applications -name "*.app" -path '*Contents/_MASReceipt/receipt' -exec dirname {} \; 2>/dev/null | \
             sed 's|/Contents/_MASReceipt||' | sort -u | tr '\n' '\0')
    
    # Statistiques résumé
    echo "=== Résumé Découverte ==="
    echo "Total applications App Store trouvées : $apps_found"
    echo "Espace disque total utilisé : $(echo "scale=2; $total_size / 1024 / 1024" | bc 2>/dev/null || echo "Inconnu") MB"
    echo "Taille moyenne application : $(echo "scale=2; $total_size / $apps_found / 1024 / 1024" | bc 2>/dev/null || echo "Inconnue") MB"
    echo "Scan terminé : $(date)"
    
    return $apps_found
}

# Exécuter découverte
discover_app_store_apps

Gestion d'Inventaire d'Applications d'Entreprise

Script d'Inventaire Complet

#!/bin/bash

# Gestion inventaire App Store d'entreprise
generate_app_store_inventory() {
    local output_format="${1:-json}"
    local include_metadata="${2:-true}"
    local export_path="${3:-/tmp}"
    
    echo "📊 Génération Inventaire App Store d'Entreprise"
    echo "==============================================="
    echo "Format sortie : $output_format"
    echo "Inclure métadonnées : $include_metadata"
    echo ""
    
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local hostname=$(hostname)
    local report_file="$export_path/app_store_inventory_${hostname}_${timestamp}"
    
    # Informations système
    local device_info=$(system_profiler SPHardwareDataType | grep -E "(Model Name|Serial Number)" | \
                        awk -F': ' '{print $2}' | xargs | tr ' ' '_')
    local macos_version=$(sw_vers -productVersion)
    local current_user=$(stat -f%Su /dev/console 2>/dev/null || echo "$USER")
    
    # Initialiser structure données inventaire
    local inventory_data=""
    local app_count=0
    local total_size_bytes=0
    
    echo "Scan applications..."
    
    # Découvrir toutes applications App Store
    while IFS= read -r -d '' app_path; do
        if [[ -d "$app_path" && -f "$app_path/Contents/_MASReceipt/receipt" ]]; then
            local app_name=$(basename "$app_path" .app)
            local bundle_id=""
            local version=""
            local build_version=""
            local size_bytes=0
            local size_human=""
            local install_date=""
            local last_modified=""
            local executable_path=""
            local app_category=""
            local developer_name=""
            local app_store_url=""
            
            # Extraire métadonnées application
            if [[ -f "$app_path/Contents/Info.plist" ]]; then
                bundle_id=$(defaults read "$app_path/Contents/Info.plist" CFBundleIdentifier 2>/dev/null || echo "inconnu")
                version=$(defaults read "$app_path/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null || echo "inconnue")
                build_version=$(defaults read "$app_path/Contents/Info.plist" CFBundleVersion 2>/dev/null || echo "inconnue")
                executable_path=$(defaults read "$app_path/Contents/Info.plist" CFBundleExecutable 2>/dev/null || echo "inconnu")
                app_category=$(defaults read "$app_path/Contents/Info.plist" LSApplicationCategoryType 2>/dev/null || echo "inconnue")
            fi
            
            # Obtenir taille application
            size_bytes=$(du -sk "$app_path" 2>/dev/null | cut -f1 || echo "0")
            size_bytes=$((size_bytes * 1024))  # Convertir KB en octets
            size_human=$(du -sh "$app_path" 2>/dev/null | cut -f1 || echo "inconnue")
            total_size_bytes=$((total_size_bytes + size_bytes))
            
            # Obtenir horodatages
            install_date=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M:%S" "$app_path/Contents/_MASReceipt/receipt" 2>/dev/null || echo "inconnue")
            last_modified=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M:%S" "$app_path" 2>/dev/null || echo "inconnue")
            
            # Essayer d'extraire métadonnées supplémentaires si demandé
            if [[ "$include_metadata" == "true" ]]; then
                # Chercher identifiant équipe
                local team_id=""
                if command -v codesign >/dev/null 2>&1; then
                    team_id=$(codesign -dv "$app_path" 2>&1 | grep "TeamIdentifier" | awk -F'=' '{print $2}' || echo "inconnu")
                fi
                
                # Vérifier si application en cours d'exécution
                local is_running="false"
                if pgrep -f "$app_name" >/dev/null 2>&1; then
                    is_running="true"
                fi
                
                # Obtenir permissions application (vérification simplifiée)
                local has_camera_permission="inconnue"
                local has_microphone_permission="inconnue"
                local has_location_permission="inconnue"
                
                if [[ -f "$app_path/Contents/Info.plist" ]]; then
                    if defaults read "$app_path/Contents/Info.plist" NSCameraUsageDescription >/dev/null 2>&1; then
                        has_camera_permission="demandee"
                    else
                        has_camera_permission="non_demandee"
                    fi
                    
                    if defaults read "$app_path/Contents/Info.plist" NSMicrophoneUsageDescription >/dev/null 2>&1; then
                        has_microphone_permission="demandee"
                    else
                        has_microphone_permission="non_demandee"
                    fi
                    
                    if defaults read "$app_path/Contents/Info.plist" NSLocationUsageDescription >/dev/null 2>&1; then
                        has_location_permission="demandee"
                    else
                        has_location_permission="non_demandee"
                    fi
                fi
            fi
            
            # Formater sortie basée sur format demandé
            case "$output_format" in
                "json")
                    local app_json="{
                        \"nom_app\": \"$app_name\",
                        \"bundle_id\": \"$bundle_id\",
                        \"version\": \"$version\",
                        \"version_build\": \"$build_version\",
                        \"taille_octets\": $size_bytes,
                        \"taille_humaine\": \"$size_human\",
                        \"date_installation\": \"$install_date\",
                        \"derniere_modification\": \"$last_modified\",
                        \"chemin_app\": \"$app_path\",
                        \"chemin_executable\": \"$executable_path\",
                        \"categorie\": \"$app_category\""
                    
                    if [[ "$include_metadata" == "true" ]]; then
                        app_json="$app_json,
                        \"id_equipe\": \"$team_id\",
                        \"en_cours_execution\": $is_running,
                        \"permission_camera\": \"$has_camera_permission\",
                        \"permission_microphone\": \"$has_microphone_permission\",
                        \"permission_localisation\": \"$has_location_permission\""
                    fi
                    
                    app_json="$app_json}"
                    
                    if [[ $app_count -gt 0 ]]; then
                        inventory_data="$inventory_data,$app_json"
                    else
                        inventory_data="$app_json"
                    fi
                    ;;
                    
                "csv")
                    if [[ $app_count -eq 0 ]]; then
                        # En-tête CSV
                        if [[ "$include_metadata" == "true" ]]; then
                            inventory_data="Nom App,Bundle ID,Version,Version Build,Taille (Octets),Taille (Humaine),Date Installation,Dernière Modification,Chemin App,Catégorie,ID Équipe,En Cours Exécution,Permission Caméra,Permission Microphone,Permission Localisation"
                        else
                            inventory_data="Nom App,Bundle ID,Version,Version Build,Taille (Octets),Taille (Humaine),Date Installation,Dernière Modification,Chemin App,Catégorie"
                        fi
                    fi
                    
                    local csv_line="\"$app_name\",\"$bundle_id\",\"$version\",\"$build_version\",$size_bytes,\"$size_human\",\"$install_date\",\"$last_modified\",\"$app_path\",\"$app_category\""
                    
                    if [[ "$include_metadata" == "true" ]]; then
                        csv_line="$csv_line,\"$team_id\",$is_running,\"$has_camera_permission\",\"$has_microphone_permission\",\"$has_location_permission\""
                    fi
                    
                    inventory_data="$inventory_data\n$csv_line"
                    ;;
                    
                "text"|*)
                    inventory_data="$inventory_data
App : $app_name
  Bundle ID : $bundle_id
  Version : $version ($build_version)
  Taille : $size_human ($size_bytes octets)
  Date Installation : $install_date
  Dernière Modification : $last_modified
  Chemin : $app_path
  Catégorie : $app_category"
                    
                    if [[ "$include_metadata" == "true" ]]; then
                        inventory_data="$inventory_data
  ID Équipe : $team_id
  Actuellement En Cours : $is_running
  Permission Caméra : $has_camera_permission
  Permission Microphone : $has_microphone_permission
  Permission Localisation : $has_location_permission"
                    fi
                    
                    inventory_data="$inventory_data
"
                    ;;
            esac
            
            ((app_count++))
        fi
    done < <(find /Applications -name "*.app" -type d -print0 2>/dev/null)
    
    # Générer rapport final
    local total_size_human=$(echo "scale=2; $total_size_bytes / 1024 / 1024 / 1024" | bc 2>/dev/null || echo "inconnue")
    
    case "$output_format" in
        "json")
            local final_report="{
                \"metadonnees_rapport\": {
                    \"horodatage\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\",
                    \"nom_hote\": \"$hostname\",
                    \"info_appareil\": \"$device_info\",
                    \"version_macos\": \"$macos_version\",
                    \"utilisateur_actuel\": \"$current_user\",
                    \"total_apps\": $app_count,
                    \"taille_totale_octets\": $total_size_bytes,
                    \"taille_totale_gb\": \"$total_size_human GB\"
                },
                \"applications\": [$inventory_data]
            }"
            
            echo "$final_report" > "${report_file}.json"
            echo "✅ Rapport JSON sauvegardé dans : ${report_file}.json"
            ;;
            
        "csv")
            echo -e "$inventory_data" > "${report_file}.csv"
            echo "✅ Rapport CSV sauvegardé dans : ${report_file}.csv"
            ;;
            
        "text"|*)
            {
                echo "Rapport d'Inventaire App Store MacFleet"
                echo "======================================="
                echo "Généré : $(date)"
                echo "Nom d'hôte : $hostname"
                echo "Appareil : $device_info"
                echo "Version macOS : $macos_version"
                echo "Utilisateur Actuel : $current_user"
                echo "Total Apps : $app_count"
                echo "Taille Totale : $total_size_human GB"
                echo ""
                echo "Applications :"
                echo "============="
                echo "$inventory_data"
            } > "${report_file}.txt"
            echo "✅ Rapport texte sauvegardé dans : ${report_file}.txt"
            ;;
    esac
    
    # Sortie résumé
    echo ""
    echo "=== Résumé Inventaire ==="
    echo "Apps découvertes : $app_count"
    echo "Taille totale : $total_size_human GB"
    echo "Format rapport : $output_format"
    echo "Emplacement rapport : $report_file"
    echo ""
    
    return $app_count
}

# Exemples d'utilisation
echo "📊 Gestion d'Inventaire App Store d'Entreprise"
echo ""
echo "1. Générer inventaire JSON avec métadonnées"
generate_app_store_inventory "json" "true" "/tmp"
echo ""

echo "2. Générer inventaire CSV (basique)"
generate_app_store_inventory "csv" "false" "/tmp"
echo ""

echo "3. Générer inventaire texte avec métadonnées"
generate_app_store_inventory "text" "true" "/tmp"

Analyse Conformité et Sécurité Applications

#!/bin/bash

# Analyse conformité et sécurité applications App Store
analyze_app_compliance() {
    echo "🔒 Analyse Conformité Applications App Store"
    echo "==========================================="
    echo ""
    
    local compliance_issues=0
    local security_concerns=0
    local policy_violations=0
    
    # Définir règles politique d'entreprise
    local blocked_apps=("Jeux" "Réseaux Sociaux" "Rencontres")  # Exemples catégories
    local required_apps=("Microsoft Word" "Microsoft Excel" "Slack")  # Exemples apps requises
    local max_app_age_days=365  # Apps plus anciennes que 1 an signalées
    local min_security_permissions=("Caméra" "Microphone" "Localisation")
    
    echo "Analyse applications App Store pour conformité..."
    echo ""
    
    # Suivre applications requises
    local found_required_apps=()
    local missing_required_apps=()
    
    # Analyser chaque application App Store
    while IFS= read -r -d '' app_path; do
        if [[ -d "$app_path" && -f "$app_path/Contents/_MASReceipt/receipt" ]]; then
            local app_name=$(basename "$app_path" .app)
            local bundle_id=""
            local version=""
            local category=""
            local install_date=""
            local days_since_install=""
            
            echo "Analyse : $app_name"
            
            # Obtenir métadonnées application
            if [[ -f "$app_path/Contents/Info.plist" ]]; then
                bundle_id=$(defaults read "$app_path/Contents/Info.plist" CFBundleIdentifier 2>/dev/null || echo "inconnu")
                version=$(defaults read "$app_path/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null || echo "inconnue")
                category=$(defaults read "$app_path/Contents/Info.plist" LSApplicationCategoryType 2>/dev/null || echo "inconnue")
            fi
            
            # Obtenir date installation et calculer âge
            if [[ -f "$app_path/Contents/_MASReceipt/receipt" ]]; then
                install_date=$(stat -f "%Sm" -t "%Y-%m-%d" "$app_path/Contents/_MASReceipt/receipt" 2>/dev/null || echo "inconnue")
                if [[ "$install_date" != "inconnue" ]]; then
                    local install_epoch=$(date -j -f "%Y-%m-%d" "$install_date" "+%s" 2>/dev/null || echo "0")
                    local current_epoch=$(date "+%s")
                    days_since_install=$(( (current_epoch - install_epoch) / 86400 ))
                fi
            fi
            
            # Vérifier contre applications/catégories bloquées
            local is_blocked=false
            for blocked_category in "${blocked_apps[@]}"; do
                if [[ "$category" =~ "$blocked_category" ]] || [[ "$app_name" =~ "$blocked_category" ]]; then
                    echo "  ❌ VIOLATION POLITIQUE : Catégorie app '$category' est bloquée"
                    is_blocked=true
                    ((policy_violations++))
                    break
                fi
            done
            
            # Vérifier âge application
            if [[ -n "$days_since_install" && "$days_since_install" -gt "$max_app_age_days" ]]; then
                echo "  ⚠️ CONFORMITÉ : App plus ancienne que $max_app_age_days jours ($days_since_install jours)"
                ((compliance_issues++))
            fi
            
            # Vérifier permissions sécurité
            local permission_count=0
            if [[ -f "$app_path/Contents/Info.plist" ]]; then
                if defaults read "$app_path/Contents/Info.plist" NSCameraUsageDescription >/dev/null 2>&1; then
                    echo "  🔒 SÉCURITÉ : App demande accès caméra"
                    ((permission_count++))
                fi
                
                if defaults read "$app_path/Contents/Info.plist" NSMicrophoneUsageDescription >/dev/null 2>&1; then
                    echo "  🔒 SÉCURITÉ : App demande accès microphone"
                    ((permission_count++))
                fi
                
                if defaults read "$app_path/Contents/Info.plist" NSLocationUsageDescription >/dev/null 2>&1; then
                    echo "  🔒 SÉCURITÉ : App demande accès localisation"
                    ((permission_count++))
                fi
                
                if [[ "$permission_count" -gt 2 ]]; then
                    echo "  ⚠️ PRÉOCCUPATION SÉCURITÉ : App demande permissions sensibles multiples"
                    ((security_concerns++))
                fi
            fi
            
            # Vérifier contre applications requises
            for required_app in "${required_apps[@]}"; do
                if [[ "$app_name" =~ "$required_app" ]]; then
                    found_required_apps+=("$required_app")
                fi
            done
            
            # Vérification signature code
            if command -v codesign >/dev/null 2>&1; then
                if ! codesign -v "$app_path" >/dev/null 2>&1; then
                    echo "  ❌ SÉCURITÉ : Signature code invalide"
                    ((security_concerns++))
                fi
            fi
            
            echo "  ✅ Analyse terminée"
            echo ""
        fi
    done < <(find /Applications -name "*.app" -type d -print0 2>/dev/null)
    
    # Vérifier applications requises manquantes
    for required_app in "${required_apps[@]}"; do
        local found=false
        for found_app in "${found_required_apps[@]}"; do
            if [[ "$found_app" == "$required_app" ]]; then
                found=true
                break
            fi
        done
        
        if [[ "$found" == "false" ]]; then
            missing_required_apps+=("$required_app")
        fi
    done
    
    # Générer rapport conformité
    echo "=== Rapport Analyse Conformité ==="
    echo "Violations politique : $policy_violations"
    echo "Problèmes conformité : $compliance_issues"
    echo "Préoccupations sécurité : $security_concerns"
    echo ""
    
    if [[ ${#missing_required_apps[@]} -gt 0 ]]; then
        echo "Applications requises manquantes :"
        for missing_app in "${missing_required_apps[@]}"; do
            echo "  - $missing_app"
        done
        echo ""
    fi
    
    if [[ ${#found_required_apps[@]} -gt 0 ]]; then
        echo "Applications requises trouvées :"
        for found_app in "${found_required_apps[@]}"; do
            echo "  ✅ $found_app"
        done
        echo ""
    fi
    
    # Score conformité global
    local total_issues=$((policy_violations + compliance_issues + security_concerns + ${#missing_required_apps[@]}))
    if [[ "$total_issues" -eq 0 ]]; then
        echo "🎉 STATUT CONFORMITÉ : ENTIÈREMENT CONFORME"
    elif [[ "$total_issues" -le 3 ]]; then
        echo "⚠️ STATUT CONFORMITÉ : PROBLÈMES MINEURS ($total_issues problèmes)"
    else
        echo "❌ STATUT CONFORMITÉ : PROBLÈMES MAJEURS ($total_issues problèmes)"
    fi
    
    return $total_issues
}

# Exécuter analyse conformité
analyze_app_compliance

Gestion Flotte et Rapports

Gestion Applications Flotte d'Entreprise

#!/bin/bash

# Gestion App Store flotte d'entreprise
manage_fleet_app_inventory() {
    local operation="${1:-discover}"  # discover, report, compliance, update
    local fleet_config_file="${2:-/etc/macfleet/app_config.json}"
    local output_dir="${3:-/var/log/macfleet}"
    
    echo "🚀 Gestion App Store Entreprise MacFleet"
    echo "======================================="
    echo "Opération : $operation"
    echo "Fichier config : $fleet_config_file"
    echo "Répertoire sortie : $output_dir"
    echo ""
    
    # Assurer que répertoire sortie existe
    mkdir -p "$output_dir"
    
    # Identification appareil
    local device_id=$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F': ' '{print $2}' | xargs)
    local device_name=$(hostname)
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local report_file="$output_dir/fleet_app_report_${device_id}_${timestamp}.json"
    
    case "$operation" in
        "discover")
            echo "🔍 Mode Découverte Flotte"
            echo "========================="
            
            # Générer inventaire application complet
            local app_data=$(generate_comprehensive_app_data)
            
            # Créer rapport flotte
            local fleet_report="{
                \"info_appareil\": {
                    \"id_appareil\": \"$device_id\",
                    \"nom_appareil\": \"$device_name\",
                    \"horodatage\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\",
                    \"version_macos\": \"$(sw_vers -productVersion)\",
                    \"utilisateur_actuel\": \"$(stat -f%Su /dev/console 2>/dev/null || echo "$USER")\"
                },
                \"inventaire_apps\": $app_data,
                \"operation\": \"decouverte_flotte\"
            }"
            
            echo "$fleet_report" > "$report_file"
            echo "✅ Rapport découverte flotte sauvegardé : $report_file"
            ;;
            
        "compliance")
            echo "📋 Vérification Conformité Flotte"
            echo "================================="
            
            # Exécuter analyse conformité
            local compliance_result=$(analyze_fleet_compliance)
            
            # Créer rapport conformité
            local compliance_report="{
                \"info_appareil\": {
                    \"id_appareil\": \"$device_id\",
                    \"nom_appareil\": \"$device_name\",
                    \"horodatage\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\"
                },
                \"resultats_conformite\": $compliance_result,
                \"operation\": \"verification_conformite\"
            }"
            
            echo "$compliance_report" > "$report_file"
            echo "✅ Rapport conformité sauvegardé : $report_file"
            ;;
            
        "report")
            echo "📊 Mode Rapports Flotte"
            echo "======================="
            
            # Générer tous formats rapport
            echo "Génération rapports flotte complets..."
            
            generate_app_store_inventory "json" "true" "$output_dir"
            generate_app_store_inventory "csv" "true" "$output_dir"
            generate_app_store_inventory "text" "true" "$output_dir"
            
            echo "✅ Tous rapports flotte générés dans : $output_dir"
            ;;
            
        "update")
            echo "🔄 Vérification Mise à Jour Flotte"
            echo "==================================="
            
            # Vérifier mises à jour applications
            check_app_store_updates
            ;;
            
        *)
            echo "❌ Opération inconnue : $operation"
            echo "Opérations disponibles : discover, report, compliance, update"
            return 1
            ;;
    esac
    
    return 0
}

# Fonction auxiliaire pour générer données applications complètes
generate_comprehensive_app_data() {
    local apps_json="["
    local first_app=true
    
    while IFS= read -r -d '' app_path; do
        if [[ -d "$app_path" && -f "$app_path/Contents/_MASReceipt/receipt" ]]; then
            local app_name=$(basename "$app_path" .app)
            local bundle_id=$(defaults read "$app_path/Contents/Info.plist" CFBundleIdentifier 2>/dev/null || echo "inconnu")
            local version=$(defaults read "$app_path/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null || echo "inconnue")
            local size_bytes=$(du -sk "$app_path" 2>/dev/null | cut -f1 || echo "0")
            size_bytes=$((size_bytes * 1024))
            
            if [[ "$first_app" == "false" ]]; then
                apps_json="$apps_json,"
            fi
            
            apps_json="$apps_json{
                \"nom\": \"$app_name\",
                \"bundle_id\": \"$bundle_id\",
                \"version\": \"$version\",
                \"taille_octets\": $size_bytes,
                \"chemin\": \"$app_path\"
            }"
            
            first_app=false
        fi
    done < <(find /Applications -name "*.app" -type d -print0 2>/dev/null)
    
    apps_json="$apps_json]"
    echo "$apps_json"
}

# Vérifier mises à jour App Store
check_app_store_updates() {
    echo "Vérification mises à jour App Store disponibles..."
    
    # Utiliser softwareupdate pour vérifier mises à jour disponibles
    local updates_available=$(softwareupdate -l 2>/dev/null | grep -i "app store" || echo "")
    
    if [[ -n "$updates_available" ]]; then
        echo "📦 Mises à jour App Store disponibles :"
        echo "$updates_available"
    else
        echo "✅ Toutes applications App Store sont à jour"
    fi
    
    # Vérifier aussi Mac App Store directement si disponible
    if command -v mas >/dev/null 2>&1; then
        echo ""
        echo "Vérification avec mas-cli..."
        mas outdated 2>/dev/null || echo "mas-cli non disponible ou aucune mise à jour trouvée"
    fi
}

# Exemples d'utilisation
echo "Exemples Gestion Flotte :"
echo "========================="
echo ""

echo "1. Mode découverte :"
manage_fleet_app_inventory "discover"
echo ""

echo "2. Vérification conformité :"
manage_fleet_app_inventory "compliance"
echo ""

echo "3. Générer tous rapports :"
manage_fleet_app_inventory "report"

Intégration App Store Connect

Gestion Applications d'Entreprise avec App Store Connect

#!/bin/bash

# Intégration App Store Connect d'entreprise pour gestion licences
manage_app_store_licenses() {
    echo "📄 Gestion Licences App Store Connect"
    echo "====================================="
    echo ""
    
    # Note : Ceci nécessite accès App Store Connect d'entreprise
    # et configuration appropriée identifiants API
    
    local license_report_file="/tmp/app_store_licenses_$(date +%Y%m%d_%H%M%S).json"
    
    echo "Analyse licences applications App Store..."
    echo ""
    
    # Suivre applications nécessitant potentiellement licences business
    local business_apps=()
    local consumer_apps=()
    local unknown_apps=()
    
    while IFS= read -r -d '' app_path; do
        if [[ -d "$app_path" && -f "$app_path/Contents/_MASReceipt/receipt" ]]; then
            local app_name=$(basename "$app_path" .app)
            local bundle_id=$(defaults read "$app_path/Contents/Info.plist" CFBundleIdentifier 2>/dev/null || echo "inconnu")
            
            # Catégories nécessitant typiquement licences business
            local business_categories=("Outils Développeur" "Business" "Productivité" "Graphisme & Design")
            local is_business_app=false
            
            # Vérifier si application est orientée business
            if [[ -f "$app_path/Contents/Info.plist" ]]; then
                local category=$(defaults read "$app_path/Contents/Info.plist" LSApplicationCategoryType 2>/dev/null || echo "inconnue")
                
                for biz_cat in "${business_categories[@]}"; do
                    if [[ "$category" =~ "$biz_cat" ]]; then
                        is_business_app=true
                        break
                    fi
                done
                
                # Vérifier aussi modèles applications business communes
                if [[ "$app_name" =~ (Microsoft|Adobe|Slack|Zoom|Teams|Office) ]]; then
                    is_business_app=true
                fi
            fi
            
            if [[ "$is_business_app" == "true" ]]; then
                business_apps+=("$app_name ($bundle_id)")
                echo "💼 Application business détectée : $app_name"
            else
                # Applications consommateur potentiellement acceptables
                if [[ "$app_name" =~ (Calculatrice|TextEdit|Safari|Mail|Photos) ]]; then
                    consumer_apps+=("$app_name ($bundle_id)")
                    echo "👤 Application consommateur : $app_name"
                else
                    unknown_apps+=("$app_name ($bundle_id)")
                    echo "❓ Catégorie inconnue : $app_name"
                fi
            fi
        fi
    done < <(find /Applications -name "*.app" -type d -print0 2>/dev/null)
    
    # Générer rapport conformité licence
    {
        echo "{"
        echo "  \"analyse_licence\": {"
        echo "    \"horodatage\": \"$(date -u +"%Y-%m-%dT%H:%M:%SZ")\","
        echo "    \"id_appareil\": \"$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F': ' '{print $2}' | xargs)\","
        echo "    \"apps_business\": ["
        
        local first=true
        for app in "${business_apps[@]}"; do
            if [[ "$first" == "false" ]]; then echo ","; fi
            echo "      \"$app\""
            first=false
        done
        
        echo "    ],"
        echo "    \"apps_consommateur\": ["
        
        first=true
        for app in "${consumer_apps[@]}"; do
            if [[ "$first" == "false" ]]; then echo ","; fi
            echo "      \"$app\""
            first=false
        done
        
        echo "    ],"
        echo "    \"apps_inconnues\": ["
        
        first=true
        for app in "${unknown_apps[@]}"; do
            if [[ "$first" == "false" ]]; then echo ","; fi
            echo "      \"$app\""
            first=false
        done
        
        echo "    ],"
        echo "    \"resume\": {"
        echo "      \"total_apps_business\": ${#business_apps[@]},"
        echo "      \"total_apps_consommateur\": ${#consumer_apps[@]},"
        echo "      \"total_apps_inconnues\": ${#unknown_apps[@]},"
        echo "      \"necessite_revision_licence\": $([[ ${#business_apps[@]} -gt 0 || ${#unknown_apps[@]} -gt 0 ]] && echo "true" || echo "false")"
        echo "    }"
        echo "  }"
        echo "}"
    } > "$license_report_file"
    
    echo ""
    echo "=== Résumé Analyse Licence ==="
    echo "Applications business trouvées : ${#business_apps[@]}"
    echo "Applications consommateur trouvées : ${#consumer_apps[@]}"
    echo "Applications inconnues trouvées : ${#unknown_apps[@]}"
    echo ""
    
    if [[ ${#business_apps[@]} -gt 0 || ${#unknown_apps[@]} -gt 0 ]]; then
        echo "⚠️ Révision licence requise pour applications business/inconnues"
        echo "📄 Rapport licence sauvegardé : $license_report_file"
    else
        echo "✅ Aucune préoccupation licence business détectée"
    fi
    
    return 0
}

# Exécuter gestion licence
manage_app_store_licenses

Notes Importantes

Fonctionnalités Gestion Entreprise

  • Inventaire Complet - Découverte et suivi complets applications App Store
  • Surveillance Conformité - Application politique et analyse sécurité
  • Gestion Licence - Intégration App Store Connect d'entreprise
  • Rapports Flotte - Rapports multi-format (JSON, CSV, texte) avec métadonnées
  • Analyse Sécurité - Audit permissions et vérification signature code
  • Gestion Mise à Jour - Détection et gestion mises à jour App Store

Système Reçu App Store

  • Reçus MAS - Preuve numérique achat App Store située dans Contents/_MASReceipt/receipt
  • Identification Bundle - Suivi application unique via CFBundleIdentifier
  • Suivi Version - Gestion version application et numéro build
  • Métadonnées Installation - Suivi date installation et modification
  • Vérification Licence - Conformité et allocation licence d'entreprise

Sécurité et Conformité

  • Audit Permissions - Surveillance accès caméra, microphone, localisation
  • Vérification Signature Code - Valider intégrité et authenticité application
  • Application Politique - Validation catégories applications bloquées et applications requises
  • Analyse Âge - Identifier applications obsolètes nécessitant mises à jour
  • Suivi Identifiant Équipe - Identification équipe développeur pour politiques entreprise

Exemples d'Utilisation

# Découverte basique applications App Store
find /Applications -path '*Contents/_MASReceipt/receipt' -maxdepth 4 -print | \
    sed 's#.app/Contents/_MASReceipt/receipt#.app#g; s#/Applications/##'

# Inventaire entreprise avec sortie JSON
generate_app_store_inventory "json" "true" "/tmp"

# Analyse conformité
analyze_app_compliance

# Gestion flotte - mode découverte
manage_fleet_app_inventory "discover"

# Gestion licence
manage_app_store_licenses

Gestion des Mises à Jour Automatiques de l'App Store sur macOS

Contrôlez et gérez les mises à jour automatiques de l'App Store sur vos appareils MacFleet pour optimiser l'utilisation de la bande passante, gérer les mises à jour de sécurité et maintenir la stabilité du système. Ce tutoriel couvre les politiques de mise à jour, la configuration d'entreprise et les stratégies complètes de gestion des mises à jour.

Comprendre les Mises à Jour Automatiques de l'App Store macOS

Les mises à jour automatiques de l'App Store sur macOS téléchargent et installent automatiquement les mises à jour d'applications depuis le Mac App Store. Cette fonctionnalité affecte :

  • Mises à Jour d'Applications - Installation automatique des mises à jour d'applications
  • Stockage Système - Les mises à jour téléchargées consomment de l'espace disque
  • Bande Passante Réseau - Les mises à jour se téléchargent en arrière-plan
  • Stabilité Système - Les nouvelles mises à jour peuvent introduire des bugs ou des problèmes de compatibilité

Considérations d'Entreprise

La gestion des mises à jour automatiques est cruciale pour les environnements d'entreprise :

  • Contrôle de la Bande Passante - Prévenir l'utilisation réseau inattendue
  • Gestion de la Sécurité - Contrôler quand les mises à jour de sécurité sont appliquées
  • Stabilité Système - Tester les mises à jour avant le déploiement
  • Gestion du Stockage - Prévenir les problèmes de stockage sur les appareils à espace limité
  • Exigences de Conformité - Certaines industries nécessitent un déploiement contrôlé des mises à jour

Contrôle de Base des Mises à Jour de l'App Store

Désactiver les Mises à Jour Automatiques

#!/bin/bash

# Désactiver les mises à jour automatiques de l'App Store
sudo defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE

echo "Mises à jour automatiques de l'App Store désactivées"
exit 0

Activer les Mises à Jour Automatiques

#!/bin/bash

# Activer les mises à jour automatiques de l'App Store
sudo defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool TRUE

echo "Mises à jour automatiques de l'App Store activées"
exit 0

Vérifier le Statut Actuel des Mises à Jour Automatiques

#!/bin/bash

# Vérifier le paramètre actuel de mise à jour automatique
auto_update_status=$(defaults read /Library/Preferences/com.apple.commerce.plist AutoUpdate 2>/dev/null || echo "Non Défini")

if [[ "$auto_update_status" == "1" ]]; then
    echo "Mises à Jour Automatiques de l'App Store : ACTIVÉES"
elif [[ "$auto_update_status" == "0" ]]; then
    echo "Mises à Jour Automatiques de l'App Store : DÉSACTIVÉES"
else
    echo "Mises à Jour Automatiques de l'App Store : PAR DÉFAUT (généralement activées)"
fi

Gestion Avancée des Mises à Jour

Configuration Complète de Politique de Mise à Jour

#!/bin/bash

# Gestion avancée des mises à jour de l'App Store avec validation
configure_app_store_updates() {
    local policy="$1"
    local schedule="$2"
    local dry_run="${3:-false}"
    
    # Valider les privilèges administrateur
    if [[ $EUID -ne 0 ]]; then
        echo "Erreur : Ce script nécessite des privilèges administrateur"
        echo "Veuillez exécuter avec sudo : sudo $0"
        exit 1
    fi
    
    echo "=== Configuration de la Politique de Mise à Jour de l'App Store : $policy ==="
    
    if [[ "$dry_run" == "true" ]]; then
        echo "MODE TEST - Aucun changement ne sera appliqué"
        return 0
    fi
    
    case "$policy" in
        "enterprise_controlled")
            echo "Application de la politique de mise à jour contrôlée d'entreprise..."
            
            # Désactiver les mises à jour automatiques pour un environnement contrôlé
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            
            # Désactiver le téléchargement automatique des mises à jour
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool FALSE
            
            # Désactiver l'installation des mises à jour critiques
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool FALSE
            
            echo "✓ Politique contrôlée d'entreprise appliquée"
            ;;
        "security_only")
            echo "Application de la politique de mise à jour sécurité uniquement..."
            
            # Désactiver les mises à jour générales d'applications
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            
            # Activer uniquement les mises à jour de sécurité critiques
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool TRUE
            
            echo "✓ Politique sécurité uniquement appliquée"
            ;;
        "scheduled_updates")
            echo "Application de la politique de mise à jour programmée..."
            
            # Désactiver les mises à jour immédiates
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            
            # Configurer la vérification programmée des mises à jour
            setup_scheduled_updates "$schedule"
            
            echo "✓ Politique de mise à jour programmée appliquée"
            ;;
        "bandwidth_conscious")
            echo "Application de la politique de mise à jour consciente de la bande passante..."
            
            # Désactiver les téléchargements automatiques
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool FALSE
            
            # Activer la vérification des mises à jour mais pas l'installation automatique
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            
            echo "✓ Politique consciente de la bande passante appliquée"
            ;;
        "full_auto")
            echo "Application de la politique de mise à jour entièrement automatique..."
            
            # Activer toutes les mises à jour automatiques
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool TRUE
            
            echo "✓ Politique de mise à jour entièrement automatique appliquée"
            ;;
        "disabled")
            echo "Désactivation de toutes les mises à jour automatiques..."
            
            # Désactiver toutes les fonctionnalités de mise à jour automatique
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool FALSE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool FALSE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool FALSE
            
            echo "✓ Toutes les mises à jour automatiques désactivées"
            ;;
        *)
            echo "Erreur : Politique inconnue '$policy'"
            echo "Politiques disponibles : enterprise_controlled, security_only, scheduled_updates, bandwidth_conscious, full_auto, disabled"
            return 1
            ;;
    esac
    
    # Vérifier la configuration
    verify_update_settings
}

# Vérifier les paramètres actuels de mise à jour
verify_update_settings() {
    echo ""
    echo "=== Configuration Actuelle des Mises à Jour ==="
    
    # Vérifier les mises à jour automatiques de l'App Store
    local app_store_auto=$(defaults read /Library/Preferences/com.apple.commerce.plist AutoUpdate 2>/dev/null || echo "Défaut")
    echo "Mises à Jour Automatiques App Store : $([ "$app_store_auto" == "1" ] && echo "Activées" || [ "$app_store_auto" == "0" ] && echo "Désactivées" || echo "Défaut (Activées)")"
    
    # Vérifier les paramètres de Software Update
    local auto_download=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload 2>/dev/null || echo "Défaut")
    echo "Téléchargement Automatique : $([ "$auto_download" == "1" ] && echo "Activé" || [ "$auto_download" == "0" ] && echo "Désactivé" || echo "Défaut")"
    
    local auto_check=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled 2>/dev/null || echo "Défaut")
    echo "Vérification Automatique : $([ "$auto_check" == "1" ] && echo "Activée" || [ "$auto_check" == "0" ] && echo "Désactivée" || echo "Défaut")"
    
    local critical_updates=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall 2>/dev/null || echo "Défaut")
    echo "Mises à Jour Critiques : $([ "$critical_updates" == "1" ] && echo "Activées" || [ "$critical_updates" == "0" ] && echo "Désactivées" || echo "Défaut")"
}

# Exemples d'utilisation
configure_app_store_updates "enterprise_controlled" "weekly"

Système de Gestion des Mises à Jour d'Entreprise App Store

#!/bin/bash

# Outil de Gestion des Mises à Jour de l'App Store MacFleet
# Gestion complète des politiques de mise à jour et surveillance pour les appareils de flotte

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_appstore_updates.log"
REPORT_DIR="/etc/macfleet/reports/updates"
CONFIG_DIR="/etc/macfleet/updates"
POLICY_DIR="/etc/macfleet/policies/updates"

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

# Modèles de politiques de mise à jour
declare -A UPDATE_POLICIES=(
    ["enterprise_strict"]="app_updates_disabled,system_updates_manual,security_updates_auto,bandwidth_priority_high"
    ["enterprise_balanced"]="app_updates_scheduled,system_updates_auto,security_updates_immediate,bandwidth_priority_medium"
    ["enterprise_liberal"]="app_updates_auto,system_updates_auto,security_updates_immediate,bandwidth_priority_low"
    ["kiosk_mode"]="app_updates_disabled,system_updates_disabled,security_updates_manual,bandwidth_priority_high"
    ["development"]="app_updates_auto,system_updates_prompt,security_updates_auto,bandwidth_priority_low"
    ["education"]="app_updates_scheduled,system_updates_scheduled,security_updates_auto,bandwidth_priority_medium"
    ["healthcare"]="app_updates_manual,system_updates_manual,security_updates_immediate,bandwidth_priority_high"
    ["financial"]="app_updates_disabled,system_updates_manual,security_updates_immediate,bandwidth_priority_high"
    ["retail"]="app_updates_scheduled,system_updates_auto,security_updates_auto,bandwidth_priority_medium"
    ["remote_work"]="app_updates_auto,system_updates_prompt,security_updates_auto,bandwidth_priority_medium"
)

# Plannings de mise à jour pour différents scénarios
declare -A UPDATE_SCHEDULES=(
    ["business_hours"]="weekdays_evening,09:00-17:00_block"
    ["maintenance_window"]="weekend_only,saturday_2am"
    ["off_peak"]="overnight,02:00-05:00"
    ["immediate"]="real_time,no_delay"
    ["weekly_batch"]="sunday_night,sunday_23:00"
    ["monthly_patch"]="first_sunday,monthly_02:00"
)

# Profils de gestion de bande passante
declare -A BANDWIDTH_PROFILES=(
    ["conservative"]="max_5mbps,off_peak_only,cellular_disabled"
    ["balanced"]="max_20mbps,business_hours_limited,cellular_security_only"
    ["unlimited"]="no_throttle,anytime,cellular_enabled"
    ["emergency_only"]="max_1mbps,security_updates_only,cellular_emergency"
)

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

# Application avancée des politiques de mise à jour
enforce_update_policy() {
    local policy_name="$1"
    local environment_type="${2:-enterprise}"
    local bandwidth_profile="${3:-balanced}"
    local dry_run="${4:-false}"
    
    log_action "Application de la politique de mise à jour : $policy_name (environnement : $environment_type, bande passante : $bandwidth_profile, dry_run : $dry_run)"
    
    if [[ -z "${UPDATE_POLICIES[$policy_name]}" ]]; then
        log_action "ERREUR : Politique inconnue '$policy_name'"
        echo "Politiques disponibles : ${!UPDATE_POLICIES[*]}"
        return 1
    fi
    
    # Analyser la configuration de politique
    IFS=',' read -ra POLICY_PARTS <<< "${UPDATE_POLICIES[$policy_name]}"
    local app_updates="${POLICY_PARTS[0]}"
    local system_updates="${POLICY_PARTS[1]}"
    local security_updates="${POLICY_PARTS[2]}"
    local bandwidth_priority="${POLICY_PARTS[3]}"
    
    echo "=== Application de la Politique de Mise à Jour : $policy_name ==="
    echo "Mises à Jour d'Applications : $app_updates"
    echo "Mises à Jour Système : $system_updates"
    echo "Mises à Jour de Sécurité : $security_updates"
    echo "Priorité Bande Passante : $bandwidth_priority"
    echo "Environnement : $environment_type"
    
    if [[ "$dry_run" == "true" ]]; then
        echo "MODE TEST - Aucun changement ne sera appliqué"
        return 0
    fi
    
    # Appliquer les paramètres de mise à jour d'applications
    apply_app_update_policy "$app_updates"
    
    # Appliquer les paramètres de mise à jour système
    apply_system_update_policy "$system_updates"
    
    # Appliquer les paramètres de mise à jour de sécurité
    apply_security_update_policy "$security_updates"
    
    # Appliquer la gestion de bande passante
    apply_bandwidth_management "$bandwidth_profile"
    
    # Configurer les paramètres spécifiques à l'environnement
    configure_environment_settings "$environment_type"
    
    # Générer un rapport de conformité de politique
    local report_file="$REPORT_DIR/policy_enforcement_${policy_name}_$(date +%Y%m%d_%H%M%S).json"
    generate_comprehensive_report "$policy_name" "$report_file"
    
    log_action "Application de politique de mise à jour terminée : $report_file"
    echo "$report_file"
}

# Appliquer les paramètres de politique de mise à jour d'applications
apply_app_update_policy() {
    local policy="$1"
    
    case "$policy" in
        "app_updates_disabled")
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            echo "✓ Mises à jour automatiques de l'App Store désactivées"
            ;;
        "app_updates_auto")
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool TRUE
            echo "✓ Mises à jour automatiques de l'App Store activées"
            ;;
        "app_updates_scheduled")
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            setup_scheduled_app_updates "weekly"
            echo "✓ Mises à jour de l'App Store programmées pour la fenêtre de maintenance hebdomadaire"
            ;;
        "app_updates_manual")
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            echo "✓ Mises à jour de l'App Store définies en manuel avec vérification automatique"
            ;;
    esac
}

# Appliquer les paramètres de politique de mise à jour système
apply_system_update_policy() {
    local policy="$1"
    
    case "$policy" in
        "system_updates_disabled")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool FALSE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool FALSE
            echo "✓ Mises à jour système complètement désactivées"
            ;;
        "system_updates_auto")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool TRUE
            echo "✓ Mises à jour système entièrement automatisées"
            ;;
        "system_updates_manual")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool FALSE
            echo "✓ Mises à jour système définies en installation manuelle"
            ;;
        "system_updates_prompt")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool TRUE
            # Configurer les invites utilisateur pour l'installation
            echo "✓ Mises à jour système définies pour inviter l'utilisateur à l'installation"
            ;;
        "system_updates_scheduled")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool TRUE
            setup_scheduled_system_updates "monthly"
            echo "✓ Mises à jour système programmées pour la maintenance mensuelle"
            ;;
    esac
}

# Appliquer les paramètres de politique de mise à jour de sécurité
apply_security_update_policy() {
    local policy="$1"
    
    case "$policy" in
        "security_updates_immediate")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool TRUE
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
            echo "✓ Mises à jour de sécurité définies en installation immédiate"
            ;;
        "security_updates_auto")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool TRUE
            echo "✓ Mises à jour de sécurité activées pour installation automatique"
            ;;
        "security_updates_manual")
            defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool FALSE
            echo "✓ Mises à jour de sécurité définies en installation manuelle"
            ;;
    esac
}

# Surveiller la conformité des mises à jour à travers la flotte
monitor_fleet_update_compliance() {
    local compliance_type="${1:-standard}"
    
    echo "=== Moniteur de Conformité des Mises à Jour de Flotte ==="
    
    # Vérifier le statut global de conformité
    local policy_violations=0
    local total_checks=0
    
    # Vérifier les paramètres de l'App Store
    local app_store_setting=$(defaults read /Library/Preferences/com.apple.commerce.plist AutoUpdate 2>/dev/null || echo "default")
    ((total_checks++))
    
    # Vérifier les mises à jour en attente qui violent la politique
    local pending_updates=$(softwareupdate -l 2>/dev/null | grep -c "recommended" || echo "0")
    
    if [[ "$pending_updates" -gt 0 && "$compliance_type" == "strict" ]]; then
        ((policy_violations++))
        echo "⚠️ Violation de Politique : Mises à jour en attente trouvées en mode de conformité strict"
    fi
    
    # Calculer le score de conformité
    local compliance_score=$((100 - (policy_violations * 100 / total_checks)))
    
    echo "Score de Conformité : $compliance_score%"
    echo "Violations de Politique : $policy_violations"
    echo "Vérifications Totales : $total_checks"
    echo "Mises à Jour en Attente : $pending_updates"
}

# Fonction d'exécution principale
main() {
    local action="${1:-status}"
    local param1="${2:-}"
    local param2="${3:-}"
    local param3="${4:-}"
    local param4="${5:-}"
    
    log_action "=== Gestion des Mises à Jour de l'App Store MacFleet Démarrée ==="
    log_action "Action : $action"
    
    # Assurer les privilèges requis pour les changements de configuration
    if [[ "$action" != "status" && "$action" != "help" && "$action" != "report" && $EUID -ne 0 ]]; then
        echo "Erreur : Cette action nécessite des privilèges administrateur"
        echo "Veuillez exécuter avec sudo : sudo $0 $*"
        exit 1
    fi
    
    case "$action" in
        "policy")
            if [[ -z "$param1" ]]; then
                echo "Politiques disponibles : ${!UPDATE_POLICIES[*]}"
                exit 1
            fi
            enforce_update_policy "$param1" "$param2" "$param3" "$param4"
            ;;
        "enable")
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool TRUE
            echo "✓ Mises à jour automatiques de l'App Store activées"
            ;;
        "disable")
            defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
            echo "✓ Mises à jour automatiques de l'App Store désactivées"
            ;;
        "check")
            echo "Vérification des mises à jour disponibles..."
            softwareupdate -l
            ;;
        "install")
            if [[ -n "$param1" ]]; then
                echo "Installation de la mise à jour spécifique : $param1"
                softwareupdate -i "$param1"
            else
                echo "Installation de toutes les mises à jour disponibles..."
                softwareupdate -i -a
            fi
            ;;
        "status")
            verify_update_settings
            ;;
        "compliance")
            monitor_fleet_update_compliance "$param1"
            ;;
        "reset")
            echo "Réinitialisation des paramètres de mise à jour de l'App Store aux valeurs par défaut..."
            defaults delete /Library/Preferences/com.apple.commerce.plist AutoUpdate 2>/dev/null || true
            defaults delete /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload 2>/dev/null || true
            defaults delete /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled 2>/dev/null || true
            defaults delete /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall 2>/dev/null || true
            echo "✓ Paramètres de mise à jour réinitialisés aux valeurs système par défaut"
            ;;
        "help")
            echo "Usage : $0 [action] [options...]"
            echo "Actions :"
            echo "  policy <nom_politique> [environnement] [bande_passante] [dry_run] - Appliquer une politique de mise à jour"
            echo "  enable - Activer les mises à jour automatiques de l'App Store"
            echo "  disable - Désactiver les mises à jour automatiques de l'App Store"
            echo "  check - Vérifier les mises à jour disponibles"
            echo "  install [nom_mise_à_jour] - Installer les mises à jour (toutes ou spécifique)"
            echo "  status - Afficher la configuration actuelle des mises à jour"
            echo "  compliance [type] - Vérifier la conformité de la flotte"
            echo "  reset - Réinitialiser aux valeurs système par défaut"
            echo "  help - Afficher cette aide"
            echo ""
            echo "Politiques : ${!UPDATE_POLICIES[*]}"
            echo "Plannings : ${!UPDATE_SCHEDULES[*]}"
            echo "Profils Bande Passante : ${!BANDWIDTH_PROFILES[*]}"
            ;;
        *)
            log_action "ERREUR : Action inconnue : $action"
            echo "Utilisez '$0 help' pour les informations d'utilisation"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion des mises à jour de l'App Store terminée ==="
}

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

Sécurité et Conformité des Mises à Jour

Conformité Santé/HIPAA

#!/bin/bash

# Configurer la gestion des mises à jour conforme HIPAA
configure_hipaa_update_compliance() {
    echo "=== Configuration de la Conformité HIPAA des Mises à Jour ==="
    
    # Désactiver les mises à jour automatiques pour le contrôle de conformité
    defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
    defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool FALSE
    
    # Activer uniquement les mises à jour de sécurité
    defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool TRUE
    
    # Configurer la journalisation d'audit
    setup_update_audit_logging "hipaa"
    
    echo "✓ Conformité HIPAA des mises à jour configurée"
}

configure_hipaa_update_compliance

Conformité Services Financiers

#!/bin/bash

# Configurer la conformité des mises à jour pour les services financiers
configure_financial_update_compliance() {
    echo "=== Configuration de la Conformité des Services Financiers ==="
    
    # Contrôle strict des mises à jour pour la conformité financière
    defaults write /Library/Preferences/com.apple.commerce.plist AutoUpdate -bool FALSE
    defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticDownload -bool FALSE
    defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist AutomaticCheckEnabled -bool TRUE
    
    # Mises à jour de sécurité uniquement avec approbation manuelle
    defaults write /Library/Preferences/com.apple.SoftwareUpdate.plist CriticalUpdateInstall -bool FALSE
    
    echo "✓ Conformité des services financiers configurée"
}

configure_financial_update_compliance

Dépannage et Maintenance

Vérification de l'État du Système de Mise à Jour

#!/bin/bash

# Vérification complète de l'état du système de mise à jour
perform_update_health_check() {
    echo "=== Vérification de l'État du Système de Mise à Jour ==="
    
    # Vérifier le statut du service de mise à jour
    local update_service_status
    update_service_status=$(launchctl list | grep -c "com.apple.softwareupdated" || echo "0")
    echo "Service de Mise à Jour Logicielle : $([ "$update_service_status" -gt 0 ] && echo "En Cours" || echo "Arrêté")"
    
    # Vérifier le cache de mise à jour
    local cache_path="/Library/Updates"
    if [[ -d "$cache_path" ]]; then
        local cache_size=$(du -sh "$cache_path" | cut -f1)
        local cache_files=$(find "$cache_path" -type f | wc -l | tr -d ' ')
        echo "Cache de Mise à Jour : $cache_size ($cache_files fichiers)"
    else
        echo "Cache de Mise à Jour : Non présent"
    fi
    
    # Vérifier les préférences corrompues
    local commerce_plist="/Library/Preferences/com.apple.commerce.plist"
    local softwareupdate_plist="/Library/Preferences/com.apple.SoftwareUpdate.plist"
    
    if plutil -lint "$commerce_plist" &>/dev/null; then
        echo "Préférences Commerce : Valides"
    else
        echo "⚠️ Préférences Commerce : Corrompues ou manquantes"
    fi
    
    if plutil -lint "$softwareupdate_plist" &>/dev/null; then
        echo "Préférences Software Update : Valides"
    else
        echo "⚠️ Préférences Software Update : Corrompues ou manquantes"
    fi
    
    # Vérifier la connectivité réseau pour les mises à jour
    if curl -s --connect-timeout 5 "https://swscan.apple.com/" &>/dev/null; then
        echo "Serveurs de Mise à Jour Apple : Accessibles"
    else
        echo "⚠️ Serveurs de Mise à Jour Apple : Non accessibles"
    fi
}

perform_update_health_check

Notes Importantes

  • Privilèges administrateur requis pour les changements de configuration de mise à jour
  • Exigences de redémarrage - Certains paramètres prennent effet après redémarrage
  • Impact réseau - Considérer l'utilisation de bande passante pour les mises à jour automatiques
  • Implications de sécurité - Équilibrer l'automatisation avec le contrôle de sécurité
  • Exigences de conformité - Certaines industries nécessitent une approbation manuelle des mises à jour
  • Considérations de stockage - Les mises à jour téléchargées consomment de l'espace disque
  • Recommandations de test - Tester les politiques de mise à jour sur des appareils de test d'abord
  • Importance de surveillance - La vérification régulière de conformité prévient la dérive de politique

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

Ce guide complet démontre comment suivre quand les applications et fichiers ont été accédés pour la dernière fois sur les appareils macOS, fournissant des informations essentielles pour la gestion du parc Mac et la surveillance d'utilisation.

Aperçu

La surveillance des modèles d'accès aux applications et fichiers est cruciale pour :

  • Optimisation des performances : Identifier les applications gourmandes en ressources
  • Gestion des licences : Suivre l'utilisation des logiciels pour la conformité
  • Audit de sécurité : Surveiller l'accès aux fichiers pour la conformité sécuritaire
  • Optimisation du stockage : Trouver les applications et fichiers inutilisés
  • Analyse comportementale : Comprendre les habitudes de travail et la productivité

Script de base pour l'heure de dernière ouverture

Vérification simple d'application/fichier

Créez un script de base pour vérifier quand une application ou un fichier a été ouvert pour la dernière fois :

#!/bin/bash

# Script de base pour obtenir l'heure de dernière ouverture d'une app ou fichier
# Usage: ./last_opened.sh "/chemin/vers/app/ou/fichier"

if [ $# -eq 0 ]; then
    echo "Usage: $0 <chemin_fichier>"
    echo "Exemple: $0 '/Applications/Safari.app'"
    exit 1
fi

file_path="$1"

# Vérifier si le fichier existe
if [ ! -e "$file_path" ]; then
    echo "Erreur: Fichier ou application non trouvé: $file_path"
    exit 1
fi

# Obtenir l'heure de dernière ouverture avec mdls
datetime=$(mdls "$file_path" -name kMDItemLastUsedDate | awk '{print $3,$4}')

if [ "$datetime" = "(null)" ]; then
    echo "'$file_path' n'a jamais été ouvert ou l'heure de dernière ouverture n'est pas disponible"
    exit 0
fi

echo "'$file_path' a été ouvert pour la dernière fois le (UTC):"
echo "$datetime"
echo "'$file_path' a été ouvert pour la dernière fois le (Heure locale):"
echo "$(date -jf "%Y-%m-%d %H:%M:%S %z" "$datetime +0000" +"%Y-%m-%d %H:%M:%S")"

Script amélioré avec gestion d'erreurs

#!/bin/bash

# Script amélioré avec gestion d'erreurs complète et formatage
# Usage: ./enhanced_last_opened.sh "/chemin/vers/app/ou/fichier"

check_last_opened() {
    local file_path="$1"
    local file_name=$(basename "$file_path")
    
    # Valider l'entrée
    if [ -z "$file_path" ]; then
        echo "Erreur: Aucun chemin de fichier fourni"
        return 1
    fi
    
    # Vérifier si le fichier existe
    if [ ! -e "$file_path" ]; then
        echo "Erreur: Fichier non trouvé: $file_path"
        return 1
    fi
    
    # Obtenir les métadonnées
    local datetime=$(mdls "$file_path" -name kMDItemLastUsedDate 2>/dev/null | awk '{print $3,$4}')
    local creation_date=$(mdls "$file_path" -name kMDItemContentCreationDate 2>/dev/null | awk '{print $3,$4}')
    local modification_date=$(mdls "$file_path" -name kMDItemContentModificationDate 2>/dev/null | awk '{print $3,$4}')
    
    echo "=== Informations du fichier ==="
    echo "Fichier: $file_name"
    echo "Chemin: $file_path"
    echo ""
    
    # Heure de dernière ouverture
    if [ "$datetime" = "(null)" ] || [ -z "$datetime" ]; then
        echo "Dernière ouverture: Jamais ouvert ou information non disponible"
    else
        echo "Dernière ouverture (UTC): $datetime"
        local local_time=$(date -jf "%Y-%m-%d %H:%M:%S %z" "$datetime +0000" +"%Y-%m-%d %H:%M:%S" 2>/dev/null)
        if [ $? -eq 0 ]; then
            echo "Dernière ouverture (Locale): $local_time"
        else
            echo "Dernière ouverture (Locale): Impossible de convertir l'heure"
        fi
    fi
    
    # Date de création
    if [ "$creation_date" != "(null)" ] && [ -n "$creation_date" ]; then
        echo "Créé (UTC): $creation_date"
    fi
    
    # Date de modification
    if [ "$modification_date" != "(null)" ] && [ -n "$modification_date" ]; then
        echo "Modifié (UTC): $modification_date"
    fi
    
    echo "=============================="
    echo ""
}

# Exécution principale
if [ $# -eq 0 ]; then
    echo "Usage: $0 <chemin_fichier>"
    echo "Exemple: $0 '/Applications/Safari.app'"
    exit 1
fi

check_last_opened "$1"

Surveillance avancée des applications

Scanner d'applications en lot

#!/bin/bash

# Scanner d'applications en lot avec rapport détaillé
# Usage: ./bulk_app_scanner.sh

scan_applications() {
    local output_file="rapport_usage_apps_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "Rapport d'utilisation des applications MacFleet" > "$output_file"
    echo "Généré: $(date)" >> "$output_file"
    echo "Appareil: $(scutil --get ComputerName)" >> "$output_file"
    echo "Utilisateur: $(whoami)" >> "$output_file"
    echo "=======================================" >> "$output_file"
    echo "" >> "$output_file"
    
    # Scanner le dossier Applications
    echo "Scan de /Applications..."
    find /Applications -maxdepth 2 -name "*.app" -type d | while read app_path; do
        app_name=$(basename "$app_path" .app)
        
        # Obtenir l'heure de dernière ouverture
        datetime=$(mdls "$app_path" -name kMDItemLastUsedDate 2>/dev/null | awk '{print $3,$4}')
        
        if [ "$datetime" = "(null)" ] || [ -z "$datetime" ]; then
            last_opened="Jamais ouvert"
        else
            last_opened=$(date -jf "%Y-%m-%d %H:%M:%S %z" "$datetime +0000" +"%Y-%m-%d %H:%M:%S" 2>/dev/null)
            if [ $? -ne 0 ]; then
                last_opened="$datetime (UTC)"
            fi
        fi
        
        # Obtenir la version de l'app
        app_version=$(mdls "$app_path" -name kMDItemVersion 2>/dev/null | awk -F'"' '{print $2}')
        if [ "$app_version" = "(null)" ] || [ -z "$app_version" ]; then
            app_version="Inconnue"
        fi
        
        # Obtenir la taille de l'app
        app_size=$(du -sh "$app_path" 2>/dev/null | cut -f1)
        if [ -z "$app_size" ]; then
            app_size="Inconnue"
        fi
        
        echo "App: $app_name" >> "$output_file"
        echo "  Version: $app_version" >> "$output_file"
        echo "  Taille: $app_size" >> "$output_file"
        echo "  Dernière ouverture: $last_opened" >> "$output_file"
        echo "  Chemin: $app_path" >> "$output_file"
        echo "" >> "$output_file"
        
        # Indicateur de progression
        echo "Traité: $app_name"
    done
    
    echo "Rapport sauvegardé dans: $output_file"
}

# Exécuter le scan
scan_applications

Filtre des applications récemment utilisées

#!/bin/bash

# Filtrer les applications par utilisation récente
# Usage: ./recent_apps.sh [jours]

filter_recent_apps() {
    local days_threshold=${1:-7}  # Par défaut 7 jours
    local cutoff_date=$(date -v -${days_threshold}d +%Y-%m-%d)
    
    echo "Applications utilisées dans les $days_threshold derniers jours:"
    echo "Date limite: $cutoff_date"
    echo "=================================="
    
    find /Applications -maxdepth 2 -name "*.app" -type d | while read app_path; do
        app_name=$(basename "$app_path" .app)
        
        # Obtenir l'heure de dernière ouverture
        datetime=$(mdls "$app_path" -name kMDItemLastUsedDate 2>/dev/null | awk '{print $3,$4}')
        
        if [ "$datetime" != "(null)" ] && [ -n "$datetime" ]; then
            # Convertir en format comparable
            app_date=$(echo "$datetime" | cut -d' ' -f1)
            
            # Comparer les dates
            if [[ "$app_date" > "$cutoff_date" ]]; then
                local_time=$(date -jf "%Y-%m-%d %H:%M:%S %z" "$datetime +0000" +"%Y-%m-%d %H:%M:%S" 2>/dev/null)
                if [ $? -eq 0 ]; then
                    echo "$app_name - Dernière utilisation: $local_time"
                else
                    echo "$app_name - Dernière utilisation: $datetime (UTC)"
                fi
            fi
        fi
    done | sort
}

# Exécution principale
if [ $# -gt 1 ]; then
    echo "Usage: $0 [jours]"
    echo "Exemple: $0 30  # Afficher les apps utilisées dans les 30 derniers jours"
    exit 1
fi

filter_recent_apps "$1"

Surveillance des fichiers d'entreprise

Suivi d'accès aux documents

#!/bin/bash

# Suivre les modèles d'accès aux documents pour les types de fichiers courants
# Usage: ./document_tracker.sh "/chemin/vers/documents"

track_document_access() {
    local base_path=${1:-"$HOME/Documents"}
    local output_file="acces_documents_$(date +%Y%m%d_%H%M%S).json"
    
    echo "Suivi de l'accès aux documents dans: $base_path"
    
    # Créer le rapport JSON
    cat > "$output_file" << EOF
{
  "info_rapport": {
    "genere": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "appareil": "$(scutil --get ComputerName)",
    "utilisateur": "$(whoami)",
    "chemin_scan": "$base_path",
    "version_macfleet": "1.0"
  },
  "documents": [
EOF
    
    local first_entry=true
    
    # Types de documents courants
    local file_types=("*.pdf" "*.doc" "*.docx" "*.xls" "*.xlsx" "*.ppt" "*.pptx" "*.txt" "*.rtf" "*.pages" "*.numbers" "*.keynote")
    
    for pattern in "${file_types[@]}"; do
        find "$base_path" -name "$pattern" -type f 2>/dev/null | while read file_path; do
            # Obtenir les métadonnées du fichier
            local filename=$(basename "$file_path")
            local extension="${filename##*.}"
            local size=$(stat -f%z "$file_path" 2>/dev/null || echo "0")
            
            # Obtenir les horodatages
            local last_used=$(mdls "$file_path" -name kMDItemLastUsedDate 2>/dev/null | awk '{print $3,$4}')
            local created=$(mdls "$file_path" -name kMDItemContentCreationDate 2>/dev/null | awk '{print $3,$4}')
            local modified=$(mdls "$file_path" -name kMDItemContentModificationDate 2>/dev/null | awk '{print $3,$4}')
            
            # Formater pour JSON
            if [ "$last_used" = "(null)" ] || [ -z "$last_used" ]; then
                last_used="null"
            else
                last_used="\"$last_used\""
            fi
            
            if [ "$created" = "(null)" ] || [ -z "$created" ]; then
                created="null"
            else
                created="\"$created\""
            fi
            
            if [ "$modified" = "(null)" ] || [ -z "$modified" ]; then
                modified="null"
            else
                modified="\"$modified\""
            fi
            
            # Ajouter une virgule si ce n'est pas la première entrée
            if [ "$first_entry" = false ]; then
                echo "," >> "$output_file"
            fi
            first_entry=false
            
            # Ajouter l'entrée du document
            cat >> "$output_file" << EOF
    {
      "nom_fichier": "$filename",
      "extension": "$extension",
      "taille_octets": $size,
      "chemin": "$file_path",
      "derniere_utilisation": $last_used,
      "cree": $created,
      "modifie": $modified
    }EOF
        done
    done
    
    # Fermer le JSON
    cat >> "$output_file" << EOF

  ]
}
EOF
    
    echo "Rapport d'accès aux documents sauvegardé dans: $output_file"
}

# Exécuter le suivi
track_document_access "$1"

Moniteur d'accès aux fichiers multi-utilisateurs

#!/bin/bash

# Surveiller l'accès aux fichiers sur plusieurs comptes utilisateurs
# Usage: ./multi_user_monitor.sh

monitor_multi_user_access() {
    local report_file="acces_multi_utilisateurs_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "Rapport d'accès aux fichiers multi-utilisateurs MacFleet" > "$report_file"
    echo "Généré: $(date)" >> "$report_file"
    echo "Appareil: $(scutil --get ComputerName)" >> "$report_file"
    echo "=========================================" >> "$report_file"
    echo "" >> "$report_file"
    
    # Obtenir tous les répertoires home des utilisateurs
    local users=($(dscl . -list /Users | grep -v "^_" | grep -v "daemon" | grep -v "nobody" | grep -v "root"))
    
    for user in "${users[@]}"; do
        local user_home=$(dscl . -read /Users/$user NFSHomeDirectory | awk '{print $2}')
        
        if [ -d "$user_home" ]; then
            echo "Utilisateur: $user ($user_home)" >> "$report_file"
            echo "--------------------------------" >> "$report_file"
            
            # Vérifier le dossier Documents
            if [ -d "$user_home/Documents" ]; then
                echo "Documents récemment accédés:" >> "$report_file"
                find "$user_home/Documents" -type f -name "*.pdf" -o -name "*.doc*" -o -name "*.xls*" -o -name "*.ppt*" 2>/dev/null | head -10 | while read file_path; do
                    local filename=$(basename "$file_path")
                    local last_used=$(mdls "$file_path" -name kMDItemLastUsedDate 2>/dev/null | awk '{print $3,$4}')
                    
                    if [ "$last_used" != "(null)" ] && [ -n "$last_used" ]; then
                        echo "  - $filename (Dernière utilisation: $last_used)" >> "$report_file"
                    fi
                done
            fi
            
            # Vérifier le dossier Téléchargements
            if [ -d "$user_home/Downloads" ]; then
                echo "Téléchargements récents:" >> "$report_file"
                find "$user_home/Downloads" -type f -mtime -7 2>/dev/null | head -5 | while read file_path; do
                    local filename=$(basename "$file_path")
                    local mod_time=$(stat -f "%Sm" -t "%Y-%m-%d %H:%M:%S" "$file_path" 2>/dev/null)
                    echo "  - $filename (Téléchargé: $mod_time)" >> "$report_file"
                done
            fi
            
            echo "" >> "$report_file"
        fi
    done
    
    echo "Rapport d'accès multi-utilisateurs sauvegardé dans: $report_file"
}

# Exécuter la surveillance
monitor_multi_user_access

Gestion distante du parc

Collecteur d'utilisation centralisé

#!/bin/bash

# Collecter les données d'utilisation pour la gestion distante du parc
# Usage: ./fleet_collector.sh

collect_fleet_data() {
    local device_id=$(system_profiler SPHardwareDataType | grep "Hardware UUID" | awk '{print $3}')
    local computer_name=$(scutil --get ComputerName)
    local timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
    
    # Créer un rapport complet
    local report_file="utilisation_parc_${computer_name}_$(date +%Y%m%d_%H%M%S).json"
    
    cat > "$report_file" << EOF
{
  "info_appareil": {
    "id_appareil": "$device_id",
    "nom_ordinateur": "$computer_name",
    "horodatage": "$timestamp",
    "version_os": "$(sw_vers -productVersion)",
    "duree_fonctionnement": "$(uptime | awk '{print $3,$4}' | sed 's/,//')"
  },
  "utilisation_applications": [
EOF
    
    # Collecter les principales applications
    local first_app=true
    find /Applications -maxdepth 2 -name "*.app" -type d | head -20 | while read app_path; do
        local app_name=$(basename "$app_path" .app)
        local last_used=$(mdls "$app_path" -name kMDItemLastUsedDate 2>/dev/null | awk '{print $3,$4}')
        local version=$(mdls "$app_path" -name kMDItemVersion 2>/dev/null | awk -F'"' '{print $2}')
        
        if [ "$first_app" = false ]; then
            echo "," >> "$report_file"
        fi
        first_app=false
        
        # Formater les valeurs pour JSON
        if [ "$last_used" = "(null)" ] || [ -z "$last_used" ]; then
            last_used="null"
        else
            last_used="\"$last_used\""
        fi
        
        if [ "$version" = "(null)" ] || [ -z "$version" ]; then
            version="null"
        else
            version="\"$version\""
        fi
        
        cat >> "$report_file" << EOF
    {
      "nom": "$app_name",
      "version": $version,
      "derniere_utilisation": $last_used,
      "chemin": "$app_path"
    }EOF
    done
    
    cat >> "$report_file" << EOF

  ],
  "stats_systeme": {
    "total_applications": $(find /Applications -maxdepth 2 -name "*.app" -type d | wc -l | tr -d ' '),
    "utilisation_disque": "$(df -h / | tail -1 | awk '{print $5}')",
    "utilisation_memoire": "$(vm_stat | grep "Pages active" | awk '{print $3}' | sed 's/\.//')"
  }
}
EOF
    
    echo "Données du parc collectées dans: $report_file"
    
    # Optionnel: Envoyer au serveur central
    # curl -X POST -H "Content-Type: application/json" -d @"$report_file" "https://votre-serveur-parc.com/api/utilisation"
}

# Exécuter la collecte
collect_fleet_data

Surveillance automatisée de l'utilisation

#!/bin/bash

# Surveillance automatisée de l'utilisation avec alertes
# Usage: ./usage_monitor.sh

setup_monitoring() {
    local log_file="/var/log/macfleet_usage.log"
    local config_file="/etc/macfleet/usage_config.conf"
    
    # Créer la configuration si elle n'existe pas
    if [ ! -f "$config_file" ]; then
        sudo mkdir -p /etc/macfleet
        sudo cat > "$config_file" << EOF
# Configuration de surveillance d'utilisation MacFleet
MONITOR_INTERVAL=3600  # Vérifier toutes les heures
ALERT_THRESHOLD=30     # Alerter si app inutilisée pendant 30 jours
REPORT_INTERVAL=86400  # Générer rapport quotidien
CLEANUP_THRESHOLD=90   # Marquer les apps inutilisées pendant 90 jours
EOF
    fi
    
    # Charger la configuration
    source "$config_file"
    
    # Créer le script de surveillance
    cat > "/tmp/macfleet_monitor.sh" << EOF
#!/bin/bash

# Moniteur d'utilisation MacFleet
log_usage() {
    local timestamp=\$(date -u +%Y-%m-%dT%H:%M:%SZ)
    local computer_name=\$(scutil --get ComputerName)
    
    echo "[\$timestamp] Début de vérification d'utilisation sur \$computer_name" >> "$log_file"
    
    # Vérifier les applications inutilisées
    find /Applications -maxdepth 2 -name "*.app" -type d | while read app_path; do
        local app_name=\$(basename "\$app_path" .app)
        local last_used=\$(mdls "\$app_path" -name kMDItemLastUsedDate 2>/dev/null | awk '{print \$3,\$4}')
        
        if [ "\$last_used" != "(null)" ] && [ -n "\$last_used" ]; then
            local days_since=\$(( (\$(date +%s) - \$(date -jf "%Y-%m-%d %H:%M:%S %z" "\$last_used +0000" +%s)) / 86400 ))
            
            if [ \$days_since -gt $ALERT_THRESHOLD ]; then
                echo "[\$timestamp] ALERTE: \$app_name inutilisée pendant \$days_since jours" >> "$log_file"
            fi
            
            if [ \$days_since -gt $CLEANUP_THRESHOLD ]; then
                echo "[\$timestamp] NETTOYAGE: \$app_name marquée pour suppression (\$days_since jours)" >> "$log_file"
            fi
        fi
    done
    
    echo "[\$timestamp] Vérification d'utilisation terminée" >> "$log_file"
}

# Exécuter la surveillance
log_usage
EOF
    
    chmod +x "/tmp/macfleet_monitor.sh"
    
    # Configurer launchd pour la surveillance automatisée
    cat > "/tmp/com.macfleet.usage.monitor.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.macfleet.usage.monitor</string>
    <key>ProgramArguments</key>
    <array>
        <string>/tmp/macfleet_monitor.sh</string>
    </array>
    <key>StartInterval</key>
    <integer>$MONITOR_INTERVAL</integer>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
EOF
    
    echo "Configuration de surveillance terminée. Utilisez 'sudo launchctl load /tmp/com.macfleet.usage.monitor.plist' pour démarrer."
}

# Exécuter la configuration
setup_monitoring

Meilleures pratiques pour la gestion du parc Mac

1. Optimisation des performances

  • Surveiller les applications gourmandes en ressources
  • Suivre les applications qui n'ont pas été utilisées récemment
  • Identifier les opportunités de nettoyage d'applications
  • Optimiser les performances système grâce aux informations d'utilisation

2. Sécurité et conformité

  • Suivre l'accès aux fichiers pour les audits de sécurité
  • Surveiller la conformité de gestion des documents
  • Identifier les modèles d'accès non autorisés aux fichiers
  • Maintenir les journaux d'accès pour les exigences de conformité

3. Gestion des licences

  • Surveiller l'utilisation des logiciels pour l'optimisation des licences
  • Suivre l'efficacité du déploiement d'applications
  • Identifier les licences inutilisées pour des économies de coût
  • Assurer la conformité aux accords de licence logicielle

4. Expérience utilisateur

  • Comprendre les modèles de comportement des utilisateurs
  • Optimiser les stratégies de déploiement d'applications
  • Améliorer la productivité des utilisateurs grâce aux informations d'utilisation
  • Personnaliser les configurations d'appareils basées sur l'utilisation

5. Maintenance et nettoyage

  • Identifier les applications inutilisées pour la suppression
  • Nettoyer les fichiers temporaires et les caches
  • Optimiser l'utilisation du stockage
  • Programmer la maintenance régulière basée sur les modèles d'utilisation

Dépannage des problèmes courants

1. Erreurs de permissions

# Corriger les problèmes de permissions
sudo chown -R $(whoami) /Users/$(whoami)/Documents
sudo chmod -R 755 /Users/$(whoami)/Documents

2. Métadonnées non disponibles

# Vérifier si l'indexation Spotlight est activée
mdutil -s /
# Re-indexer si nécessaire
sudo mdutil -i on /
sudo mdutil -E /

3. Problèmes d'exécution de script

# Rendre le script exécutable
chmod +x nom_script.sh
# Vérifier la version bash
bash --version
# Utiliser le chemin complet pour les commandes
/usr/bin/mdls au lieu de mdls

4. Problèmes de format de date

# Gérer différents formats de date
date -jf "%Y-%m-%d %H:%M:%S %z" "2024-01-01 12:00:00 +0000" +"%Y-%m-%d %H:%M:%S"

Conclusion

La surveillance de l'utilisation des applications et fichiers est essentielle pour une gestion efficace du parc Mac. Ces scripts fournissent des informations complètes sur le comportement des utilisateurs, les performances du système et la conformité sécuritaire. Une surveillance régulière aide à optimiser les ressources, améliorer l'expérience utilisateur et maintenir les normes de sécurité à travers votre parc Mac.

N'oubliez pas de tester les scripts dans un environnement contrôlé avant de les déployer sur votre parc, et toujours suivre les politiques de sécurité et de confidentialité de votre organisation lors de la surveillance de l'activité des utilisateurs.

Configurer Son d'Alerte et Volume sur macOS

Apprenez à personnaliser les sons d'alerte système et niveaux de volume sur Mac. Essentiel pour créer des expériences audio cohérentes dans les flottes Mac d'entreprise et s'adapter aux différents environnements de travail.

Changer Son d'Alerte

Changez le son d'alerte par défaut de "Tink" vers d'autres sons système disponibles :

#!/bin/bash

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

# Configuration
ALERT_SOUND="Submarine"  # Options : Basso, Funk, Glass, Ping, Pop, Submarine, Tink

echo "Définition son d'alerte à : $ALERT_SOUND"

# Appliquer paramètre son d'alerte
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults write .GlobalPreferences com.apple.sound.beep.sound "/System/Library/Sounds/${ALERT_SOUND}.aiff"

echo "✅ Son d'alerte changé vers $ALERT_SOUND"
echo "🔄 Changements prennent effet immédiatement"

Changer Volume d'Alerte

Ajustez le niveau de volume d'alerte (0-100%) :

#!/bin/bash

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

# Configuration
ALERT_VOLUME="75"  # Pourcentage volume (0-100)

echo "Définition volume d'alerte à : ${ALERT_VOLUME}%"

# Appliquer paramètre volume d'alerte
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    osascript -e "set volume alert volume $ALERT_VOLUME"

echo "✅ Volume d'alerte défini à ${ALERT_VOLUME}%"

Lister Sons d'Alerte Disponibles

Script pour découvrir tous les sons d'alerte système disponibles :

#!/bin/bash

echo "🔊 Sons d'Alerte Système Disponibles :"
echo "======================================"

# Lister tous fichiers son dans répertoire sons système
SOUNDS_DIR="/System/Library/Sounds"
if [[ -d "$SOUNDS_DIR" ]]; then
    for sound_file in "$SOUNDS_DIR"/*.aiff; do
        if [[ -f "$sound_file" ]]; then
            sound_name=$(basename "$sound_file" .aiff)
            echo "  📢 $sound_name"
        fi
    done
else
    echo "❌ Répertoire sons système non trouvé"
fi

echo ""
echo "💡 Utilisez n'importe lequel de ces noms dans la variable ALERT_SOUND"

Configuration Alerte Complète

Script complet pour configurer son et volume :

#!/bin/bash

# Fonction pour configurer paramètres d'alerte
configure_alert_settings() {
    local sound_name="$1"
    local volume_level="$2"
    
    # Obtenir le contexte utilisateur actuel
    local current_user=$(stat -f "%Su" /dev/console)
    local current_user_uid=$(id -u "$current_user")
    
    echo "=== Configuration Alerte MacFleet ==="
    echo "👤 Utilisateur : $current_user"
    echo "🔊 Son : $sound_name"
    echo "🔊 Volume : ${volume_level}%"
    echo "====================================="
    
    # Valider que fichier son existe
    local sound_path="/System/Library/Sounds/${sound_name}.aiff"
    if [[ ! -f "$sound_path" ]]; then
        echo "❌ Erreur : Son '$sound_name' non trouvé"
        echo "📋 Sons disponibles :"
        ls /System/Library/Sounds/*.aiff | sed 's|.*/||' | sed 's|\.aiff||' | sed 's/^/  - /'
        return 1
    fi
    
    # Valider plage volume
    if [[ $volume_level -lt 0 || $volume_level -gt 100 ]]; then
        echo "❌ Erreur : Volume doit être entre 0 et 100"
        return 1
    fi
    
    # Appliquer paramètre son d'alerte
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write .GlobalPreferences com.apple.sound.beep.sound "$sound_path"
    
    # Appliquer paramètre volume d'alerte
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        osascript -e "set volume alert volume $volume_level"
    
    echo "✅ Paramètres d'alerte configurés avec succès"
    echo "🎵 Son : $sound_name"
    echo "🔊 Volume : ${volume_level}%"
}

# Configuration entreprise
ALERT_SOUND="Glass"
ALERT_VOLUME="50"

# Appliquer configuration
configure_alert_settings "$ALERT_SOUND" "$ALERT_VOLUME"

Obtenir Paramètres Alerte Actuels

Script pour afficher configuration actuelle son et volume d'alerte :

#!/bin/bash

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

echo "📊 Paramètres Alerte Actuels"
echo "============================="

# Obtenir son d'alerte actuel
current_sound=$(launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults read .GlobalPreferences com.apple.sound.beep.sound 2>/dev/null)

if [[ -n "$current_sound" ]]; then
    sound_name=$(basename "$current_sound" .aiff)
    echo "🔊 Son d'Alerte : $sound_name"
else
    echo "🔊 Son d'Alerte : Tink (par défaut)"
fi

# Obtenir volume d'alerte actuel avec AppleScript
current_volume=$(launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    osascript -e "get volume settings" 2>/dev/null | grep -o 'alert volume:[0-9]*' | cut -d: -f2)

if [[ -n "$current_volume" ]]; then
    echo "🔊 Volume d'Alerte : ${current_volume}%"
else
    echo "🔊 Volume d'Alerte : Impossible à déterminer"
fi

echo "👤 Utilisateur : $CURRENT_USER"
echo "🖥️  Appareil : $(hostname)"

Politique Alerte Entreprise

Configuration d'alerte standardisée pour environnements d'entreprise :

#!/bin/bash

# Standardisation alerte entreprise
COMPANY_NAME="MacFleet"
ENVIRONMENT_TYPE="office"  # Options : office, quiet, presentation, factory

# Définir paramètres spécifiques environnement
case "$ENVIRONMENT_TYPE" in
    "office")
        ALERT_SOUND="Glass"
        ALERT_VOLUME="50"
        ;;
    "quiet")
        ALERT_SOUND="Tink"
        ALERT_VOLUME="25"
        ;;
    "presentation")
        ALERT_SOUND="Pop"
        ALERT_VOLUME="10"
        ;;
    "factory")
        ALERT_SOUND="Basso"
        ALERT_VOLUME="100"
        ;;
    *)
        ALERT_SOUND="Glass"
        ALERT_VOLUME="50"
        ;;
esac

# Fonction pour appliquer politique alerte entreprise
apply_enterprise_alert_policy() {
    local current_user=$(stat -f "%Su" /dev/console)
    local current_user_uid=$(id -u "$current_user")
    
    echo "🏢 Application Politique Alerte Entreprise"
    echo "=========================================="
    echo "Environnement : $ENVIRONMENT_TYPE"
    echo "Appareil : $(hostname)"
    echo "Utilisateur : $current_user"
    echo "Son : $ALERT_SOUND"
    echo "Volume : ${ALERT_VOLUME}%"
    echo "Horodatage : $(date)"
    
    # Appliquer paramètre son
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        defaults write .GlobalPreferences com.apple.sound.beep.sound "/System/Library/Sounds/${ALERT_SOUND}.aiff"
    
    # Appliquer paramètre volume
    launchctl asuser $current_user_uid sudo -iu "$current_user" \
        osascript -e "set volume alert volume $ALERT_VOLUME"
    
    echo "✅ Politique alerte entreprise appliquée"
    echo "📊 Configuration terminée sur $(hostname)"
}

# Exécuter politique entreprise
apply_enterprise_alert_policy

Réinitialiser aux Paramètres Par Défaut

Restaurer paramètres d'alerte aux valeurs par défaut macOS :

#!/bin/bash

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

echo "🔄 Réinitialisation paramètres alerte aux valeurs par défaut..."

# Réinitialiser son d'alerte au défaut (Tink)
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    defaults delete .GlobalPreferences com.apple.sound.beep.sound 2>/dev/null || true

# Réinitialiser volume d'alerte au défaut (75%)
launchctl asuser $CURRENT_USER_UID sudo -iu "$CURRENT_USER" \
    osascript -e "set volume alert volume 75"

echo "✅ Paramètres alerte réinitialisés aux valeurs par défaut"
echo "🔊 Son : Tink (par défaut)"
echo "🔊 Volume : 75% (par défaut)"

Utilisation avec MacFleet

  1. Choisissez son et volume appropriés pour votre environnement
  2. Testez paramètres sur un seul appareil d'abord
  3. Déployez via l'exécution de script distant MacFleet
  4. Vérifiez paramètres dans la flotte d'appareils

Sons Système Disponibles

Nom SonDescriptionCas d'Usage
BassoProfond, attire l'attentionAlertes haute priorité
FunkModerne, plaisantNotifications générales
GlassClair, netEnvironnements professionnels
PingRapide, subtilDistraction minimale
PopCourt, netConfirmations rapides
SubmarineUnique, distinctifEnvironnements créatifs
TinkSon système par défautConfiguration standard

Directives Environnement

EnvironnementSon RecommandéNiveau Volume
BureauGlass, Tink25-50%
Zones silencieusesPing, Pop10-25%
PrésentationsPop, Tink10%
Usine/BruyantBasso, Funk75-100%
CréatifSubmarine, Funk50-75%

Dépannage

Son ne change pas : Vérifiez que fichier son existe dans /System/Library/Sounds/ Volume ne s'applique pas : Assurez-vous permissions exécution AppleScript Permission refusée : Vérifiez contexte utilisateur avec launchctl asuser