Guide

Nouvelles mises à jour et améliorations de Macfleet.

Gérer le chiffrement FileVault sur macOS

FileVault offre un chiffrement complet du disque pour les appareils macOS, protégeant les données sensibles même si l'appareil est perdu ou volé. Ce tutoriel montre comment automatiser la gestion de FileVault sur votre MacFleet en utilisant des scripts en ligne de commande.

Comprendre FileVault

FileVault chiffre l'ensemble du disque de démarrage en utilisant le chiffrement XTS-AES-128 avec une clé de 256 bits. Les avantages clés incluent :

  • Protection des données - Chiffre toutes les données sur le disque de démarrage
  • Conformité - Répond aux exigences de sécurité d'entreprise
  • Performance - Chiffrement accéléré par le matériel sur les Mac modernes
  • Récupération - Plusieurs options de récupération disponibles

Commandes FileVault de base

Vérifier le statut de FileVault

#!/bin/bash

# Vérifier le statut actuel de FileVault
fdesetup status

# Obtenir des informations détaillées sur le chiffrement
diskutil apfs listCryptoUsers /

Activer FileVault

#!/bin/bash

# Commande de base pour activer FileVault
sudo fdesetup enable --user "username" --password "password"

# Activer avec un trousseau spécifique
sudo fdesetup enable --user "username" --password "password" --keychain /Library/Keychains/System.keychain

Désactiver FileVault

#!/bin/bash

# Commande de base pour désactiver FileVault
sudo fdesetup disable --user "username" --password "password"

Script de gestion FileVault d'entreprise

Script complet pour gérer FileVault sur votre MacFleet :

#!/bin/bash

# Script de gestion FileVault pour MacFleet
# Compatible avec macOS 10.14+

# Configuration
LOG_FILE="/var/log/filevault_management.log"
KEYCHAIN_PATH="/Library/Keychains/System.keychain"

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

# Fonction pour obtenir l'utilisateur actuel
get_current_user() {
    stat -f "%Su" /dev/console
}

# Fonction pour vérifier si l'utilisateur a un token sécurisé
check_secure_token() {
    local username="$1"
    
    if sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep -q "ENABLED"; then
        return 0
    else
        return 1
    fi
}

# Fonction pour vérifier le statut de FileVault
check_filevault_status() {
    local status
    status=$(fdesetup status)
    
    if echo "$status" | grep -q "FileVault is On"; then
        echo "enabled"
    elif echo "$status" | grep -q "FileVault is Off"; then
        echo "disabled"
    elif echo "$status" | grep -q "Encryption in progress"; then
        echo "encrypting"
    elif echo "$status" | grep -q "Decryption in progress"; then
        echo "decrypting"
    else
        echo "unknown"
    fi
}

# Fonction pour obtenir le progrès du chiffrement
get_encryption_progress() {
    fdesetup status | grep -o '[0-9]\+%' | head -1
}

# Fonction pour valider les identifiants utilisateur
validate_user_credentials() {
    local username="$1"
    local password="$2"
    
    # Vérifier si l'utilisateur existe
    if ! id "$username" &>/dev/null; then
        log_message "✗ L'utilisateur n'existe pas : $username"
        return 1
    fi
    
    # Vérifier si l'utilisateur a des privilèges admin
    if ! dsmemberutil checkmembership -U "$username" -G admin &>/dev/null; then
        log_message "✗ L'utilisateur n'est pas un administrateur : $username"
        return 1
    fi
    
    # Vérifier si l'utilisateur a un token sécurisé
    if ! check_secure_token "$username"; then
        log_message "✗ L'utilisateur n'a pas de token sécurisé : $username"
        return 1
    fi
    
    # Vérifier le mot de passe (vérification de base)
    if [[ -z "$password" ]]; then
        log_message "✗ Le mot de passe ne peut pas être vide pour l'utilisateur : $username"
        return 1
    fi
    
    log_message "✓ Identifiants utilisateur validés : $username"
    return 0
}

# Fonction pour activer FileVault
enable_filevault() {
    local username="$1"
    local password="$2"
    local force_enable="$3"
    
    log_message "Début de l'activation de FileVault pour l'utilisateur : $username"
    
    # Vérifier le statut actuel
    local current_status
    current_status=$(check_filevault_status)
    
    case "$current_status" in
        "enabled")
            log_message "! FileVault est déjà activé"
            if [[ "$force_enable" != "true" ]]; then
                return 0
            fi
            ;;
        "encrypting")
            log_message "! Le chiffrement FileVault est déjà en cours"
            local progress
            progress=$(get_encryption_progress)
            log_message "  Progrès du chiffrement : ${progress:-Inconnu}"
            return 0
            ;;
        "decrypting")
            log_message "✗ Impossible d'activer FileVault pendant qu'un déchiffrement est en cours"
            return 1
            ;;
    esac
    
    # Valider les identifiants utilisateur
    if ! validate_user_credentials "$username" "$password"; then
        return 1
    fi
    
    # Activer FileVault
    log_message "Activation de FileVault..."
    
    if fdesetup enable -user "$username" -password "$password" -keychain "$KEYCHAIN_PATH" 2>/dev/null; then
        log_message "✓ Commande d'activation de FileVault exécutée avec succès"
        
        # Attendre un moment et vérifier le statut
        sleep 5
        local new_status
        new_status=$(check_filevault_status)
        
        case "$new_status" in
            "enabled")
                log_message "✓ FileVault est maintenant activé"
                ;;
            "encrypting")
                local progress
                progress=$(get_encryption_progress)
                log_message "✓ Chiffrement FileVault démarré (${progress:-0%})"
                ;;
            *)
                log_message "! Statut FileVault incertain : $new_status"
                ;;
        esac
        
        return 0
    else
        log_message "✗ Échec de l'activation de FileVault"
        return 1
    fi
}

# Fonction pour désactiver FileVault
disable_filevault() {
    local username="$1"
    local password="$2"
    local force_disable="$3"
    
    log_message "Début de la désactivation de FileVault pour l'utilisateur : $username"
    
    # Vérifier le statut actuel
    local current_status
    current_status=$(check_filevault_status)
    
    case "$current_status" in
        "disabled")
            log_message "! FileVault est déjà désactivé"
            if [[ "$force_disable" != "true" ]]; then
                return 0
            fi
            ;;
        "decrypting")
            log_message "! Le déchiffrement FileVault est déjà en cours"
            local progress
            progress=$(get_encryption_progress)
            log_message "  Progrès du déchiffrement : ${progress:-Inconnu}"
            return 0
            ;;
        "encrypting")
            log_message "✗ Impossible de désactiver FileVault pendant qu'un chiffrement est en cours"
            return 1
            ;;
    esac
    
    # Valider les identifiants utilisateur
    if ! validate_user_credentials "$username" "$password"; then
        return 1
    fi
    
    # Désactiver FileVault
    log_message "Désactivation de FileVault..."
    
    if fdesetup disable -user "$username" -password "$password" 2>/dev/null; then
        log_message "✓ Commande de désactivation de FileVault exécutée avec succès"
        
        # Attendre un moment et vérifier le statut
        sleep 5
        local new_status
        new_status=$(check_filevault_status)
        
        case "$new_status" in
            "disabled")
                log_message "✓ FileVault est maintenant désactivé"
                ;;
            "decrypting")
                local progress
                progress=$(get_encryption_progress)
                log_message "✓ Déchiffrement FileVault démarré (${progress:-0%})"
                ;;
            *)
                log_message "! Statut FileVault incertain : $new_status"
                ;;
        esac
        
        return 0
    else
        log_message "✗ Échec de la désactivation de FileVault"
        return 1
    fi
}

# Fonction pour obtenir les informations système
get_system_info() {
    log_message "=== Informations système ==="
    log_message "Nom d'hôte : $(hostname)"
    log_message "Version macOS : $(sw_vers -productVersion)"
    log_message "Utilisateur actuel : $(get_current_user)"
    log_message "Statut FileVault : $(check_filevault_status)"
    
    # Obtenir les utilisateurs FileVault
    local fv_users
    fv_users=$(fdesetup list 2>/dev/null)
    if [[ -n "$fv_users" ]]; then
        log_message "Utilisateurs avec FileVault activé :"
        echo "$fv_users" | while read -r line; do
            log_message "  $line"
        done
    fi
}

# Fonction pour afficher l'usage
usage() {
    echo "Usage : $0 {enable|disable|status} [options]"
    echo ""
    echo "Commandes :"
    echo "  enable    Activer FileVault"
    echo "  disable   Désactiver FileVault"
    echo "  status    Vérifier le statut de FileVault"
    echo ""
    echo "Options :"
    echo "  -u, --user USERNAME      Spécifier le nom d'utilisateur"
    echo "  -p, --password PASSWORD  Spécifier le mot de passe"
    echo "  -f, --force             Forcer l'opération même si déjà dans l'état désiré"
    echo "  -h, --help              Afficher ce message d'aide"
    echo ""
    echo "Exemples :"
    echo "  $0 enable -u admin -p password123"
    echo "  $0 disable -u admin -p password123 -f"
    echo "  $0 status"
}

# Fonction principale
main() {
    local command="$1"
    local username=""
    local password=""
    local force="false"
    
    # Analyser les arguments
    shift
    while [[ $# -gt 0 ]]; do
        case $1 in
            -u|--user)
                username="$2"
                shift 2
                ;;
            -p|--password)
                password="$2"
                shift 2
                ;;
            -f|--force)
                force="true"
                shift
                ;;
            -h|--help)
                usage
                exit 0
                ;;
            *)
                echo "Option inconnue : $1"
                usage
                exit 1
                ;;
        esac
    done
    
    # Exécuter la commande
    case "$command" in
        "enable")
            if [[ -z "$username" ]] || [[ -z "$password" ]]; then
                echo "Erreur : Nom d'utilisateur et mot de passe requis pour la commande enable"
                usage
                exit 1
            fi
            
            log_message "=== Début de l'opération d'activation de FileVault ==="
            get_system_info
            
            if enable_filevault "$username" "$password" "$force"; then
                log_message "=== Opération d'activation de FileVault terminée avec succès ==="
                exit 0
            else
                log_message "=== Échec de l'opération d'activation de FileVault ==="
                exit 1
            fi
            ;;
        "disable")
            if [[ -z "$username" ]] || [[ -z "$password" ]]; then
                echo "Erreur : Nom d'utilisateur et mot de passe requis pour la commande disable"
                usage
                exit 1
            fi
            
            log_message "=== Début de l'opération de désactivation de FileVault ==="
            get_system_info
            
            if disable_filevault "$username" "$password" "$force"; then
                log_message "=== Opération de désactivation de FileVault terminée avec succès ==="
                exit 0
            else
                log_message "=== Échec de l'opération de désactivation de FileVault ==="
                exit 1
            fi
            ;;
        "status")
            get_system_info
            exit 0
            ;;
        *)
            echo "Erreur : Commande invalide : $command"
            usage
            exit 1
            ;;
    esac
}

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

Scripts FileVault rapides

Script d'activation simple

#!/bin/bash

USERNAME="admin"
PASSWORD="votre_mot_de_passe_ici"

if fdesetup enable -user "$USERNAME" -password "$PASSWORD"; then
    echo "FileVault activé avec succès"
else
    echo "Échec de l'activation de FileVault"
    exit 1
fi

Vérification simple du statut

#!/bin/bash

STATUS=$(fdesetup status)
echo "Statut FileVault : $STATUS"

if echo "$STATUS" | grep -q "FileVault is On"; then
    echo "✓ FileVault est activé"
    exit 0
elif echo "$STATUS" | grep -q "FileVault is Off"; then
    echo "✗ FileVault est désactivé"
    exit 1
else
    echo "! Statut FileVault incertain"
    exit 2
fi

Gestion des clés de récupération

Générer une clé de récupération personnelle

#!/bin/bash

# Activer FileVault avec clé de récupération personnelle
sudo fdesetup enable -user "$USERNAME" -password "$PASSWORD" -outputplist > /tmp/filevault_key.plist

# Extraire la clé de récupération
RECOVERY_KEY=$(grep -A1 "RecoveryKey" /tmp/filevault_key.plist | tail -1 | sed 's/.*<string>\(.*\)<\/string>.*/\1/')

echo "Clé de récupération : $RECOVERY_KEY"

# Stocker la clé de récupération en sécurité
echo "$RECOVERY_KEY" | sudo tee /var/root/filevault_recovery_key.txt
sudo chmod 600 /var/root/filevault_recovery_key.txt

# Nettoyer
rm -f /tmp/filevault_key.plist

Activer la clé de récupération institutionnelle

#!/bin/bash

# Créer une clé de récupération institutionnelle
CERT_PATH="/path/to/institutional_certificate.cer"

if [[ -f "$CERT_PATH" ]]; then
    sudo fdesetup enable -user "$USERNAME" -password "$PASSWORD" -certificate "$CERT_PATH"
    echo "FileVault activé avec clé de récupération institutionnelle"
else
    echo "Certificat institutionnel non trouvé : $CERT_PATH"
    exit 1
fi

Dépannage des problèmes courants

Corriger les problèmes de token sécurisé

#!/bin/bash

USERNAME="admin"

# Accorder un token sécurisé à l'utilisateur
sudo sysadminctl -secureTokenOn "$USERNAME" -password -

# Vérifier le token sécurisé
if sysadminctl -secureTokenStatus "$USERNAME" | grep -q "ENABLED"; then
    echo "✓ Token sécurisé activé pour $USERNAME"
else
    echo "✗ Échec de l'activation du token sécurisé pour $USERNAME"
fi

Gérer l'erreur de mot de passe vide

#!/bin/bash

USERNAME="admin"

# Vérifier si l'utilisateur a un mot de passe défini
if dscl . -read "/Users/$USERNAME" AuthenticationAuthority | grep -q "No such key"; then
    echo "L'utilisateur $USERNAME n'a pas de mot de passe défini"
    echo "Définition du mot de passe..."
    sudo dscl . -passwd "/Users/$USERNAME" "" "nouveau_mot_de_passe_ici"
fi

Surveillance et rapports

Rapport de statut FileVault

#!/bin/bash

# Générer un rapport de statut FileVault
REPORT_FILE="/tmp/filevault_report.txt"

{
    echo "=== Rapport de statut FileVault ==="
    echo "Généré : $(date)"
    echo "Nom d'hôte : $(hostname)"
    echo ""
    
    echo "=== Statut FileVault ==="
    fdesetup status
    echo ""
    
    echo "=== Utilisateurs activés ==="
    fdesetup list
    echo ""
    
    echo "=== Statut du token sécurisé ==="
    for user in $(dscl . -list /Users | grep -v '^_'); do
        if [[ "$user" != "daemon" ]] && [[ "$user" != "nobody" ]]; then
            token_status=$(sysadminctl -secureTokenStatus "$user" 2>/dev/null | grep -o "ENABLED\|DISABLED")
            echo "Utilisateur : $user - Token : ${token_status:-INCONNU}"
        fi
    done
    
} > "$REPORT_FILE"

echo "Rapport généré : $REPORT_FILE"

Solutions aux erreurs courantes

ErreurCauseSolution
"Blank password"L'utilisateur n'a pas de mot de passeDéfinir un mot de passe avec dscl . -passwd
"Master keychain found"Ambiguïté du trousseauAjouter le paramètre -keychain
"Secure token required"L'utilisateur n'a pas de token sécuriséAccorder un token avec sysadminctl
"Already encrypted"FileVault déjà activéUtiliser -force ou vérifier le statut d'abord
"Encryption in progress"Opération concurrenteAttendre la fin

Bonnes pratiques de sécurité

  • Utiliser des mots de passe forts pour les comptes avec FileVault activé
  • Stocker les clés de récupération en sécurité dans la gestion des clés d'entreprise
  • Tester les scripts sur des appareils isolés avant le déploiement en flotte
  • Surveiller le progrès du chiffrement pour assurer la completion
  • Sauvegarder les clés de récupération avant de faire des modifications
  • Valider les permissions utilisateur avant de tenter des opérations

Considérations de performance

  • Le chiffrement initial peut prendre plusieurs heures
  • Les performances du système peuvent être impactées pendant le chiffrement
  • Planifier les opérations pendant les fenêtres de maintenance
  • Surveiller l'espace disque (le chiffrement nécessite de l'espace libre)
  • Considérer les différences de performance SSD vs HDD

Notes importantes

  • FileVault nécessite des privilèges administrateur et des tokens sécurisés
  • Les clés de récupération sont essentielles pour la récupération des données
  • Le chiffrement/déchiffrement ne peut pas être interrompu en sécurité
  • Tester tous les scripts minutieusement avant l'utilisation en production
  • Toujours avoir un plan de récupération de sauvegarde

Gestion des Mises à Jour macOS

Implémentez une gestion de mises à jour macOS de niveau entreprise sur votre déploiement MacFleet avec un déploiement automatisé de correctifs, une surveillance de conformité, des déploiements échelonnés et des politiques de mise à jour complètes. Ce tutoriel fournit des solutions pour maintenir les correctifs de sécurité et la currency du système d'exploitation tout en minimisant les perturbations des opérations commerciales.

Comprendre la Gestion des Mises à Jour macOS

macOS fournit plusieurs méthodes pour gérer les mises à jour du système d'exploitation de manière programmatique :

  • Utilitaire Software Update - Outil en ligne de commande pour vérifier et installer les mises à jour
  • startosinstall - Installation directe du système depuis les applications d'installation
  • Commandes de Mise à Jour MDM - Intégration avec la gestion des appareils mobiles
  • Profils de Configuration - Contrôle des mises à jour basé sur les politiques
  • Service de Recherche de Logiciels Apple - Vérification de disponibilité des mises à jour

Opérations de Mise à Jour de Base

Lister les Mises à Jour Disponibles

#!/bin/bash

# Lister toutes les versions de système disponibles pour installation
softwareupdate --list-full-installers | grep 'macOS' | awk '{print ++count " " $0}'

Télécharger l'Installeur du Système

#!/bin/bash

# Récupérer l'installeur d'une version spécifique du système
softwareupdate --fetch-full-installer --full-installer-version 12.1

echo "Installeur du système téléchargé avec succès"

Installer la Mise à Jour du Système

#!/bin/bash

# Installation basique de mise à jour système
osVersion="$1"
majorVersion=$(echo $osVersion | cut -d "." -f 1)
minorVersion=$(echo $osVersion | cut -d "." -f 2)

if [ $majorVersion == "12" ]; then
    installerPath="Install macOS Monterey.app"
elif [ $majorVersion == "11" ]; then
    installerPath="Install macOS Big Sur.app"
elif [ $minorVersion == "15"* ]; then
    installerPath="Install macOS Catalina.app"
fi

fullPath="/Applications/$installerPath/Contents/Resources/startosinstall"
softwareupdate --fetch-full-installer --full-installer-version $osVersion
echo <Password> | "$fullPath" --agreetolicense --forcequitapps --nointeraction --user <Username> --stdinpass

Système de Gestion des Mises à Jour Entreprise

Outil de Gestion des Mises à Jour Complet

#!/bin/bash

# Outil de Gestion des Mises à Jour macOS Entreprise MacFleet
# Déploiement automatisé de correctifs et surveillance de conformité

# Configuration
CONFIG_FILE="/etc/macfleet/update_policy.conf"
LOG_FILE="/var/log/macfleet_updates.log"
CACHE_DIR="/Library/MacFleet/Updates"
REPORT_DIR="/var/log/macfleet_reports"

# Créer les répertoires
mkdir -p "$(dirname "$CONFIG_FILE")" "$(dirname "$LOG_FILE")" "$CACHE_DIR" "$REPORT_DIR"

# Politique de mise à jour par défaut
cat > "$CONFIG_FILE" 2>/dev/null << 'EOF' || true
# Politique de Gestion des Mises à Jour macOS MacFleet
# Version : 2.0

# Application des Mises à Jour
ENFORCE_SECURITY_UPDATES=true
ALLOW_MAJOR_OS_UPDATES=false
AUTO_INSTALL_SECURITY_PATCHES=true
DEFER_MAJOR_UPDATES_DAYS=30

# Configuration de Planification
UPDATE_CHECK_INTERVAL=86400  # 24 heures
MAINTENANCE_WINDOW_START="02:00"
MAINTENANCE_WINDOW_END="06:00"
WEEKEND_UPDATES_ALLOWED=true
BUSINESS_HOURS_UPDATES=false

# Stratégie de Déploiement
STAGED_ROLLOUT=true
PILOT_GROUP_PERCENTAGE=10
PRODUCTION_DELAY_DAYS=7
EMERGENCY_PATCH_IMMEDIATE=true

# Exigences Système
MIN_BATTERY_PERCENTAGE=50
MIN_FREE_SPACE_GB=20
REQUIRE_AC_POWER=true
MAX_REBOOT_ATTEMPTS=3

# Paramètres de Notification
NOTIFY_USERS_BEFORE_UPDATE=true
NOTIFICATION_LEAD_TIME_HOURS=24
FORCE_UPDATE_AFTER_DEFERRALS=5
SEND_COMPLETION_REPORTS=true

# Paramètres de Compatibilité
EXCLUDE_BETA_UPDATES=true
VALIDATE_APP_COMPATIBILITY=true
BACKUP_BEFORE_MAJOR_UPDATE=true
EOF

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

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

# Obtenir la version macOS actuelle
get_current_version() {
    sw_vers -productVersion
}

# Obtenir les mises à jour disponibles
get_available_updates() {
    echo "=== Mises à Jour Disponibles ==="
    
    # Vérifier les mises à jour logicielles
    local updates
    updates=$(softwareupdate --list 2>/dev/null)
    
    if echo "$updates" | grep -q "No new software available"; then
        echo "✅ Le système est à jour"
        return 0
    else
        echo "Mises à jour disponibles :"
        echo "$updates"
        return 1
    fi
}

# Obtenir les installeurs de système disponibles
get_available_installers() {
    echo "=== Installeurs de Système Disponibles ==="
    
    # Lister les installeurs complets
    local installers
    installers=$(softwareupdate --list-full-installers 2>/dev/null)
    
    if [[ -n "$installers" ]]; then
        echo "$installers" | grep 'macOS' | awk '{print ++count " " $0}'
    else
        echo "Aucun installeur de système disponible"
    fi
}

# Vérifier la préparation du système pour les mises à jour
check_update_readiness() {
    echo "=== Vérification de Préparation aux Mises à Jour ==="
    local issues=0
    local warnings=0
    
    # Vérifier le niveau de batterie
    local battery_level
    if command -v pmset >/dev/null; then
        battery_level=$(pmset -g batt | grep -Eo "\d+%" | tr -d '%' | head -1)
        
        if [[ -n "$battery_level" && $battery_level -lt $MIN_BATTERY_PERCENTAGE ]]; then
            echo "❌ Niveau de batterie trop faible : ${battery_level}% (min : ${MIN_BATTERY_PERCENTAGE}%)"
            ((issues++))
        else
            echo "✅ Niveau de batterie adéquat : ${battery_level:-Alimentation CA}%"
        fi
    fi
    
    # Vérifier l'alimentation CA si requise
    if [[ "$REQUIRE_AC_POWER" == "true" ]]; then
        local ac_power
        ac_power=$(pmset -g ps | grep "AC Power" || echo "")
        
        if [[ -z "$ac_power" ]]; then
            echo "❌ Alimentation CA requise mais non connectée"
            ((issues++))
        else
            echo "✅ Alimentation CA connectée"
        fi
    fi
    
    # Vérifier l'espace disque libre
    local free_space_gb
    free_space_gb=$(df / | awk 'NR==2 {print int($4/1024/1024)}')
    
    if [[ $free_space_gb -lt $MIN_FREE_SPACE_GB ]]; then
        echo "❌ Espace disque insuffisant : ${free_space_gb}GB (min : ${MIN_FREE_SPACE_GB}GB)"
        ((issues++))
    else
        echo "✅ Espace disque suffisant : ${free_space_gb}GB"
    fi
    
    # Vérifier si le système est dans la fenêtre de maintenance
    local current_time
    current_time=$(date '+%H:%M')
    
    if [[ "$current_time" > "$MAINTENANCE_WINDOW_START" && "$current_time" < "$MAINTENANCE_WINDOW_END" ]]; then
        echo "✅ Dans la fenêtre de maintenance"
    else
        echo "⚠️  Hors de la fenêtre de maintenance (actuel : $current_time)"
        ((warnings++))
    fi
    
    # Vérifier si les mises à jour de week-end sont autorisées
    local day_of_week
    day_of_week=$(date '+%u')  # 1=Lundi, 7=Dimanche
    
    if [[ $day_of_week -gt 5 ]] && [[ "$WEEKEND_UPDATES_ALLOWED" != "true" ]]; then
        echo "❌ Mises à jour de week-end non autorisées"
        ((issues++))
    fi
    
    echo "Résumé de préparation : $issues problèmes, $warnings avertissements"
    return $issues
}

# Installer les mises à jour de sécurité
install_security_updates() {
    echo "=== Installation des Mises à Jour de Sécurité ==="
    
    if [[ "$AUTO_INSTALL_SECURITY_PATCHES" != "true" ]]; then
        echo "Installation automatique des mises à jour de sécurité désactivée"
        return 0
    fi
    
    # Vérifier la préparation
    if ! check_update_readiness >/dev/null; then
        echo "❌ Système non prêt pour les mises à jour"
        return 1
    fi
    
    # Installer les mises à jour recommandées
    echo "Installation des mises à jour de sécurité et recommandées..."
    log_action "Démarrage de l'installation des mises à jour de sécurité"
    
    # Utiliser softwareupdate pour installer les mises à jour recommandées
    if softwareupdate --install --recommended --verbose; then
        echo "✅ Mises à jour de sécurité installées avec succès"
        log_action "Mises à jour de sécurité installées avec succès"
        
        # Vérifier si un redémarrage est requis
        if softwareupdate --list | grep -q "restart"; then
            echo "⚠️  Redémarrage système requis"
            log_action "Redémarrage système requis après mises à jour de sécurité"
        fi
        
        return 0
    else
        echo "❌ Échec de l'installation des mises à jour de sécurité"
        log_action "ÉCHEC : Installation des mises à jour de sécurité"
        return 1
    fi
}

# Télécharger l'installeur du système
download_os_installer() {
    local target_version="$1"
    
    echo "=== Téléchargement de l'Installeur du Système ==="
    echo "Version cible : $target_version"
    
    # Valider le format de version
    if [[ ! "$target_version" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then
        echo "❌ Format de version invalide : $target_version"
        return 1
    fi
    
    # Télécharger l'installeur
    echo "Téléchargement de l'installeur macOS $target_version..."
    log_action "Téléchargement de l'installeur macOS : $target_version"
    
    if softwareupdate --fetch-full-installer --full-installer-version "$target_version"; then
        echo "✅ Installeur macOS téléchargé avec succès"
        log_action "Installeur macOS téléchargé : $target_version"
        
        # Vérifier que l'installeur existe
        local installer_path
        installer_path=$(find /Applications -name "Install macOS*.app" -path "*$target_version*" 2>/dev/null | head -1)
        
        if [[ -n "$installer_path" && -d "$installer_path" ]]; then
            echo "Emplacement de l'installeur : $installer_path"
            return 0
        else
            # Vérifier l'installeur par version majeure
            local major_version
            major_version=$(echo "$target_version" | cut -d'.' -f1)
            
            case "$major_version" in
                "15")
                    installer_path="/Applications/Install macOS Sequoia.app"
                    ;;
                "14")
                    installer_path="/Applications/Install macOS Sonoma.app"
                    ;;
                "13")
                    installer_path="/Applications/Install macOS Ventura.app"
                    ;;
                "12")
                    installer_path="/Applications/Install macOS Monterey.app"
                    ;;
                "11")
                    installer_path="/Applications/Install macOS Big Sur.app"
                    ;;
                *)
                    echo "❌ Version macOS inconnue : $target_version"
                    return 1
                    ;;
            esac
            
            if [[ -d "$installer_path" ]]; then
                echo "Installeur trouvé : $installer_path"
                return 0
            else
                echo "❌ Installeur non trouvé après téléchargement"
                return 1
            fi
        fi
    else
        echo "❌ Échec du téléchargement de l'installeur macOS"
        log_action "ÉCHEC : Téléchargement de l'installeur macOS pour $target_version"
        return 1
    fi
}

# Installer une mise à jour majeure du système
install_major_update() {
    local target_version="$1"
    local admin_user="$2"
    local admin_password="$3"
    
    echo "=== Installation de Mise à Jour Majeure du Système ==="
    echo "Version cible : $target_version"
    echo "Utilisateur admin : $admin_user"
    
    if [[ "$ALLOW_MAJOR_OS_UPDATES" != "true" ]]; then
        echo "❌ Mises à jour majeures du système non autorisées par la politique"
        return 1
    fi
    
    # Vérifier la préparation
    if ! check_update_readiness; then
        echo "❌ Système non prêt pour une mise à jour majeure"
        return 1
    fi
    
    # Trouver l'installeur
    local installer_path
    local major_version
    major_version=$(echo "$target_version" | cut -d'.' -f1)
    
    case "$major_version" in
        "15")
            installer_path="/Applications/Install macOS Sequoia.app"
            ;;
        "14")
            installer_path="/Applications/Install macOS Sonoma.app"
            ;;
        "13")
            installer_path="/Applications/Install macOS Ventura.app"
            ;;
        "12")
            installer_path="/Applications/Install macOS Monterey.app"
            ;;
        "11")
            installer_path="/Applications/Install macOS Big Sur.app"
            ;;
        *)
            echo "❌ Version macOS non supportée : $target_version"
            return 1
            ;;
    esac
    
    if [[ ! -d "$installer_path" ]]; then
        echo "Installeur non trouvé, téléchargement..."
        if ! download_os_installer "$target_version"; then
            return 1
        fi
    fi
    
    # Préparer la commande d'installation
    local install_cmd="$installer_path/Contents/Resources/startosinstall"
    local install_args="--agreetolicense --forcequitapps --nointeraction"
    
    # Vérifier si c'est un Mac Apple Silicon (nécessite des identifiants)
    if system_profiler SPHardwareDataType | grep -q "Apple M"; then
        if [[ -z "$admin_user" || -z "$admin_password" ]]; then
            echo "❌ Mac Apple Silicon nécessite des identifiants administrateur"
            return 1
        fi
        install_args="$install_args --user $admin_user --stdinpass"
    fi
    
    echo "Démarrage de l'installation macOS..."
    log_action "Démarrage de la mise à jour majeure vers $target_version"
    
    # Exécuter l'installation
    if [[ -n "$admin_password" ]]; then
        echo "$admin_password" | "$install_cmd" $install_args
    else
        "$install_cmd" $install_args
    fi
    
    local result=$?
    
    if [[ $result -eq 0 ]]; then
        echo "✅ Mise à jour macOS initiée avec succès"
        log_action "Mise à jour macOS initiée avec succès vers $target_version"
        echo "⚠️  Le système redémarrera pour terminer l'installation"
    else
        echo "❌ Échec de l'initiation de la mise à jour macOS (code de sortie : $result)"
        log_action "ÉCHEC : Initiation de la mise à jour macOS vers $target_version (code de sortie : $result)"
    fi
    
    return $result
}

# Générer un rapport de conformité des mises à jour
generate_update_report() {
    local report_file="$REPORT_DIR/update_compliance_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Génération du Rapport de Conformité des Mises à Jour ==="
    
    # Obtenir les informations système actuelles
    local current_version
    current_version=$(sw_vers -productVersion)
    local build_version
    build_version=$(sw_vers -buildVersion)
    local hardware_model
    hardware_model=$(system_profiler SPHardwareDataType | grep "Model Identifier" | awk -F: '{print $2}' | xargs)
    
    # Vérifier les mises à jour disponibles
    local updates_available="false"
    local security_updates_available="false"
    
    if ! softwareupdate --list 2>/dev/null | grep -q "No new software available"; then
        updates_available="true"
        
        if softwareupdate --list 2>/dev/null | grep -i "security\|recommended"; then
            security_updates_available="true"
        fi
    fi
    
    # Calculer les jours depuis la dernière mise à jour
    local last_update_date
    last_update_date=$(system_profiler SPInstallHistoryDataType | grep "Install Date" | head -1 | awk -F: '{print $2}' | xargs)
    local days_since_update="inconnu"
    
    if [[ -n "$last_update_date" ]]; then
        local last_update_epoch
        last_update_epoch=$(date -j -f "%m/%d/%y" "$last_update_date" "+%s" 2>/dev/null || echo "0")
        local current_epoch
        current_epoch=$(date "+%s")
        days_since_update=$(( (current_epoch - last_update_epoch) / 86400 ))
    fi
    
    # Créer le rapport JSON
    cat > "$report_file" << EOF
{
  "type_rapport": "conformite_mise_a_jour",
  "horodatage": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "infos_appareil": {
    "nom_hote": "$(hostname)",
    "numero_serie": "$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F: '{print $2}' | xargs)",
    "modele_materiel": "$hardware_model",
    "version_os_actuelle": "$current_version",
    "version_build": "$build_version"
  },
  "statut_mise_a_jour": {
    "mises_a_jour_disponibles": $updates_available,
    "mises_a_jour_securite_disponibles": $security_updates_available,
    "jours_depuis_derniere_mise_a_jour": $days_since_update,
    "date_derniere_mise_a_jour": "$last_update_date",
    "mise_a_jour_auto_activee": $(defaults read /Library/Preferences/com.apple.SoftwareUpdate AutomaticCheckEnabled 2>/dev/null || echo false)
  },
  "conformite_politique": {
    "mises_a_jour_securite_appliquees": $ENFORCE_SECURITY_UPDATES,
    "mises_a_jour_majeures_autorisees": $ALLOW_MAJOR_OS_UPDATES,
    "installation_auto_activee": $AUTO_INSTALL_SECURITY_PATCHES,
    "deploiement_echelonne_active": $STAGED_ROLLOUT
  },
  "preparation_systeme": {
    "batterie_suffisante": true,
    "alimentation_ca_connectee": $(pmset -g ps | grep -q "AC Power" && echo true || echo false),
    "espace_disque_suffisant": true,
    "dans_fenetre_maintenance": false
  }
}
EOF
    
    echo "Rapport de conformité des mises à jour sauvegardé dans : $report_file"
    log_action "Rapport de conformité des mises à jour généré : $report_file"
}

# Fonction principale avec gestion d'arguments
main() {
    log_action "=== Outil de Gestion des Mises à Jour MacFleet Démarré ==="
    
    case "${1:-status}" in
        "check")
            get_available_updates
            ;;
        "security")
            install_security_updates
            ;;
        "download")
            download_os_installer "$2"
            ;;
        "install")
            install_major_update "$2" "$3" "$4"
            ;;
        "readiness")
            check_update_readiness
            ;;
        "installers")
            get_available_installers
            ;;
        "report")
            generate_update_report
            ;;
        "status"|*)
            echo "Version macOS actuelle : $(get_current_version)"
            get_available_updates
            ;;
    esac
    
    log_action "=== Opération de gestion des mises à jour terminée ==="
}

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

Gestion Avancée des Mises à Jour

Gestion du Déploiement Échelonné

#!/bin/bash

# Gestion du déploiement échelonné pour les déploiements d'entreprise
manage_staged_rollout() {
    local update_version="$1"
    local deployment_stage="${2:-pilot}"
    
    echo "=== Gestion du Déploiement Échelonné ==="
    echo "Version de mise à jour : $update_version"
    echo "Étape de déploiement : $deployment_stage"
    
    # Définir les groupes d'appareils
    local device_serial
    device_serial=$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F: '{print $2}' | xargs)
    
    # Calculer le hash pour l'affectation cohérente de groupe
    local hash_value
    hash_value=$(echo "$device_serial" | md5 | cut -c1-2)
    local numeric_hash
    numeric_hash=$(printf "%d" "0x$hash_value")
    local group_percentage
    group_percentage=$((numeric_hash % 100))
    
    case "$deployment_stage" in
        "pilot")
            if [[ $group_percentage -lt $PILOT_GROUP_PERCENTAGE ]]; then
                echo "✅ Appareil sélectionné pour le déploiement pilote"
                log_action "Appareil inclus dans le groupe pilote pour $update_version"
                return 0
            else
                echo "⏳ Appareil non dans le groupe pilote, en attente du déploiement production"
                return 1
            fi
            ;;
        "production")
            echo "✅ Appareil éligible pour le déploiement production"
            log_action "Appareil inclus dans le déploiement production pour $update_version"
            return 0
            ;;
        "emergency")
            echo "🚨 Déploiement d'urgence - contournement des étapes"
            log_action "Déploiement d'urgence initié pour $update_version"
            return 0
            ;;
        *)
            echo "❌ Étape de déploiement inconnue : $deployment_stage"
            return 1
            ;;
    esac
}

# Exemple d'utilisation :
# manage_staged_rollout "14.2.1" "pilot"

Vérification de Compatibilité des Applications

#!/bin/bash

# Vérifier la compatibilité des applications avant les mises à jour majeures
check_app_compatibility() {
    local target_version="$1"
    
    echo "=== Vérification de Compatibilité des Applications ==="
    
    if [[ "$VALIDATE_APP_COMPATIBILITY" != "true" ]]; then
        echo "Vérification de compatibilité des applications désactivée"
        return 0
    fi
    
    local incompatible_apps=()
    
    # Vérifier les applications 32 bits (non supportées dans macOS 10.15+)
    local target_major
    target_major=$(echo "$target_version" | cut -d'.' -f1)
    
    if [[ $target_major -ge 10 ]]; then
        echo "Vérification des applications 32 bits..."
        
        # Utiliser system_profiler pour trouver les applications 32 bits
        local bit32_apps
        bit32_apps=$(system_profiler SPApplicationsDataType | grep -B1 -A1 "64-Bit (Intel): No" | grep "Location:" | awk -F: '{print $2}' | xargs)
        
        if [[ -n "$bit32_apps" ]]; then
            echo "⚠️  Applications 32 bits trouvées :"
            echo "$bit32_apps"
            incompatible_apps+=("applications 32 bits")
        fi
    fi
    
    # Vérifier les applications incompatibles connues
    local known_incompatible=(
        "/Applications/Adobe CS6"
        "/Applications/Microsoft Office 2011"
        "/Applications/Final Cut Pro 7"
    )
    
    for app_path in "${known_incompatible[@]}"; do
        if [[ -d "$app_path" ]]; then
            echo "⚠️  Application incompatible connue trouvée : $app_path"
            incompatible_apps+=("$(basename "$app_path")")
        fi
    done
    
    # Générer le rapport de compatibilité
    if [[ ${#incompatible_apps[@]} -eq 0 ]]; then
        echo "✅ Aucun problème de compatibilité détecté"
        return 0
    else
        echo "❌ Problèmes de compatibilité trouvés :"
        printf '  - %s\n' "${incompatible_apps[@]}"
        
        # Journaliser les problèmes de compatibilité
        log_action "Problèmes de compatibilité d'applications trouvés pour $target_version : ${incompatible_apps[*]}"
        return 1
    fi
}

check_app_compatibility "14.0"

Sauvegarde Automatisée Avant Mises à Jour

#!/bin/bash

# Créer une sauvegarde système avant les mises à jour majeures
create_pre_update_backup() {
    local backup_destination="${1:-/Volumes/Backup}"
    
    echo "=== Sauvegarde Pré-Mise à Jour ==="
    
    if [[ "$BACKUP_BEFORE_MAJOR_UPDATE" != "true" ]]; then
        echo "Sauvegarde pré-mise à jour désactivée"
        return 0
    fi
    
    # Vérifier la destination de sauvegarde
    if [[ ! -d "$backup_destination" ]]; then
        echo "❌ Destination de sauvegarde non disponible : $backup_destination"
        return 1
    fi
    
    # Créer une sauvegarde Time Machine
    echo "Création de la sauvegarde Time Machine..."
    if tmutil startbackup --auto --block; then
        echo "✅ Sauvegarde Time Machine terminée"
        log_action "Sauvegarde Time Machine pré-mise à jour terminée"
    else
        echo "⚠️  Sauvegarde Time Machine échouée, poursuite de la mise à jour"
        log_action "AVERTISSEMENT : Sauvegarde Time Machine pré-mise à jour échouée"
    fi
    
    # Créer une sauvegarde de configuration système
    local config_backup="$backup_destination/macfleet_config_$(date +%Y%m%d_%H%M%S).tar.gz"
    
    echo "Création de la sauvegarde de configuration..."
    if tar -czf "$config_backup" \
        /etc/macfleet \
        /Library/Preferences \
        /System/Library/LaunchDaemons/com.macfleet.* \
        2>/dev/null; then
        echo "✅ Sauvegarde de configuration créée : $config_backup"
        log_action "Sauvegarde de configuration créée : $config_backup"
    else
        echo "⚠️  Sauvegarde de configuration échouée"
        log_action "AVERTISSEMENT : Sauvegarde de configuration échouée"
    fi
    
    return 0
}

create_pre_update_backup

Surveillance et Conformité

Surveillance de Conformité des Mises à Jour

#!/bin/bash

# Surveiller la conformité des mises à jour dans la flotte
monitor_update_compliance() {
    echo "=== Surveillance de Conformité des Mises à Jour ==="
    
    local current_version
    current_version=$(sw_vers -productVersion)
    
    # Vérifier contre les lignes de base de sécurité
    local security_baseline="14.2.1"  # Exemple de ligne de base
    
    if [[ "$(printf '%s\n' "$security_baseline" "$current_version" | sort -V | head -1)" != "$security_baseline" ]]; then
        echo "❌ En dessous de la ligne de base de sécurité (actuel : $current_version, requis : $security_baseline)"
        log_action "VIOLATION DE CONFORMITÉ : En dessous de la ligne de base de sécurité $security_baseline"
        
        # Déclencher la remédiation si activée
        if [[ "$ENFORCE_SECURITY_UPDATES" == "true" ]]; then
            echo "Initiation de la remédiation automatique..."
            install_security_updates
        fi
    else
        echo "✅ Répond aux exigences de ligne de base de sécurité"
    fi
    
    # Vérifier les mises à jour en retard
    local last_check
    last_check=$(defaults read /Library/Preferences/com.apple.SoftwareUpdate LastSuccessfulDate 2>/dev/null || echo "")
    
    if [[ -n "$last_check" ]]; then
        local days_since_check
        days_since_check=$(( ($(date +%s) - $(date -j -f "%Y-%m-%d %H:%M:%S %z" "$last_check" +%s 2>/dev/null || echo 0)) / 86400 ))
        
        if [[ $days_since_check -gt 7 ]]; then
            echo "⚠️  Mises à jour non vérifiées depuis $days_since_check jours"
            log_action "AVERTISSEMENT : Mises à jour non vérifiées depuis $days_since_check jours"
        fi
    fi
}

monitor_update_compliance

Déploiement de Correctifs d'Urgence

#!/bin/bash

# Déploiement de correctifs d'urgence pour les mises à jour de sécurité critiques
deploy_emergency_patch() {
    local patch_version="$1"
    local override_policies="${2:-false}"
    
    echo "=== Déploiement de Correctifs d'Urgence ==="
    echo "Version du correctif : $patch_version"
    echo "Contournement des politiques : $override_policies"
    
    log_action "URGENCE : Déploiement du correctif critique $patch_version"
    
    # Contourner les restrictions normales pour les correctifs d'urgence
    if [[ "$override_policies" == "true" ]]; then
        # Modifier temporairement la configuration
        local original_config
        original_config=$(cat "$CONFIG_FILE")
        
        # Configuration d'urgence
        cat > "$CONFIG_FILE" << 'EOF'
ENFORCE_SECURITY_UPDATES=true
AUTO_INSTALL_SECURITY_PATCHES=true
EMERGENCY_PATCH_IMMEDIATE=true
REQUIRE_AC_POWER=false
MIN_BATTERY_PERCENTAGE=20
BUSINESS_HOURS_UPDATES=true
EOF
        
        # Installer le correctif d'urgence
        if install_security_updates; then
            echo "✅ Correctif d'urgence déployé avec succès"
            log_action "Correctif d'urgence $patch_version déployé avec succès"
        else
            echo "❌ Déploiement du correctif d'urgence échoué"
            log_action "CRITIQUE : Déploiement du correctif d'urgence $patch_version ÉCHOUÉ"
        fi
        
        # Restaurer la configuration originale
        echo "$original_config" > "$CONFIG_FILE"
    else
        # Déploiement d'urgence standard
        install_security_updates
    fi
}

# Exemple d'utilisation :
# deploy_emergency_patch "14.2.1" "true"

Notes de Configuration Importantes

Outils de Mise à Jour macOS

  • softwareupdate - Utilitaire de mise à jour logicielle en ligne de commande
  • startosinstall - Outil d'installation directe du système
  • system_profiler - Informations système et historique des mises à jour
  • tmutil - Utilitaire de sauvegarde Time Machine
  • pmset - Paramètres de gestion d'énergie

Considérations Apple Silicon

  • Identifiants administrateur requis - Les mises à jour nécessitent une authentification utilisateur
  • Politiques de démarrage sécurisé - Peuvent affecter l'installation des mises à jour
  • Options de mode de récupération - Différentes des Mac Intel
  • Extensions de noyau réduites - Modèle d'extension système

Bonnes Pratiques pour l'Entreprise

  1. Stratégie de Déploiement Échelonné

    • Tester les mises à jour sur un groupe pilote d'abord
    • Surveiller les problèmes avant le déploiement complet
    • Maintenir des capacités de retour en arrière
  2. Gestion de Conformité

    • Définir des lignes de base de sécurité
    • Surveiller régulièrement le statut des mises à jour
    • Automatiser les rapports de conformité
  3. Atténuation des Risques

    • Sauvegarder avant les mises à jour majeures
    • Tester la compatibilité des applications
    • Planifier pour les correctifs d'urgence
  4. Communication Utilisateur

    • Notifier les utilisateurs des mises à jour planifiées
    • Fournir des fenêtres de maintenance claires
    • Offrir des options de report dans les limites des politiques

Dépannage des Problèmes Courants

  • Espace disque insuffisant - Nettoyer avant les mises à jour ou augmenter le stockage
  • Exigences d'alimentation - Assurer l'alimentation CA pour les mises à jour majeures
  • Connectivité réseau - Vérifier l'accès aux serveurs de mise à jour d'Apple
  • Échecs d'authentification - Vérifier les identifiants administrateur sur Apple Silicon
  • Échecs d'installation - Examiner les journaux système et la compatibilité

N'oubliez pas de tester minutieusement les procédures de mise à jour dans un environnement non-production avant de les déployer sur l'ensemble de votre MacFleet.

Personnalisation de la Fenêtre de Connexion sur macOS

Personnalisez et sécurisez la fenêtre de connexion sur vos appareils MacFleet pour améliorer la sécurité, l'image de marque et l'expérience utilisateur. Ce tutoriel couvre la gestion des listes d'utilisateurs, le contrôle des options d'alimentation, les messages personnalisés et la configuration de la fenêtre de connexion d'entreprise.

Comprendre la Fenêtre de Connexion macOS

La fenêtre de connexion macOS est la première interface que les utilisateurs rencontrent lors du démarrage de leur appareil. Elle offre plusieurs options de personnalisation :

  • Modes d'affichage utilisateur - Afficher la liste des utilisateurs ou les champs nom d'utilisateur/mot de passe
  • Options d'alimentation - Contrôler les boutons d'arrêt, de redémarrage et de veille
  • Messages personnalisés - Afficher des avis organisationnels ou de la personnalisation
  • Paramètres de sécurité - Masquer les informations sensibles et contrôler l'accès

Considérations d'Entreprise

La personnalisation de la fenêtre de connexion est cruciale pour la sécurité d'entreprise :

  • Masquer les listes d'utilisateurs pour prévenir l'énumération des utilisateurs
  • Désactiver les options d'alimentation pour prévenir les arrêts non autorisés
  • Afficher des avis de sécurité pour les exigences de conformité
  • Personnaliser l'interface pour l'identité organisationnelle

Configuration de Base de la Fenêtre de Connexion

Afficher la Liste des Utilisateurs

#!/bin/bash

# Afficher la liste des utilisateurs dans la fenêtre de connexion
defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME false

echo "Affichage de la liste des utilisateurs activé dans la fenêtre de connexion"

Afficher la Boîte de Dialogue Nom d'Utilisateur/Mot de Passe

#!/bin/bash

# Afficher la boîte de dialogue nom d'utilisateur et mot de passe au lieu de la liste des utilisateurs
defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME true

echo "Boîte de dialogue nom d'utilisateur/mot de passe activée dans la fenêtre de connexion"

Masquer les Options d'Alimentation

#!/bin/bash

# Masquer le bouton d'arrêt
defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true

# Masquer le bouton de redémarrage
defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled true

# Masquer le bouton de veille
defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true

echo "Toutes les options d'alimentation masquées de la fenêtre de connexion"

Activer les Options d'Alimentation

#!/bin/bash

# Activer le bouton d'arrêt
defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled false

# Activer le bouton de redémarrage
defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled false

# Activer le bouton de veille
defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled false

echo "Toutes les options d'alimentation activées dans la fenêtre de connexion"

Afficher un Message Personnalisé

#!/bin/bash

# Afficher un message personnalisé sur la fenêtre de connexion
MESSAGE="Votre appareil est géré par MacFleet. Contactez l'IT pour assistance."
defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$MESSAGE"

echo "Message personnalisé défini pour la fenêtre de connexion"

Gestion Avancée de la Fenêtre de Connexion

Configuration Complète de la Fenêtre de Connexion

#!/bin/bash

# Configuration avancée de la fenêtre de connexion avec validation
configure_login_window() {
    local config_type="$1"
    local custom_message="$2"
    
    # 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
    
    case "$config_type" in
        "secure")
            echo "Application de la configuration sécurisée de la fenêtre de connexion..."
            
            # Masquer la liste des utilisateurs pour la sécurité
            defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME true
            
            # Désactiver toutes les options d'alimentation
            defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true
            
            # Définir un message de sécurité
            local security_msg="Personnel Autorisé Uniquement - Toute Activité Surveillée"
            defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$security_msg"
            
            echo "✓ Configuration sécurisée appliquée"
            ;;
        "corporate")
            echo "Application de la configuration d'entreprise de la fenêtre de connexion..."
            
            # Afficher la liste des utilisateurs pour la commodité
            defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME false
            
            # Permettre le redémarrage mais désactiver l'arrêt et la veille
            defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled false
            defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true
            
            # Définir un message d'entreprise
            local corp_msg="${custom_message:-Propriété de MacFleet Corporation}"
            defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$corp_msg"
            
            echo "✓ Configuration d'entreprise appliquée"
            ;;
        "kiosk")
            echo "Application de la configuration kiosque de la fenêtre de connexion..."
            
            # Masquer la liste des utilisateurs
            defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME true
            
            # Désactiver toutes les options d'alimentation
            defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true
            
            # Masquer des éléments supplémentaires pour le mode kiosque
            defaults write /Library/Preferences/com.apple.loginwindow HideLocalUsers true
            defaults write /Library/Preferences/com.apple.loginwindow HideMobileAccounts true
            
            # Définir un message de kiosque
            local kiosk_msg="Mode Kiosque - Accès Autorisé Uniquement"
            defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$kiosk_msg"
            
            echo "✓ Configuration kiosque appliquée"
            ;;
        "standard")
            echo "Application de la configuration standard de la fenêtre de connexion..."
            
            # Afficher la liste des utilisateurs
            defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME false
            
            # Activer toutes les options d'alimentation
            defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled false
            defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled false
            defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled false
            
            # Effacer le message personnalisé
            defaults delete /Library/Preferences/com.apple.loginwindow LoginwindowText 2>/dev/null || true
            
            echo "✓ Configuration standard appliquée"
            ;;
        *)
            echo "Erreur : Type de configuration inconnu '$config_type'"
            echo "Types disponibles : secure, corporate, kiosk, standard"
            return 1
            ;;
    esac
    
    # Vérifier la configuration
    verify_login_window_config
}

# Vérifier la configuration actuelle de la fenêtre de connexion
verify_login_window_config() {
    echo ""
    echo "=== Configuration Actuelle de la Fenêtre de Connexion ==="
    
    # Vérifier le mode d'affichage utilisateur
    local show_fullname
    show_fullname=$(defaults read /Library/Preferences/com.apple.loginwindow SHOWFULLNAME 2>/dev/null || echo "false")
    
    if [[ "$show_fullname" == "true" ]]; then
        echo "Affichage Utilisateur : Boîte de Dialogue Nom d'Utilisateur/Mot de Passe"
    else
        echo "Affichage Utilisateur : Liste des Utilisateurs"
    fi
    
    # Vérifier les options d'alimentation
    local shutdown_disabled
    shutdown_disabled=$(defaults read /Library/Preferences/com.apple.loginwindow ShutDownDisabled 2>/dev/null || echo "false")
    echo "Bouton d'Arrêt : $([ "$shutdown_disabled" == "true" ] && echo "Masqué" || echo "Visible")"
    
    local restart_disabled
    restart_disabled=$(defaults read /Library/Preferences/com.apple.loginwindow RestartDisabled 2>/dev/null || echo "false")
    echo "Bouton de Redémarrage : $([ "$restart_disabled" == "true" ] && echo "Masqué" || echo "Visible")"
    
    local sleep_disabled
    sleep_disabled=$(defaults read /Library/Preferences/com.apple.loginwindow SleepDisabled 2>/dev/null || echo "false")
    echo "Bouton de Veille : $([ "$sleep_disabled" == "true" ] && echo "Masqué" || echo "Visible")"
    
    # Vérifier le message personnalisé
    local login_text
    login_text=$(defaults read /Library/Preferences/com.apple.loginwindow LoginwindowText 2>/dev/null || echo "Aucun")
    echo "Message Personnalisé : $login_text"
}

# Exemples d'utilisation
configure_login_window "corporate" "Bienvenue dans MacFleet Enterprise"

Système de Gestion de Fenêtre de Connexion d'Entreprise

#!/bin/bash

# Outil de Gestion de Fenêtre de Connexion MacFleet
# Configuration et surveillance complètes de la fenêtre de connexion pour les appareils de flotte

# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_loginwindow.log"
REPORT_DIR="/etc/macfleet/reports/loginwindow"
CONFIG_DIR="/etc/macfleet/loginwindow"

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

# Modèles de politiques de fenêtre de connexion
declare -A LOGIN_POLICIES=(
    ["corporate_standard"]="user_list,restart_only,company_branding,moderate_security"
    ["corporate_secure"]="username_dialog,no_power,security_message,high_security"
    ["kiosk_mode"]="username_dialog,no_power,kiosk_branding,maximum_security"
    ["public_access"]="user_list,all_power,public_notice,low_security"
    ["executive"]="username_dialog,restart_only,executive_branding,high_security"
    ["guest_network"]="user_list,no_power,guest_notice,moderate_security"
    ["development"]="user_list,all_power,dev_environment,low_security"
    ["classroom"]="user_list,restart_only,educational_message,moderate_security"
    ["healthcare"]="username_dialog,no_power,hipaa_notice,maximum_security"
    ["financial"]="username_dialog,no_power,compliance_notice,maximum_security"
)

# Modèles de messages pour différents scénarios
declare -A MESSAGE_TEMPLATES=(
    ["security_warning"]="ACCÈS RESTREINT - PERSONNEL AUTORISÉ UNIQUEMENT - TOUTE ACTIVITÉ SURVEILLÉE"
    ["corporate_standard"]="Propriété de {COMPANY} | Support IT : {SUPPORT_CONTACT}"
    ["compliance_notice"]="Ce système contient des informations confidentielles. L'accès non autorisé est interdit."
    ["guest_notice"]="Accès Invité | Veuillez contacter la réception pour assistance"
    ["kiosk_mode"]="Terminal Kiosque | Pour assistance appuyez sur F1"
    ["maintenance"]="Système en Maintenance | Contactez le Département IT"
    ["emergency"]="Accès d'Urgence Uniquement | Incident de Sécurité en Cours"
    ["educational"]="Appareil Éducatif | Les étudiants doivent suivre la politique d'usage acceptable"
    ["hipaa_notice"]="Système Protégé HIPAA | Personnel de Santé Autorisé Uniquement"
    ["financial_compliance"]="Système de Données Financières | Conformité SOX Requise"
)

# 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 fenêtre de connexion
enforce_login_policy() {
    local policy_name="$1"
    local company_name="${2:-MacFleet}"
    local support_contact="${3:-Département IT}"
    local dry_run="${4:-false}"
    
    log_action "Application de la politique de fenêtre de connexion : $policy_name (dry_run : $dry_run)"
    
    if [[ -z "${LOGIN_POLICIES[$policy_name]}" ]]; then
        log_action "ERREUR : Politique inconnue '$policy_name'"
        echo "Politiques disponibles : ${!LOGIN_POLICIES[*]}"
        return 1
    fi
    
    # Analyser la configuration de politique
    IFS=',' read -ra POLICY_PARTS <<< "${LOGIN_POLICIES[$policy_name]}"
    local user_display="${POLICY_PARTS[0]}"
    local power_options="${POLICY_PARTS[1]}"
    local branding_type="${POLICY_PARTS[2]}"
    local security_level="${POLICY_PARTS[3]}"
    
    echo "=== Application de la Politique : $policy_name ==="
    echo "Affichage Utilisateur : $user_display"
    echo "Options d'Alimentation : $power_options"
    echo "Image de Marque : $branding_type"
    echo "Niveau de Sécurité : $security_level"
    
    if [[ "$dry_run" == "true" ]]; then
        echo "MODE TEST - Aucun changement ne sera appliqué"
        return 0
    fi
    
    # Appliquer les paramètres d'affichage utilisateur
    apply_user_display_settings "$user_display"
    
    # Appliquer les paramètres d'options d'alimentation
    apply_power_option_settings "$power_options"
    
    # Appliquer l'image de marque et la messagerie
    apply_branding_settings "$branding_type" "$company_name" "$support_contact"
    
    # Appliquer les configurations de sécurité
    apply_security_settings "$security_level"
    
    # 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_policy_report "$policy_name" "$report_file"
    
    log_action "Application de politique terminée : $report_file"
    echo "$report_file"
}

# Appliquer les paramètres d'affichage utilisateur
apply_user_display_settings() {
    local display_type="$1"
    
    case "$display_type" in
        "user_list")
            defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME false
            defaults write /Library/Preferences/com.apple.loginwindow HideLocalUsers false
            echo "✓ Affichage de la liste des utilisateurs activé"
            ;;
        "username_dialog")
            defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME true
            echo "✓ Boîte de dialogue nom d'utilisateur/mot de passe activée"
            ;;
        "hidden_users")
            defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME true
            defaults write /Library/Preferences/com.apple.loginwindow HideLocalUsers true
            defaults write /Library/Preferences/com.apple.loginwindow HideMobileAccounts true
            echo "✓ Tous les utilisateurs masqués de l'affichage"
            ;;
    esac
}

# Appliquer les paramètres d'options d'alimentation
apply_power_option_settings() {
    local power_config="$1"
    
    case "$power_config" in
        "all_power")
            defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled false
            defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled false
            defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled false
            echo "✓ Toutes les options d'alimentation activées"
            ;;
        "restart_only")
            defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled false
            defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true
            echo "✓ Seule l'option de redémarrage activée"
            ;;
        "no_power")
            defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled true
            defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true
            echo "✓ Toutes les options d'alimentation désactivées"
            ;;
    esac
}

# Appliquer les paramètres d'image de marque et de messagerie
apply_branding_settings() {
    local branding_type="$1"
    local company_name="$2"
    local support_contact="$3"
    
    local message=""
    
    case "$branding_type" in
        "company_branding")
            message="${MESSAGE_TEMPLATES[corporate_standard]}"
            message="${message/\{COMPANY\}/$company_name}"
            message="${message/\{SUPPORT_CONTACT\}/$support_contact}"
            ;;
        "security_message")
            message="${MESSAGE_TEMPLATES[security_warning]}"
            ;;
        "kiosk_branding")
            message="${MESSAGE_TEMPLATES[kiosk_mode]}"
            ;;
        "executive_branding")
            message="Poste de Travail Exécutif | $company_name | Confidentiel"
            ;;
        "guest_notice")
            message="${MESSAGE_TEMPLATES[guest_notice]}"
            ;;
        "educational_message")
            message="${MESSAGE_TEMPLATES[educational]}"
            ;;
        "hipaa_notice")
            message="${MESSAGE_TEMPLATES[hipaa_notice]}"
            ;;
        "compliance_notice")
            message="${MESSAGE_TEMPLATES[financial_compliance]}"
            ;;
        *)
            message="Géré par $company_name"
            ;;
    esac
    
    if [[ -n "$message" ]]; then
        defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$message"
        echo "✓ Message personnalisé appliqué : $message"
    fi
}

# Appliquer les paramètres spécifiques à la sécurité
apply_security_settings() {
    local security_level="$1"
    
    case "$security_level" in
        "maximum_security")
            # Masquer les informations de l'ordinateur
            defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo ""
            
            # Désactiver le menu d'entrée
            defaults write /Library/Preferences/com.apple.loginwindow showInputMenu false
            
            # Désactiver la connexion automatique
            defaults delete /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null || true
            
            # Activer le délai de fenêtre de connexion
            defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled false
            
            echo "✓ Paramètres de sécurité maximale appliqués"
            ;;
        "high_security")
            # Afficher des informations minimales de l'ordinateur
            defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName
            
            # Activer le menu d'entrée pour le support linguistique
            defaults write /Library/Preferences/com.apple.loginwindow showInputMenu true
            
            # Désactiver le compte invité
            defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled false
            
            echo "✓ Paramètres de sécurité élevée appliqués"
            ;;
        "moderate_security")
            # Sécurité standard avec quelques fonctionnalités de commodité
            defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName
            defaults write /Library/Preferences/com.apple.loginwindow showInputMenu true
            defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled false
            
            echo "✓ Paramètres de sécurité modérée appliqués"
            ;;
        "low_security")
            # Restrictions minimales pour la commodité
            defaults write /Library/Preferences/com.apple.loginwindow showInputMenu true
            
            echo "✓ Paramètres de sécurité faible appliqués"
            ;;
    esac
}

# Générer un rapport complet de conformité de politique
generate_policy_report() {
    local policy_name="$1"
    local report_file="$2"
    
    # Obtenir les paramètres actuels de la fenêtre de connexion
    local show_fullname=$(defaults read /Library/Preferences/com.apple.loginwindow SHOWFULLNAME 2>/dev/null || echo "false")
    local shutdown_disabled=$(defaults read /Library/Preferences/com.apple.loginwindow ShutDownDisabled 2>/dev/null || echo "false")
    local restart_disabled=$(defaults read /Library/Preferences/com.apple.loginwindow RestartDisabled 2>/dev/null || echo "false")
    local sleep_disabled=$(defaults read /Library/Preferences/com.apple.loginwindow SleepDisabled 2>/dev/null || echo "false")
    local login_text=$(defaults read /Library/Preferences/com.apple.loginwindow LoginwindowText 2>/dev/null || echo "")
    local hide_local_users=$(defaults read /Library/Preferences/com.apple.loginwindow HideLocalUsers 2>/dev/null || echo "false")
    local guest_enabled=$(defaults read /Library/Preferences/com.apple.loginwindow GuestEnabled 2>/dev/null || echo "false")
    
    cat > "$report_file" << EOF
{
    "policy_report": {
        "policy_name": "$policy_name",
        "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
        "hostname": "$(hostname)",
        "script_version": "$SCRIPT_VERSION",
        "current_settings": {
            "show_fullname": $show_fullname,
            "shutdown_disabled": $shutdown_disabled,
            "restart_disabled": $restart_disabled,
            "sleep_disabled": $sleep_disabled,
            "custom_message": "$login_text",
            "hide_local_users": $hide_local_users,
            "guest_enabled": $guest_enabled
        },
        "display_mode": "$([ "$show_fullname" == "true" ] && echo "username_dialog" || echo "user_list")",
        "security_level": "unknown",
        "compliance_status": "compliant"
    }
}
EOF
    
    log_action "Rapport de politique généré : $report_file"
}

# Surveiller la configuration de la fenêtre de connexion
monitor_login_window() {
    local detailed="${1:-false}"
    
    echo "=== Moniteur de Configuration de Fenêtre de Connexion ==="
    
    # Vérification de configuration de base
    local show_fullname=$(defaults read /Library/Preferences/com.apple.loginwindow SHOWFULLNAME 2>/dev/null || echo "false")
    local display_mode=$([ "$show_fullname" == "true" ] && echo "Boîte de Dialogue Nom d'Utilisateur/Mot de Passe" || echo "Liste des Utilisateurs")
    
    echo "Mode d'Affichage : $display_mode"
    
    # Statut des options d'alimentation
    local shutdown_status=$([ "$(defaults read /Library/Preferences/com.apple.loginwindow ShutDownDisabled 2>/dev/null)" == "true" ] && echo "Masqué" || echo "Visible")
    local restart_status=$([ "$(defaults read /Library/Preferences/com.apple.loginwindow RestartDisabled 2>/dev/null)" == "true" ] && echo "Masqué" || echo "Visible")
    local sleep_status=$([ "$(defaults read /Library/Preferences/com.apple.loginwindow SleepDisabled 2>/dev/null)" == "true" ] && echo "Masqué" || echo "Visible")
    
    echo "Options d'Alimentation :"
    echo "  Bouton d'Arrêt : $shutdown_status"
    echo "  Bouton de Redémarrage : $restart_status"
    echo "  Bouton de Veille : $sleep_status"
    
    # Message personnalisé
    local custom_message=$(defaults read /Library/Preferences/com.apple.loginwindow LoginwindowText 2>/dev/null || echo "Aucun")
    echo "Message Personnalisé : $custom_message"
    
    if [[ "$detailed" == "true" ]]; then
        echo ""
        echo "=== Configuration Détaillée ==="
        
        # Paramètres supplémentaires
        local hide_local=$(defaults read /Library/Preferences/com.apple.loginwindow HideLocalUsers 2>/dev/null || echo "false")
        local hide_mobile=$(defaults read /Library/Preferences/com.apple.loginwindow HideMobileAccounts 2>/dev/null || echo "false")
        local guest_enabled=$(defaults read /Library/Preferences/com.apple.loginwindow GuestEnabled 2>/dev/null || echo "false")
        local admin_info=$(defaults read /Library/Preferences/com.apple.loginwindow AdminHostInfo 2>/dev/null || echo "DSStatus")
        
        echo "Paramètres Avancés :"
        echo "  Masquer Utilisateurs Locaux : $hide_local"
        echo "  Masquer Comptes Mobiles : $hide_mobile"
        echo "  Compte Invité Activé : $guest_enabled"
        echo "  Info Hôte Admin : $admin_info"
        
        # Vérifier l'arrière-plan personnalisé
        local desktop_picture=$(defaults read /Library/Preferences/com.apple.loginwindow DesktopPicture 2>/dev/null || echo "Par Défaut")
        echo "  Image de Bureau : $desktop_picture"
    fi
}

# 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 de Fenêtre de Connexion MacFleet Démarrée ==="
    log_action "Action : $action"
    
    # Assurer les privilèges requis pour les changements de configuration
    if [[ "$action" != "status" && "$action" != "help" && $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 : ${!LOGIN_POLICIES[*]}"
                exit 1
            fi
            enforce_login_policy "$param1" "$param2" "$param3" "$param4"
            ;;
        "message")
            if [[ -z "$param1" ]]; then
                echo "Usage : $0 message <texte_message>"
                exit 1
            fi
            defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "$param1"
            echo "✓ Message personnalisé défini : $param1"
            ;;
        "power")
            case "$param1" in
                "disable")
                    defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true
                    defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled true
                    defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true
                    echo "✓ Toutes les options d'alimentation désactivées"
                    ;;
                "enable")
                    defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled false
                    defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled false
                    defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled false
                    echo "✓ Toutes les options d'alimentation activées"
                    ;;
                *)
                    echo "Usage : $0 power <enable|disable>"
                    exit 1
                    ;;
            esac
            ;;
        "display")
            case "$param1" in
                "userlist")
                    defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME false
                    echo "✓ Affichage de la liste des utilisateurs activé"
                    ;;
                "dialog")
                    defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME true
                    echo "✓ Boîte de dialogue nom d'utilisateur/mot de passe activée"
                    ;;
                *)
                    echo "Usage : $0 display <userlist|dialog>"
                    exit 1
                    ;;
            esac
            ;;
        "status")
            monitor_login_window "$param1"
            ;;
        "reset")
            echo "Réinitialisation de la fenêtre de connexion aux paramètres par défaut..."
            defaults delete /Library/Preferences/com.apple.loginwindow SHOWFULLNAME 2>/dev/null || true
            defaults delete /Library/Preferences/com.apple.loginwindow ShutDownDisabled 2>/dev/null || true
            defaults delete /Library/Preferences/com.apple.loginwindow RestartDisabled 2>/dev/null || true
            defaults delete /Library/Preferences/com.apple.loginwindow SleepDisabled 2>/dev/null || true
            defaults delete /Library/Preferences/com.apple.loginwindow LoginwindowText 2>/dev/null || true
            echo "✓ Fenêtre de connexion réinitialisée aux paramètres système par défaut"
            ;;
        "help")
            echo "Usage : $0 [action] [options...]"
            echo "Actions :"
            echo "  policy <nom_politique> [entreprise] [support] [dry_run] - Appliquer une politique"
            echo "  message <texte> - Définir un message de connexion personnalisé"
            echo "  power <enable|disable> - Contrôler la visibilité des boutons d'alimentation"
            echo "  display <userlist|dialog> - Définir le mode d'affichage utilisateur"
            echo "  status [detailed] - Afficher la configuration actuelle"
            echo "  reset - Réinitialiser aux paramètres système par défaut"
            echo "  help - Afficher cette aide"
            echo ""
            echo "Politiques : ${!LOGIN_POLICIES[*]}"
            echo "Modèles de Messages : ${!MESSAGE_TEMPLATES[*]}"
            ;;
        *)
            log_action "ERREUR : Action inconnue : $action"
            echo "Utilisez '$0 help' pour les informations d'utilisation"
            exit 1
            ;;
    esac
    
    log_action "=== Gestion de fenêtre de connexion terminée ==="
}

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

Meilleures Pratiques de Sécurité de Fenêtre de Connexion

Configuration de Sécurité d'Entreprise

#!/bin/bash

# Implémenter la sécurité de fenêtre de connexion d'entreprise
implement_corporate_security() {
    echo "=== Implémentation de la Sécurité de Fenêtre de Connexion d'Entreprise ==="
    
    # Masquer l'énumération des utilisateurs
    defaults write /Library/Preferences/com.apple.loginwindow SHOWFULLNAME true
    
    # Désactiver les options d'alimentation pour prévenir les arrêts non autorisés
    defaults write /Library/Preferences/com.apple.loginwindow ShutDownDisabled true
    defaults write /Library/Preferences/com.apple.loginwindow SleepDisabled true
    
    # Permettre le redémarrage pour les mises à jour (optionnel)
    defaults write /Library/Preferences/com.apple.loginwindow RestartDisabled false
    
    # Définir un message de sécurité d'entreprise
    defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "Propriété d'Entreprise - Personnel Autorisé Uniquement"
    
    # Désactiver le compte invité
    defaults write /Library/Preferences/com.apple.loginwindow GuestEnabled false
    
    # Masquer les informations de l'ordinateur
    defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo ""
    
    echo "✓ Configuration de sécurité d'entreprise appliquée"
}

implement_corporate_security

Notes Importantes

  • Privilèges administrateur requis pour les modifications de la fenêtre de connexion
  • Les changements prennent effet après déconnexion ou redémarrage
  • Tester minutieusement sur des appareils individuels avant le déploiement en flotte
  • Sauvegarder les paramètres avant d'apporter des changements
  • Implications de sécurité - Considérer masquer les listes d'utilisateurs dans les environnements haute sécurité
  • Expérience utilisateur - Équilibrer sécurité et utilisabilité
  • Exigences de conformité - Certaines industries nécessitent des configurations spécifiques de fenêtre de connexion
  • Caractères spéciaux - Éviter les points d'exclamation dans les messages personnalisés à cause de l'interprétation du shell

Gestion d'Entreprise de l'Historique de Connexion sur macOS

Surveillez et analysez l'activité de connexion des utilisateurs sur vos appareils MacFleet en utilisant des outils en ligne de commande avancés. Ce tutoriel couvre le suivi de l'historique de connexion, l'analyse des sessions utilisateur, l'audit de sécurité, et la surveillance de conformité de niveau entreprise avec des capacités de rapport complètes.

Comprendre la Gestion de l'Historique de Connexion macOS

macOS fournit plusieurs outils puissants pour traquer l'activité de connexion des utilisateurs :

  • who - Affiche les utilisateurs actuellement connectés et un bref historique de connexion
  • last - Affiche l'historique de connexion détaillé avec les informations de session
  • dscl - Utilitaire en ligne de commande des Services d'Annuaire pour la gestion des utilisateurs
  • w - Informations étendues d'activité utilisateur avec la charge système
  • finger - Informations utilisateur et détails de connexion (si disponible)

Ces outils accèdent aux journaux système et aux bases de données utilisateur pour fournir des capacités de suivi de connexion complètes.

Commandes de Base de l'Historique de Connexion

Historique de Connexion Bref avec who

#!/bin/bash

# Afficher l'historique de connexion bref
get_brief_login_history() {
    echo "=== Historique de Connexion Bref ==="
    who
    echo ""
    
    # Alternative avec horodatages
    echo "=== Sessions Utilisateur Actuelles ==="
    who -u
}

# Exécuter la vérification de connexion de base
get_brief_login_history

Historique de Connexion Détaillé avec last

#!/bin/bash

# Afficher l'historique de connexion détaillé
get_detailed_login_history() {
    echo "=== Historique de Connexion Détaillé ==="
    last
    echo ""
    
    # Afficher les 10 dernières entrées de connexion
    echo "=== 10 Dernières Sessions de Connexion ==="
    last -10
    echo ""
    
    # Afficher l'historique de connexion d'aujourd'hui
    echo "=== Sessions de Connexion d'Aujourd'hui ==="
    last -t "$(date '+%Y%m%d%H%M%S')"
}

# Exécuter la vérification de connexion détaillée
get_detailed_login_history

Vérifier l'Historique de Connexion d'un Utilisateur Spécifique

#!/bin/bash

# Obtenir l'heure de dernière connexion pour un utilisateur spécifique
check_user_login() {
    local username="$1"
    
    if [[ -z "$username" ]]; then
        echo "Usage : check_user_login <nom_utilisateur>"
        return 1
    fi
    
    echo "=== Dernière Connexion pour l'Utilisateur : $username ==="
    last -1 "$username"
    echo ""
    
    # Informations utilisateur supplémentaires
    echo "=== Informations du Compte Utilisateur ==="
    dscl . -read "/Users/$username" RealName 2>/dev/null || echo "Utilisateur non trouvé"
    dscl . -read "/Users/$username" UniqueID 2>/dev/null || echo "UID non disponible"
}

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

Analyse Avancée de l'Historique de Connexion

Analyse Complète des Sessions Utilisateur

#!/bin/bash

# Analyse avancée de l'historique de connexion avec insights de sécurité
analyze_login_patterns() {
    echo "=== Analyse Complète de Connexion ==="
    echo "Généré : $(date)"
    echo "Nom d'hôte : $(hostname)"
    echo "=================================="
    echo ""
    
    # Sessions actives actuelles
    echo "1. SESSIONS UTILISATEUR ACTIVES :"
    echo "--------------------------------"
    who -u | while IFS= read -r line; do
        echo "  $line"
    done
    echo ""
    
    # Activité de connexion récente (dernières 24 heures)
    echo "2. ACTIVITÉ DE CONNEXION RÉCENTE (24 heures) :"
    echo "----------------------------------------------"
    local yesterday
    yesterday=$(date -v-1d '+%Y%m%d%H%M%S' 2>/dev/null || date -d 'yesterday' '+%Y%m%d%H%M%S' 2>/dev/null)
    
    if [[ -n "$yesterday" ]]; then
        last -t "$yesterday" | head -20
    else
        last -20
    fi
    echo ""
    
    # Tentatives de connexion échouées (si disponible dans les journaux)
    echo "3. TENTATIVES DE CONNEXION ÉCHOUÉES :"
    echo "------------------------------------"
    grep "authentication failure" /var/log/system.log 2>/dev/null | tail -10 || echo "Aucun échec récent trouvé"
    echo ""
    
    # Analyse de fréquence de connexion
    echo "4. FRÉQUENCE DE CONNEXION PAR UTILISATEUR :"
    echo "------------------------------------------"
    last | grep -v "wtmp begins" | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
    echo ""
    
    # Analyse des connexions distantes vs locales
    echo "5. ANALYSE SOURCE DE CONNEXION :"
    echo "-------------------------------"
    echo "Connexions console :"
    last | grep -c "console" || echo "0"
    echo "Connexions distantes :"
    last | grep -v "console" | grep -v "wtmp begins" | wc -l | tr -d ' '
}

# Exécuter l'analyse complète
analyze_login_patterns

Découverte des Comptes Utilisateur

#!/bin/bash

# Lister tous les utilisateurs et leur statut de connexion
discover_users() {
    echo "=== Découverte des Comptes Utilisateur ==="
    echo ""
    
    # Tous les utilisateurs des services d'annuaire
    echo "1. TOUS LES UTILISATEURS SYSTÈME :"
    echo "---------------------------------"
    dscl . list /Users | grep -v "^_" | grep -v "^root" | grep -v "^daemon" | grep -v "^nobody"
    echo ""
    
    # Utilisateurs avec UID >= 500 (typiquement utilisateurs réguliers)
    echo "2. COMPTES UTILISATEUR RÉGULIERS :"
    echo "---------------------------------"
    dscl . list /Users UniqueID | awk '$2 >= 500 {print $1, "(UID: " $2 ")"}'
    echo ""
    
    # Utilisateurs avec activité de connexion récente
    echo "3. UTILISATEURS AVEC ACTIVITÉ DE CONNEXION RÉCENTE :"
    echo "---------------------------------------------------"
    last | awk '{print $1}' | sort | uniq | grep -v "wtmp" | grep -v "^$" | head -10
    echo ""
    
    # Répertoires personnels
    echo "4. RÉPERTOIRES PERSONNELS UTILISATEUR :"
    echo "---------------------------------------"
    ls -la /Users/ | grep -v "^total" | grep -v "Shared" | awk '{print $9, $3, $4}' | grep -v "^$"
}

# Exécuter la découverte des utilisateurs
discover_users

Système de Gestion de l'Historique de Connexion d'Entreprise

#!/bin/bash

# Système de Gestion de l'Historique de Connexion d'Entreprise MacFleet
# Surveillance complète de l'activité utilisateur et audit de sécurité

# Configuration
LOG_FILE="/var/log/macfleet_login_history.log"
REPORT_DIR="/var/reports/macfleet/login_history"
CONFIG_FILE="/etc/macfleet/login_monitoring.conf"
ALERT_THRESHOLD_FAILED_LOGINS=5
ALERT_THRESHOLD_UNUSUAL_HOURS=22  # Alerte pour connexions après 22h

# Créer la structure des répertoires
setup_directories() {
    mkdir -p "$(dirname "$LOG_FILE")" "$REPORT_DIR" "$(dirname "$CONFIG_FILE")"
    touch "$LOG_FILE"
}

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

# Générer un rapport de connexion complet
generate_login_report() {
    local report_file="$REPORT_DIR/login_report_$(date +%Y%m%d_%H%M%S).json"
    
    log_action "Génération du rapport d'historique de connexion complet : $report_file"
    
    {
        echo "{"
        echo "  \"report_type\": \"login_history\","
        echo "  \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
        echo "  \"hostname\": \"$(hostname)\","
        echo "  \"system_info\": {"
        echo "    \"macos_version\": \"$(sw_vers -productVersion)\","
        echo "    \"uptime\": \"$(uptime | awk -F'up ' '{print $2}' | awk -F', ' '{print $1}')\","
        echo "    \"current_users\": $(who | wc -l | tr -d ' ')"
        echo "  },"
        
        # Sessions actives
        echo "  \"active_sessions\": ["
        local first_session=true
        who -u | while IFS= read -r line; do
            if [[ "$first_session" == "false" ]]; then
                echo ","
            fi
            first_session=false
            
            local user terminal login_time pid
            user=$(echo "$line" | awk '{print $1}')
            terminal=$(echo "$line" | awk '{print $2}')
            login_time=$(echo "$line" | awk '{print $3, $4}')
            pid=$(echo "$line" | awk '{print $6}')
            
            echo "    {"
            echo "      \"user\": \"$user\","
            echo "      \"terminal\": \"$terminal\","
            echo "      \"login_time\": \"$login_time\","
            echo "      \"pid\": \"$pid\""
            echo -n "    }"
        done
        echo ""
        echo "  ],"
        
        # Historique de connexion récent
        echo "  \"recent_logins\": ["
        local first_login=true
        last -20 | grep -v "wtmp begins" | while IFS= read -r line; do
            if [[ -n "$line" ]]; then
                if [[ "$first_login" == "false" ]]; then
                    echo ","
                fi
                first_login=false
                
                local user terminal source login_date login_time logout_info
                user=$(echo "$line" | awk '{print $1}')
                terminal=$(echo "$line" | awk '{print $2}')
                source=$(echo "$line" | awk '{print $3}')
                login_date=$(echo "$line" | awk '{print $4, $5, $6}')
                login_time=$(echo "$line" | awk '{print $7}')
                logout_info=$(echo "$line" | awk '{print $9, $10}')
                
                echo "    {"
                echo "      \"user\": \"$user\","
                echo "      \"terminal\": \"$terminal\","
                echo "      \"source\": \"$source\","
                echo "      \"login_date\": \"$login_date\","
                echo "      \"login_time\": \"$login_time\","
                echo "      \"logout_info\": \"$logout_info\""
                echo -n "    }"
            fi
        done
        echo ""
        echo "  ],"
        
        # Statistiques utilisateur
        echo "  \"user_statistics\": {"
        local total_users
        total_users=$(dscl . list /Users | grep -v "^_" | wc -l | tr -d ' ')
        echo "    \"total_system_users\": $total_users,"
        
        local regular_users
        regular_users=$(dscl . list /Users UniqueID | awk '$2 >= 500' | wc -l | tr -d ' ')
        echo "    \"regular_users\": $regular_users,"
        
        local active_login_users
        active_login_users=$(last | awk '{print $1}' | sort | uniq | grep -v "wtmp" | grep -v "^$" | wc -l | tr -d ' ')
        echo "    \"users_with_login_history\": $active_login_users"
        echo "  }"
        echo "}"
    } > "$report_file"
    
    log_action "Rapport d'historique de connexion généré avec succès"
    echo "$report_file"
}

# Surveiller l'activité de connexion suspecte
monitor_suspicious_activity() {
    log_action "Démarrage de la surveillance d'activité de connexion suspecte..."
    
    local alerts=()
    
    # Vérifier les heures de connexion inhabituelles (configurable)
    local current_hour
    current_hour=$(date +%H)
    
    if [[ "$current_hour" -ge "$ALERT_THRESHOLD_UNUSUAL_HOURS" ]]; then
        local late_logins
        late_logins=$(who | wc -l | tr -d ' ')
        
        if [[ "$late_logins" -gt 0 ]]; then
            alerts+=("Activité de connexion nocturne détectée : $late_logins sessions actives après $ALERT_THRESHOLD_UNUSUAL_HOURS:00")
        fi
    fi
    
    # Vérifier les tentatives de connexion échouées multiples
    local failed_logins
    failed_logins=$(grep "authentication failure" /var/log/system.log 2>/dev/null | grep "$(date '+%b %d')" | wc -l | tr -d ' ')
    
    if [[ "$failed_logins" -ge "$ALERT_THRESHOLD_FAILED_LOGINS" ]]; then
        alerts+=("Nombre élevé de tentatives de connexion échouées aujourd'hui : $failed_logins échecs")
    fi
    
    # Vérifier les connexions root
    local root_logins
    root_logins=$(last | grep "^root " | head -5 | wc -l | tr -d ' ')
    
    if [[ "$root_logins" -gt 0 ]]; then
        alerts+=("Activité de connexion root récente détectée : $root_logins sessions")
    fi
    
    # Vérifier les connexions simultanées du même utilisateur
    local duplicate_users
    duplicate_users=$(who | awk '{print $1}' | sort | uniq -d)
    
    if [[ -n "$duplicate_users" ]]; then
        alerts+=("Sessions simultanées multiples détectées pour les utilisateurs : $duplicate_users")
    fi
    
    # Rapporter les alertes
    if [[ ${#alerts[@]} -eq 0 ]]; then
        log_action "✅ Aucune activité de connexion suspecte détectée"
        return 0
    else
        log_action "⚠️  Alertes d'activité de connexion suspecte :"
        for alert in "${alerts[@]}"; do
            log_action "  - $alert"
        done
        return 1
    fi
}

# Analyser les modèles de connexion pour insights de sécurité
analyze_security_patterns() {
    log_action "Analyse des modèles de connexion pour insights de sécurité..."
    
    echo "=== Analyse des Modèles de Sécurité ==="
    echo ""
    
    # Fréquence de connexion par jour de la semaine
    echo "1. FRÉQUENCE DE CONNEXION PAR JOUR :"
    echo "-----------------------------------"
    last | grep -v "wtmp begins" | awk '{print $4}' | sort | uniq -c | sort -nr
    echo ""
    
    # Utilisateurs les plus actifs
    echo "2. UTILISATEURS LES PLUS ACTIFS :"
    echo "--------------------------------"
    last | grep -v "wtmp begins" | awk '{print $1}' | sort | uniq -c | sort -nr | head -10
    echo ""
    
    # Analyse des sources de connexion
    echo "3. SOURCES DE CONNEXION :"
    echo "------------------------"
    echo "Connexions console : $(last | grep -c "console")"
    echo "Connexions distantes : $(last | grep -v "console" | grep -v "wtmp begins" | wc -l | tr -d ' ')"
    echo ""
    
    # Analyse de durée de session
    echo "4. MODÈLES DE SESSION :"
    echo "----------------------"
    local avg_sessions
    avg_sessions=$(last | grep -v "wtmp begins" | grep -v "still logged in" | wc -l | tr -d ' ')
    echo "Total sessions terminées : $avg_sessions"
    
    local active_sessions
    active_sessions=$(who | wc -l | tr -d ' ')
    echo "Sessions actuellement actives : $active_sessions"
    echo ""
    
    # Analyse basée sur l'heure
    echo "5. MODÈLES D'HEURE DE CONNEXION :"
    echo "--------------------------------"
    echo "Heures de bureau (9-17) : $(last | awk '{print $7}' | grep -E '^(09|1[0-7]):' | wc -l | tr -d ' ')"
    echo "Après les heures (18-08) : $(last | awk '{print $7}' | grep -E '^(1[8-9]|2[0-3]|0[0-8]):' | wc -l | tr -d ' ')"
}

# Audit d'accès utilisateur
perform_user_audit() {
    local audit_file="$REPORT_DIR/user_audit_$(date +%Y%m%d_%H%M%S).txt"
    
    log_action "Exécution d'un audit d'accès utilisateur complet : $audit_file"
    
    {
        echo "Rapport d'Audit d'Accès Utilisateur MacFleet"
        echo "Généré : $(date)"
        echo "Nom d'hôte : $(hostname)"
        echo "============================================="
        echo ""
        
        echo "APERÇU SYSTÈME :"
        echo "----------------"
        echo "Version macOS : $(sw_vers -productVersion)"
        echo "Build : $(sw_vers -buildVersion)"
        echo "Temps de fonctionnement système : $(uptime | awk -F'up ' '{print $2}' | awk -F', ' '{print $1}')"
        echo "Date/Heure actuelle : $(date)"
        echo ""
        
        echo "RÉSUMÉ COMPTES UTILISATEUR :"
        echo "---------------------------"
        echo "Total utilisateurs système : $(dscl . list /Users | wc -l | tr -d ' ')"
        echo "Utilisateurs réguliers (UID >= 500) : $(dscl . list /Users UniqueID | awk '$2 >= 500' | wc -l | tr -d ' ')"
        echo "Actuellement connectés : $(who | wc -l | tr -d ' ')"
        echo ""
        
        echo "INFORMATIONS UTILISATEUR DÉTAILLÉES :"
        echo "------------------------------------"
        dscl . list /Users UniqueID | awk '$2 >= 500' | while read -r username uid; do
            echo "Utilisateur : $username (UID : $uid)"
            
            # Nom réel
            local real_name
            real_name=$(dscl . -read "/Users/$username" RealName 2>/dev/null | grep "RealName:" | cut -d' ' -f2-)
            echo "  Nom réel : ${real_name:-"Non défini"}"
            
            # Répertoire personnel
            local home_dir
            home_dir=$(dscl . -read "/Users/$username" NFSHomeDirectory 2>/dev/null | grep "NFSHomeDirectory:" | cut -d' ' -f2)
            echo "  Répertoire personnel : ${home_dir:-"Non défini"}"
            
            # Dernière connexion
            local last_login
            last_login=$(last -1 "$username" 2>/dev/null | head -1 | awk '{print $4, $5, $6, $7}')
            echo "  Dernière connexion : ${last_login:-"Jamais"}"
            
            # Statut du compte
            local account_disabled
            account_disabled=$(dscl . -read "/Users/$username" AuthenticationAuthority 2>/dev/null | grep -c "DisabledUser" || echo "0")
            if [[ "$account_disabled" -gt 0 ]]; then
                echo "  Statut : DÉSACTIVÉ"
            else
                echo "  Statut : Actif"
            fi
            
            echo ""
        done
        
        echo "ACTIVITÉ DE CONNEXION RÉCENTE :"
        echo "------------------------------"
        last -50
        
        echo ""
        echo "RECOMMANDATIONS DE SÉCURITÉ :"
        echo "----------------------------"
        
        # Vérifier les utilisateurs sans activité de connexion récente
        local inactive_users
        inactive_users=$(dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}' | while read -r user; do
            if ! last "$user" | grep -q "$(date '+%b')" 2>/dev/null; then
                echo "$user"
            fi
        done)
        
        if [[ -n "$inactive_users" ]]; then
            echo "• Considérer la révision des comptes utilisateur inactifs :"
            echo "$inactive_users" | while read -r user; do
                echo "  - $user"
            done
        else
            echo "• Tous les utilisateurs ont une activité de connexion récente"
        fi
        
        # Vérifier les utilisateurs admin
        local admin_users
        admin_users=$(dscl . -read /Groups/admin GroupMembership 2>/dev/null | cut -d' ' -f2-)
        if [[ -n "$admin_users" ]]; then
            echo "• Réviser régulièrement l'accès utilisateur admin :"
            for admin in $admin_users; do
                echo "  - $admin"
            done
        fi
        
    } > "$audit_file"
    
    log_action "Audit d'accès utilisateur terminé avec succès"
    echo "$audit_file"
}

# Exporter les données de connexion pour analyse externe
export_login_data() {
    local export_format="${1:-json}"  # json, csv, xml
    local export_file="$REPORT_DIR/login_export_$(date +%Y%m%d_%H%M%S).$export_format"
    
    log_action "Exportation des données de connexion au format $export_format : $export_file"
    
    case "$export_format" in
        "csv")
            {
                echo "Utilisateur,Terminal,Source,DateConnexion,HeureConnexion,InfoDeconnexion,Duree"
                last -100 | grep -v "wtmp begins" | while IFS= read -r line; do
                    if [[ -n "$line" ]]; then
                        echo "$line" | awk -F' ' '{
                            user=$1; terminal=$2; source=$3; 
                            login_date=$4" "$5" "$6; login_time=$7; 
                            logout_info=$9" "$10; duration=$8;
                            print user","terminal","source","login_date","login_time","logout_info","duration
                        }'
                    fi
                done
            } > "$export_file"
            ;;
        "json")
            generate_login_report > /dev/null
            cp "$REPORT_DIR"/login_report_*.json "$export_file" 2>/dev/null || echo "{\"error\": \"Aucun rapport récent trouvé\"}" > "$export_file"
            ;;
        "xml")
            {
                echo '<?xml version="1.0" encoding="UTF-8"?>'
                echo '<login_history>'
                echo "  <generated>$(date -u +%Y-%m-%dT%H:%M:%SZ)</generated>"
                echo "  <hostname>$(hostname)</hostname>"
                echo "  <sessions>"
                
                last -50 | grep -v "wtmp begins" | while IFS= read -r line; do
                    if [[ -n "$line" ]]; then
                        local user terminal source login_date login_time
                        user=$(echo "$line" | awk '{print $1}')
                        terminal=$(echo "$line" | awk '{print $2}')
                        source=$(echo "$line" | awk '{print $3}')
                        login_date=$(echo "$line" | awk '{print $4, $5, $6}')
                        login_time=$(echo "$line" | awk '{print $7}')
                        
                        echo "    <session>"
                        echo "      <user>$user</user>"
                        echo "      <terminal>$terminal</terminal>"
                        echo "      <source>$source</source>"
                        echo "      <login_date>$login_date</login_date>"
                        echo "      <login_time>$login_time</login_time>"
                        echo "    </session>"
                    fi
                done
                
                echo "  </sessions>"
                echo '</login_history>'
            } > "$export_file"
            ;;
        *)
            log_action "ERREUR : Format d'exportation non supporté : $export_format"
            return 1
            ;;
    esac
    
    log_action "Données de connexion exportées avec succès"
    echo "$export_file"
}

# Fonction de gestion principale
main() {
    local action="${1:-report}"
    local parameter="$2"
    
    setup_directories
    log_action "Gestion Historique de Connexion MacFleet démarrée avec l'action : $action"
    
    case "$action" in
        "brief")
            who
            ;;
        "detailed")
            last
            ;;
        "user")
            if [[ -n "$parameter" ]]; then
                last -1 "$parameter"
            else
                echo "Usage : $0 user <nom_utilisateur>"
                exit 1
            fi
            ;;
        "users")
            dscl . list /Users | grep -v "^_"
            ;;
        "analyze")
            analyze_security_patterns
            ;;
        "monitor")
            monitor_suspicious_activity
            ;;
        "audit")
            perform_user_audit
            ;;
        "export")
            export_login_data "$parameter"
            ;;
        "report"|*)
            generate_login_report
            ;;
    esac
    
    log_action "Gestion Historique de Connexion MacFleet terminée avec l'action : $action"
}

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

Fonctions de Gestion Rapide

Vérification Simple du Statut de Connexion

#!/bin/bash

# Statut de connexion rapide avec sortie améliorée
quick_login_status() {
    echo "📊 Statut de Connexion MacFleet - $(date)"
    echo "=========================================="
    
    # Utilisateurs actuels
    local current_users
    current_users=$(who | wc -l | tr -d ' ')
    echo "👥 Actuellement connectés : $current_users utilisateurs"
    
    if [[ "$current_users" -gt 0 ]]; then
        echo ""
        echo "Sessions Actives :"
        who | while IFS= read -r line; do
            echo "  🔹 $line"
        done
    fi
    
    echo ""
    echo "📈 Activité Récente :"
    echo "  - Dernières 24 heures : $(last -t "$(date -v-1d '+%Y%m%d%H%M%S' 2>/dev/null || date -d 'yesterday' '+%Y%m%d%H%M%S')" | wc -l | tr -d ' ') connexions"
    echo "  - Cette semaine : $(last | grep "$(date '+%b')" | wc -l | tr -d ' ') connexions"
    
    # Temps de fonctionnement système
    echo "  - Temps de fonctionnement système : $(uptime | awk -F'up ' '{print $2}' | awk -F', ' '{print $1}')"
}

quick_login_status

Résumé de Connexion Utilisateur

#!/bin/bash

# Générer un résumé de connexion utilisateur
user_login_summary() {
    echo "🔍 Résumé de Connexion Utilisateur"
    echo "=================================="
    echo ""
    
    echo "Top 10 Utilisateurs les Plus Actifs :"
    echo "-------------------------------------"
    last | grep -v "wtmp begins" | awk '{print $1}' | sort | uniq -c | sort -nr | head -10 | while read -r count user; do
        echo "  $user : $count connexions"
    done
    
    echo ""
    echo "Activité Utilisateur Récente :"
    echo "-----------------------------"
    dscl . list /Users UniqueID | awk '$2 >= 500 {print $1}' | head -10 | while read -r username; do
        local last_login
        last_login=$(last -1 "$username" 2>/dev/null | head -1 | awk '{print $4, $5, $7}' | tr -s ' ')
        echo "  $username : ${last_login:-"Aucune activité récente"}"
    done
}

user_login_summary

Fonctions de Surveillance de Sécurité

Détection de Connexions Échouées

#!/bin/bash

# Surveiller et rapporter les tentatives de connexion échouées
monitor_failed_logins() {
    echo "🔒 Surveillance des Connexions Échouées"
    echo "======================================="
    echo ""
    
    # Vérifier le journal système pour les échecs d'authentification
    echo "Tentatives de Connexion Échouées Récentes :"
    echo "------------------------------------------"
    
    # Dernières 24 heures de tentatives échouées
    grep "authentication failure" /var/log/system.log 2>/dev/null | grep "$(date '+%b %d')" | while IFS= read -r line; do
        echo "  ⚠️  $line"
    done || echo "  ✅ Aucune tentative de connexion échouée trouvée aujourd'hui"
    
    echo ""
    echo "Résumé des Connexions Échouées :"
    echo "-------------------------------"
    
    # Compter les échecs par utilisateur (si disponible)
    local failure_count
    failure_count=$(grep "authentication failure" /var/log/system.log 2>/dev/null | grep "$(date '+%b %d')" | wc -l | tr -d ' ')
    echo "  Total d'échecs aujourd'hui : $failure_count"
    
    # Recommandations
    if [[ "$failure_count" -gt 5 ]]; then
        echo ""
        echo "🚨 Alerte de Sécurité : Nombre élevé de connexions échouées détecté !"
        echo "  - Réviser les comptes utilisateur pour d'éventuelles attaques par force brute"
        echo "  - Considérer l'implémentation de politiques de verrouillage de compte"
        echo "  - Vérifier les adresses IP suspectes dans les journaux"
    fi
}

monitor_failed_logins

Analyse de Durée de Session

#!/bin/bash

# Analyser les durées de session utilisateur
analyze_session_duration() {
    echo "⏱️  Analyse de Durée de Session"
    echo "==============================="
    echo ""
    
    echo "Statistiques de Session :"
    echo "------------------------"
    
    # Sessions actives
    local active_count
    active_count=$(who | wc -l | tr -d ' ')
    echo "  Sessions actives : $active_count"
    
    # Analyse des sessions terminées
    echo "  Sessions terminées récentes :"
    last | grep -v "still logged in" | grep -v "wtmp begins" | head -10 | while IFS= read -r line; do
        local duration
        duration=$(echo "$line" | awk '{print $10}' | tr -d '()')
        if [[ -n "$duration" ]]; then
            echo "    Durée : $duration"
        fi
    done
    
    echo ""
    echo "Sessions de Longue Durée (Actives) :"
    echo "-----------------------------------"
    who -u | while IFS= read -r line; do
        local login_time pid idle
        login_time=$(echo "$line" | awk '{print $3, $4}')
        pid=$(echo "$line" | awk '{print $6}')
        idle=$(echo "$line" | awk '{print $5}')
        
        if [[ "$idle" != "." ]]; then
            echo "  Session démarrée : $login_time (Inactif : $idle)"
        else
            echo "  Session démarrée : $login_time (Actif)"
        fi
    done
}

analyze_session_duration

Configuration et Conformité

Configuration de Politique de Connexion

# /etc/macfleet/login_monitoring.conf
# Configuration de Surveillance d'Historique de Connexion MacFleet

# Seuils d'alerte
ALERT_THRESHOLD_FAILED_LOGINS=5
ALERT_THRESHOLD_UNUSUAL_HOURS=22
ALERT_THRESHOLD_SIMULTANEOUS_SESSIONS=3

# Paramètres de surveillance
MONITOR_INTERVAL_MINUTES=15
LOG_RETENTION_DAYS=90
REPORT_GENERATION_SCHEDULE="daily"

# Politiques de sécurité
REQUIRE_LOGIN_AUDIT_TRAIL=true
ALERT_ON_ROOT_LOGIN=true
ALERT_ON_AFTER_HOURS_LOGIN=true
MONITOR_REMOTE_LOGINS=true

# Paramètres de conformité
GDPR_COMPLIANCE=true
SOX_COMPLIANCE=false
HIPAA_COMPLIANCE=false
EXPORT_FORMAT="json"  # json, csv, xml

Rapport de Conformité

#!/bin/bash

# Générer des rapports de connexion prêts pour la conformité
generate_compliance_report() {
    local compliance_type="${1:-general}"
    local report_file="$REPORT_DIR/compliance_${compliance_type}_$(date +%Y%m%d).txt"
    
    echo "📋 Génération du rapport de conformité $compliance_type..."
    
    {
        echo "RAPPORT DE CONFORMITÉ HISTORIQUE DE CONNEXION"
        echo "============================================="
        echo "Type de rapport : $compliance_type"
        echo "Généré : $(date)"
        echo "Période : $(date -v-30d '+%Y-%m-%d') à $(date '+%Y-%m-%d')"
        echo "Système : $(hostname)"
        echo ""
        
        case "$compliance_type" in
            "gdpr")
                echo "ENREGISTREMENT DE TRAITEMENT DES DONNÉES RGPD :"
                echo "----------------------------------------------"
                echo "• Données de connexion collectées pour surveillance de sécurité"
                echo "• Rétention des données : 90 jours (configurable)"
                echo "• Contrôles d'accès : Utilisateurs admin uniquement"
                echo "• Sujets des données : Tous les utilisateurs système"
                echo ""
                ;;
            "sox")
                echo "CONFORMITÉ CONTRÔLE D'ACCÈS SOX :"
                echo "--------------------------------"
                echo "• Surveillance d'accès utilisateur : Activé"
                echo "• Suivi d'accès privilégié : Activé"
                echo "• Surveillance de connexions échouées : Activé"
                echo "• Complétude piste d'audit : Vérifiée"
                echo ""
                ;;
            "hipaa")
                echo "EXIGENCES D'AUDIT D'ACCÈS HIPAA :"
                echo "--------------------------------"
                echo "• Journalisation d'authentification utilisateur : Active"
                echo "• Surveillance tentatives d'accès : Activé"
                echo "• Accès minimum nécessaire : En cours de révision"
                echo "• Intégrité journal d'audit : Maintenue"
                echo ""
                ;;
        esac
        
        echo "ACTIVITÉ DE CONNEXION DÉTAILLÉE :"
        echo "--------------------------------"
        last -30
        
        echo ""
        echo "RÉSUMÉ D'ACCÈS UTILISATEUR :"
        echo "---------------------------"
        dscl . list /Users UniqueID | awk '$2 >= 500' | while read -r username uid; do
            local login_count
            login_count=$(last "$username" | grep -v "wtmp begins" | wc -l | tr -d ' ')
            echo "$username (UID : $uid) : $login_count sessions de connexion"
        done
        
    } > "$report_file"
    
    echo "✅ Rapport de conformité généré : $report_file"
}

# Générer différents rapports de conformité
# generate_compliance_report "gdpr"
# generate_compliance_report "sox"
# generate_compliance_report "hipaa"

Notes Techniques Importantes

Détails des Commandes

  • who : Affiche les utilisateurs actuellement connectés avec heures de connexion
  • last : Affiche l'historique de connexion depuis /var/log/wtmp
  • dscl : Ligne de commande Services d'Annuaire pour informations utilisateur
  • w : Version étendue de who avec informations de charge système

Emplacements des Fichiers de Journal

  • /var/log/wtmp : Base de données binaire d'historique de connexion
  • /var/log/system.log : Journal système incluant événements d'authentification
  • /var/log/secure.log : Entrées de journal liées à la sécurité (si activé)

Considérations de Sécurité

  1. Conformité Confidentialité : La surveillance de connexion doit respecter les lois locales de confidentialité
  2. Rétention de Données : Implémenter des politiques de rétention appropriées pour les journaux d'audit
  3. Contrôle d'Accès : Restreindre l'accès aux données d'historique de connexion au personnel autorisé
  4. Surveillance Temps Réel : Considérer l'implémentation d'alertes temps réel pour activité suspecte

Meilleures Pratiques

  1. Audit Régulier : Réviser les modèles de connexion régulièrement pour anomalies
  2. Surveillance Automatisée : Configurer des alertes automatisées pour activité suspecte
  3. Rétention de Données : Maintenir une rétention de journal appropriée pour exigences de conformité
  4. Confidentialité Utilisateur : Équilibrer surveillance de sécurité avec attentes de confidentialité utilisateur
  5. Documentation : Maintenir une documentation claire des procédures de surveillance
  6. Intégration : Considérer l'intégration avec systèmes SIEM pour surveillance centralisée
  7. Impact Performance : Surveiller l'impact sur performance système des activités de journalisation
  8. Stratégie Sauvegarde : Implémenter procédures de sauvegarde pour journaux d'audit critiques

N'oubliez pas de valider tous les scripts sur des appareils de test avant de les déployer sur votre environnement MacFleet, et assurez-vous de la conformité avec les politiques de confidentialité et de sécurité de votre organisation lors de l'implémentation de la surveillance d'historique de connexion.

Gérer les Services de Localisation sur macOS

Contrôlez les Services de Localisation sur vos appareils MacFleet en utilisant des outils en ligne de commande. Ce tutoriel couvre l'activation, la désactivation et la surveillance des services de localisation pour une meilleure gestion de la confidentialité et conformité de sécurité.

Comprendre les Services de Localisation macOS

Les Services de Localisation permettent aux applications et services macOS de collecter des informations basées sur la localisation pour améliorer l'expérience utilisateur. Cependant, l'activation de ces services peut créer des préoccupations potentielles de sécurité et de confidentialité.

Considérations clés :

  • Fonctionnalités améliorées - Les applications comme Plans nécessitent l'accès à la localisation
  • Préoccupations de confidentialité - Potentiel de suivi et de collecte de données
  • Risques de sécurité - Surface d'attaque accrue pour les acteurs malveillants
  • Exigences de conformité - Les politiques d'entreprise peuvent nécessiter des restrictions de localisation

Activer les Services de Localisation

Activation Basique des Services de Localisation

#!/bin/bash

# Activer les Services de Localisation à l'échelle du système
sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool true

echo "Services de Localisation activés avec succès"
echo "⚠️  Redémarrage de l'appareil requis pour que les changements prennent effet"

Activer avec Redémarrage Automatique

#!/bin/bash

# Activer les Services de Localisation et programmer un redémarrage
sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool true

echo "Configuration des Services de Localisation mise à jour"
echo "Programmation du redémarrage système dans 60 secondes..."

# Donner aux utilisateurs le temps de sauvegarder leur travail
sleep 60
sudo reboot

Vérifier le Succès de l'Activation

#!/bin/bash

# Activer les Services de Localisation avec vérification
echo "Activation des Services de Localisation..."
sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool true

# Vérifier si le paramètre a été appliqué
if sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled 2>/dev/null; then
    echo "✅ Configuration des Services de Localisation mise à jour avec succès"
    echo "🔄 Redémarrage requis pour appliquer les changements"
else
    echo "❌ Échec de la mise à jour de la configuration des Services de Localisation"
    exit 1
fi

Désactiver les Services de Localisation

Désactivation Basique des Services de Localisation

#!/bin/bash

# Désactiver les Services de Localisation à l'échelle du système
sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool false

echo "Services de Localisation désactivés avec succès"
echo "⚠️  Redémarrage de l'appareil requis pour que les changements prennent effet"

Désactiver avec Notification de Confidentialité

#!/bin/bash

# Désactiver les Services de Localisation avec notification utilisateur
echo "🔒 Mise en place des mesures de protection de la confidentialité..."
echo "Désactivation des Services de Localisation pour une sécurité renforcée"

sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool false

echo "✅ Les Services de Localisation ont été désactivés"
echo "🔄 Redémarrage système requis pour compléter le processus"
echo "📱 Les applications n'auront plus accès aux données de localisation"

Désactivation Sécurisée d'Entreprise

#!/bin/bash

# Désactivation des services de localisation de niveau entreprise avec journalisation
LOG_FILE="/var/log/macfleet_location_services.log"

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

log_action "=== Désactivation Sécurisée des Services de Localisation Initiée ==="

# Vérifier le statut actuel
CURRENT_STATUS=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" LocationServicesEnabled 2>/dev/null)

if [[ "$CURRENT_STATUS" == "1" ]]; then
    log_action "Services de Localisation actuellement activés - procédure de désactivation"
    
    # Désactiver les services de localisation
    sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool false
    
    log_action "Services de Localisation désactivés pour conformité de sécurité"
    log_action "Redémarrage système requis pour compléter le durcissement de sécurité"
    
    echo "🔒 Politique de sécurité appliquée : Services de Localisation désactivés"
    echo "📋 Action journalisée dans : $LOG_FILE"
else
    log_action "Services de Localisation déjà désactivés - aucune action requise"
    echo "✅ Services de Localisation déjà sécurisés"
fi

Vérifier le Statut des Services de Localisation

Vérification Basique du Statut

#!/bin/bash

# Vérifier le statut actuel des Services de Localisation
sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd"

echo "Statut des Services de Localisation récupéré"

Rapport de Statut Détaillé

#!/bin/bash

# Vérification complète du statut des Services de Localisation
echo "=== Rapport de Statut des Services de Localisation ==="
echo "Appareil : $(hostname)"
echo "Date : $(date)"
echo "========================================"

# Vérifier si le daemon locationd fonctionne
if pgrep -x "locationd" > /dev/null; then
    echo "📍 Daemon de localisation : En cours d'exécution"
else
    echo "❌ Daemon de localisation : Non en cours d'exécution"
fi

# Obtenir la configuration actuelle
STATUS_OUTPUT=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" 2>&1)

if echo "$STATUS_OUTPUT" | grep -q "LocationServicesEnabled = 1"; then
    echo "🟢 Services de Localisation : ACTIVÉS"
    echo "📱 Les applications peuvent accéder aux données de localisation"
elif echo "$STATUS_OUTPUT" | grep -q "LocationServicesEnabled = 0"; then
    echo "🔴 Services de Localisation : DÉSACTIVÉS"
    echo "🔒 Accès à la localisation bloqué pour toutes les applications"
else
    echo "⚠️  Services de Localisation : Statut incertain"
    echo "Sortie brute : $STATUS_OUTPUT"
fi

echo "========================================"

Surveillance de Statut à l'Échelle de la Flotte

#!/bin/bash

# Script de Surveillance des Services de Localisation MacFleet
LOG_FILE="/var/log/macfleet_location_monitoring.log"
REPORT_FILE="/tmp/location_services_report.txt"

# Créer un rapport de statut
generate_report() {
    {
        echo "Rapport des Services de Localisation MacFleet"
        echo "Généré : $(date)"
        echo "Appareil : $(hostname)"
        echo "Utilisateur : $(whoami)"
        echo "================================"
        echo ""
        
        # Informations système
        echo "Informations Système :"
        echo "Version OS : $(sw_vers -productVersion)"
        echo "Build : $(sw_vers -buildVersion)"
        echo ""
        
        # Statut du daemon de localisation
        echo "Statut du Daemon de Localisation :"
        if pgrep -x "locationd" > /dev/null; then
            echo "Statut : En cours d'exécution (PID : $(pgrep -x "locationd"))"
        else
            echo "Statut : Non en cours d'exécution"
        fi
        echo ""
        
        # Statut de configuration
        echo "Configuration des Services de Localisation :"
        local status_output
        status_output=$(sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd" 2>&1)
        
        if echo "$status_output" | grep -q "LocationServicesEnabled = 1"; then
            echo "Statut : ACTIVÉ"
            echo "Niveau de Confidentialité : Standard"
        elif echo "$status_output" | grep -q "LocationServicesEnabled = 0"; then
            echo "Statut : DÉSACTIVÉ"
            echo "Niveau de Confidentialité : Élevé"
        else
            echo "Statut : Inconnu"
            echo "Configuration Brute :"
            echo "$status_output"
        fi
        
        echo ""
        echo "Rapport terminé à : $(date)"
        
    } > "$REPORT_FILE"
    
    echo "📊 Rapport généré : $REPORT_FILE"
}

# Journaliser l'action de surveillance
echo "$(date '+%Y-%m-%d %H:%M:%S') - Surveillance des Services de Localisation initiée" >> "$LOG_FILE"

# Générer le rapport
generate_report

# Afficher le résumé
echo "=== Résumé des Services de Localisation MacFleet ==="
cat "$REPORT_FILE"

Gestion Avancée de la Localisation

Contrôle Conditionnel de la Localisation

#!/bin/bash

# Gestion intelligente des services de localisation basée sur l'environnement
NETWORK_SSID=$(networksetup -getairportnetwork en0 | cut -d' ' -f4-)
LOCATION_POLICY=""

# Définir les politiques de localisation basées sur le réseau
case "$NETWORK_SSID" in
    "Corporate_WiFi"|"Company_Network")
        LOCATION_POLICY="disable"
        echo "🏢 Réseau d'entreprise détecté - application de la politique de sécurité"
        ;;
    "Home_Network"|"Personal_WiFi")
        LOCATION_POLICY="enable"
        echo "🏠 Réseau personnel détecté - autorisation des services de localisation"
        ;;
    *)
        LOCATION_POLICY="disable"
        echo "🔒 Réseau inconnu - application de la politique restrictive"
        ;;
esac

# Appliquer la politique
if [[ "$LOCATION_POLICY" == "disable" ]]; then
    sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool false
    echo "🔴 Services de Localisation désactivés pour la sécurité"
else
    sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool true
    echo "🟢 Services de Localisation activés"
fi

echo "⚠️  Redémarrage requis pour que les changements prennent effet"

Sauvegarde et Restauration des Services de Localisation

#!/bin/bash

# Sauvegarde et restauration de la configuration des services de localisation
BACKUP_DIR="/var/backups/macfleet"
BACKUP_FILE="$BACKUP_DIR/location_services_$(date +%Y%m%d_%H%M%S).plist"

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

backup_settings() {
    echo "📦 Sauvegarde de la configuration des Services de Localisation..."
    
    if sudo cp "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.plist" "$BACKUP_FILE" 2>/dev/null; then
        echo "✅ Sauvegarde enregistrée dans : $BACKUP_FILE"
    else
        echo "❌ Échec de la sauvegarde - le fichier de configuration pourrait ne pas exister"
        return 1
    fi
}

restore_settings() {
    local restore_file="$1"
    
    if [[ -z "$restore_file" ]]; then
        echo "Usage : restore_settings <fichier_sauvegarde>"
        return 1
    fi
    
    if [[ ! -f "$restore_file" ]]; then
        echo "❌ Fichier de sauvegarde non trouvé : $restore_file"
        return 1
    fi
    
    echo "🔄 Restauration de la configuration des Services de Localisation..."
    
    if sudo cp "$restore_file" "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.plist"; then
        echo "✅ Configuration restaurée avec succès"
        echo "🔄 Redémarrage requis pour appliquer les changements"
    else
        echo "❌ Échec de la restauration"
        return 1
    fi
}

# Exécuter la sauvegarde
backup_settings

Considérations de Sécurité

Durcissement de Sécurité d'Entreprise

#!/bin/bash

# Durcissement complet de sécurité des services de localisation
echo "🔒 Durcissement de Sécurité MacFleet : Services de Localisation"
echo "=============================================================="

# 1. Désactiver les services de localisation
echo "Étape 1 : Désactivation des Services de Localisation..."
sudo /usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -bool false

# 2. Vérifier la configuration du daemon
echo "Étape 2 : Vérification de la configuration du daemon..."
if pgrep -x "locationd" > /dev/null; then
    echo "⚠️  Le daemon de localisation fonctionne encore (s'arrêtera après redémarrage)"
else
    echo "✅ Le daemon de localisation ne fonctionne pas"
fi

# 3. Définir les permissions de fichier
echo "Étape 3 : Sécurisation des fichiers de configuration..."
sudo chmod 600 /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.plist 2>/dev/null
sudo chown _locationd:_locationd /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.plist 2>/dev/null

# 4. Créer un rapport de sécurité
SECURITY_REPORT="/var/log/macfleet_location_security.log"
{
    echo "Rapport de Durcissement de Sécurité des Services de Localisation MacFleet"
    echo "Date : $(date)"
    echo "Appareil : $(hostname)"
    echo "Action : Services de Localisation Désactivés"
    echo "Conformité : Protection de Confidentialité Renforcée"
    echo "Prochaines Étapes : Redémarrage système requis"
} | sudo tee -a "$SECURITY_REPORT"

echo "✅ Durcissement de sécurité terminé"
echo "📋 Rapport enregistré dans : $SECURITY_REPORT"
echo "🔄 Redémarrage système requis pour compléter le durcissement"

Notes Importantes

  • Redémarrage système requis - Les changements prennent effet seulement après redémarrage
  • Privilèges administrateur - Toutes les commandes nécessitent un accès sudo
  • Paramètres spécifiques aux applications - Ces scripts contrôlent seulement les paramètres à l'échelle du système
  • Compatibilité version macOS - Scripts testés sur macOS 10.14+
  • Conformité de confidentialité - Considérer les exigences légales dans votre juridiction
  • Notification utilisateur - Informer les utilisateurs des changements de politique de localisation

Dépannage

Problèmes Courants

Permission Refusée :

# Assurer le contexte approprié de l'utilisateur daemon
sudo -u "_locationd" defaults -currentHost read "/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd"

Configuration Non Appliquée :

# Forcer le redémarrage du daemon de localisation
sudo launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist
sudo launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

Problèmes de Vérification :

# Vérifier l'intégrité du système
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate

N'oubliez pas de tester ces scripts sur des appareils individuels avant de les déployer dans votre environnement MacFleet.