User Account Deletion and Lifecycle Management on macOS
Manage user account lifecycle and secure deletion processes across your MacFleet devices with comprehensive user management, data retention policies, and enterprise offboarding procedures. This tutorial covers secure user deletion, data archival, and compliance-driven user lifecycle management.
Understanding User Account Deletion
User account deletion on macOS involves multiple components and security considerations:
- Account Removal - Deleting the user account from system databases
- Data Management - Handling user home directories and associated files
- Security Tokens - Managing Secure Token requirements for deletion
- Enterprise Compliance - Meeting data retention and privacy requirements
Enterprise Considerations
Proper user account deletion requires enterprise planning:
- Data Retention Policies - Compliance with legal and regulatory requirements
- Security Protocols - Ensuring complete data removal and access revocation
- Audit Requirements - Maintaining deletion logs for compliance tracking
- Recovery Procedures - Backup and recovery capabilities before deletion
- Process Automation - Streamlined offboarding for departing employees
Basic User Account Deletion
Prerequisites and Security Requirements
#!/bin/bash
# Check prerequisites for user deletion
check_deletion_prerequisites() {
echo "=== User Deletion Prerequisites Check ==="
# Check if running with administrator privileges
if [[ $EUID -ne 0 ]]; then
echo "⚠️ Warning: This script requires administrator privileges"
echo "Run with: sudo $0"
else
echo "✓ Administrator privileges confirmed"
fi
# Check Service app full disk access
echo ""
echo "--- Full Disk Access Check ---"
local tcc_db="/Library/Application Support/com.apple.TCC/TCC.db"
if [[ -r "$tcc_db" ]]; then
echo "✓ TCC database accessible - Full disk access likely granted"
else
echo "⚠️ Warning: TCC database not accessible"
echo "Ensure Service app has Full Disk Access in System Preferences"
fi
# Check available Secure Token holders
echo ""
echo "--- Secure Token Analysis ---"
local secure_token_users=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
echo "Secure Token holders found: $secure_token_users"
if [[ $secure_token_users -lt 2 ]]; then
echo "⚠️ Warning: Less than 2 Secure Token holders detected"
echo "Cannot delete the only Secure Token holder"
echo "Add another admin user with Secure Token before deletion"
else
echo "✓ Multiple Secure Token holders available"
fi
}
# Usage
check_deletion_prerequisites
Safe User Account Deletion
#!/bin/bash
# Safely delete user account with validation
delete_user_account() {
local username="$1"
local method="${2:-sysadminctl}" # sysadminctl or dscl
local backup_data="${3:-true}"
if [[ -z "$username" ]]; then
echo "Usage: delete_user_account <username> [method] [backup_data]"
echo "Methods: sysadminctl (default), dscl"
echo "Backup data: true (default), false"
return 1
fi
echo "=== Safe User Account Deletion ==="
echo "Target user: $username"
echo "Deletion method: $method"
echo "Backup data: $backup_data"
echo ""
# Validate user exists
if ! id "$username" >/dev/null 2>&1; then
echo "Error: User '$username' does not exist"
return 1
fi
# Check if user is currently logged in
local logged_in_users=$(who | awk '{print $1}' | sort -u)
if echo "$logged_in_users" | grep -q "^$username$"; then
echo "⚠️ Warning: User '$username' is currently logged in"
echo "Force logout or wait for user to log out before deletion"
return 1
fi
# Check Secure Token status
local token_status=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep "Enabled")
if [[ -n "$token_status" ]]; then
echo "User '$username' has Secure Token"
# Count total Secure Token holders
local total_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep "Enabled" | wc -l | tr -d ' ')
if [[ $total_tokens -eq 1 ]]; then
echo "Error: Cannot delete the only Secure Token holder"
echo "Add another admin user with Secure Token first"
return 1
fi
fi
# Backup user data if requested
if [[ "$backup_data" == "true" ]]; then
echo "Creating backup of user data..."
backup_user_data "$username"
fi
# Perform deletion based on method
echo ""
echo "--- Deleting User Account ---"
case "$method" in
"sysadminctl")
delete_user_sysadminctl "$username"
;;
"dscl")
delete_user_dscl "$username"
;;
*)
echo "Error: Unknown deletion method: $method"
return 1
;;
esac
}
# Delete user using sysadminctl (macOS 10.13+)
delete_user_sysadminctl() {
local username="$1"
echo "Using sysadminctl to delete user: $username"
if sysadminctl -deleteUser "$username" 2>/dev/null; then
echo "✓ User account '$username' deleted successfully using sysadminctl"
return 0
else
echo "✗ Failed to delete user '$username' using sysadminctl"
return 1
fi
}
# Delete user using dscl (legacy method)
delete_user_dscl() {
local username="$1"
echo "Using dscl to delete user: $username"
if dscl . delete "/Users/$username" 2>/dev/null; then
echo "✓ User account '$username' deleted successfully using dscl"
return 0
else
echo "✗ Failed to delete user '$username' using dscl"
return 1
fi
}
# Usage example (commented out for safety)
# delete_user_account "departing_employee" "sysadminctl" "true"
User Data and Directory Management
#!/bin/bash
# Comprehensive user data management
manage_user_data() {
local username="$1"
local action="${2:-archive}" # archive, delete, preserve
local backup_location="${3:-/var/backups/user_data}"
if [[ -z "$username" ]]; then
echo "Usage: manage_user_data <username> [action] [backup_location]"
echo "Actions: archive (default), delete, preserve"
return 1
fi
echo "=== User Data Management ==="
echo "Username: $username"
echo "Action: $action"
echo "Backup location: $backup_location"
echo ""
local user_home="/Users/$username"
# Check if user home directory exists
if [[ ! -d "$user_home" ]]; then
echo "User home directory not found: $user_home"
return 1
fi
# Get directory size for reporting
local dir_size=$(du -sh "$user_home" 2>/dev/null | awk '{print $1}')
echo "User home directory size: $dir_size"
case "$action" in
"archive")
archive_user_data "$username" "$backup_location"
;;
"delete")
delete_user_data "$username"
;;
"preserve")
preserve_user_data "$username"
;;
*)
echo "Error: Unknown action: $action"
return 1
;;
esac
}
# Archive user data before deletion
archive_user_data() {
local username="$1"
local backup_location="$2"
echo "--- Archiving User Data ---"
# Create backup directory if it doesn't exist
mkdir -p "$backup_location"
local timestamp=$(date +%Y%m%d_%H%M%S)
local archive_name="${username}_backup_${timestamp}.tar.gz"
local archive_path="$backup_location/$archive_name"
echo "Creating archive: $archive_path"
# Create compressed archive of user home directory
if tar -czf "$archive_path" -C "/Users" "$username" 2>/dev/null; then
echo "✓ User data archived successfully"
# Create metadata file
local metadata_file="$backup_location/${username}_metadata_${timestamp}.json"
cat > "$metadata_file" << EOF
{
"backup_metadata": {
"username": "$username",
"backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"archive_file": "$archive_name",
"archive_size": "$(du -sh "$archive_path" | awk '{print $1}')",
"original_path": "/Users/$username",
"backup_location": "$backup_location",
"hostname": "$(hostname)",
"created_by": "$(whoami)"
}
}
EOF
echo "✓ Metadata file created: $metadata_file"
echo "Archive details:"
echo " File: $archive_path"
echo " Size: $(du -sh "$archive_path" | awk '{print $1}')"
return 0
else
echo "✗ Failed to create archive"
return 1
fi
}
# Delete user data and directories
delete_user_data() {
local username="$1"
local user_home="/Users/$username"
echo "--- Deleting User Data ---"
echo "⚠️ WARNING: This will permanently delete all user data"
echo "Target directory: $user_home"
# Safety check - don't delete system directories
case "$username" in
"root"|"admin"|"administrator"|"Guest"|"Shared")
echo "Error: Cannot delete system user data: $username"
return 1
;;
esac
if [[ "$user_home" == "/Users/"* && ${#username} -gt 2 ]]; then
echo "Deleting user home directory..."
if rm -rf "$user_home" 2>/dev/null; then
echo "✓ User data deleted successfully: $user_home"
return 0
else
echo "✗ Failed to delete user data: $user_home"
return 1
fi
else
echo "Error: Invalid user home path: $user_home"
return 1
fi
}
# Preserve user data with ownership change
preserve_user_data() {
local username="$1"
local user_home="/Users/$username"
local preserved_name="${username}_preserved_$(date +%Y%m%d)"
local preserved_path="/Users/$preserved_name"
echo "--- Preserving User Data ---"
echo "Renaming user directory for preservation"
echo "From: $user_home"
echo "To: $preserved_path"
if mv "$user_home" "$preserved_path" 2>/dev/null; then
# Change ownership to admin user
chown -R root:admin "$preserved_path" 2>/dev/null
chmod -R 755 "$preserved_path" 2>/dev/null
echo "✓ User data preserved at: $preserved_path"
echo "✓ Ownership changed to root:admin"
return 0
else
echo "✗ Failed to preserve user data"
return 1
fi
}
# Usage example
# manage_user_data "departing_employee" "archive" "/var/backups/user_data"
Enterprise User Lifecycle Management
#!/bin/bash
# MacFleet User Account Deletion and Lifecycle Management Tool
# Comprehensive user offboarding, data management, and compliance
# Configuration
SCRIPT_VERSION="1.0.0"
LOG_FILE="/var/log/macfleet_user_lifecycle.log"
REPORT_DIR="/etc/macfleet/reports/users"
CONFIG_DIR="/etc/macfleet/user_management"
POLICY_DIR="/etc/macfleet/policies/users"
BACKUP_DIR="/var/backups/macfleet/users"
COMPLIANCE_DIR="/etc/macfleet/compliance/users"
# Create directories if they don't exist
mkdir -p "$REPORT_DIR" "$CONFIG_DIR" "$POLICY_DIR" "$BACKUP_DIR" "$COMPLIANCE_DIR"
# User lifecycle policies
declare -A LIFECYCLE_POLICIES=(
["immediate_deletion"]="delete_account,delete_data,no_backup,audit_log"
["secure_archival"]="backup_data,delete_account,delete_data,compliance_report"
["data_preservation"]="backup_data,preserve_home,delete_account,extended_audit"
["legal_hold"]="preserve_all,disable_account,legal_compliance,no_deletion"
["healthcare_hipaa"]="encrypted_backup,secure_deletion,hipaa_compliance,audit_trail"
["financial_compliance"]="full_backup,sox_compliance,retention_policy,secure_deletion"
["education_ferpa"]="student_data_protection,ferpa_compliance,selective_backup,audit_log"
["government_classified"]="classified_data_handling,security_clearance_check,secure_deletion,audit_trail"
["contractor_offboarding"]="project_data_separation,limited_backup,quick_deletion,access_revocation"
["temporary_disable"]="disable_only,preserve_all,no_deletion,reactivation_ready"
)
# Data retention periods (in days)
declare -A RETENTION_PERIODS=(
["immediate"]="0"
["short_term"]="30"
["medium_term"]="90"
["long_term"]="365"
["legal_hold"]="indefinite"
["compliance_minimum"]="2555" # 7 years
)
# Compliance frameworks
declare -A COMPLIANCE_FRAMEWORKS=(
["hipaa"]="healthcare_data_protection,encrypted_storage,audit_logs,secure_deletion"
["sox"]="financial_records_retention,change_management,access_controls,audit_trail"
["ferpa"]="student_privacy,educational_records,consent_management,access_restrictions"
["gdpr"]="data_minimization,consent_withdrawal,right_to_erasure,data_portability"
["pci_dss"]="payment_data_protection,secure_deletion,access_monitoring,compliance_reporting"
)
# Logging function
log_action() {
local message="$1"
local severity="${2:-INFO}"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$severity] $message" | tee -a "$LOG_FILE"
}
# Enhanced user account deletion with enterprise features
enterprise_user_deletion() {
local username="$1"
local policy="${2:-secure_archival}"
local compliance_framework="${3:-}"
local retention_period="${4:-medium_term}"
local authorized_by="${5:-$(whoami)}"
log_action "Starting enterprise user deletion process" "INFO"
log_action "Username: $username, Policy: $policy, Authorized by: $authorized_by" "INFO"
echo "=== Enterprise User Deletion Process ==="
echo "Username: $username"
echo "Policy: $policy"
echo "Compliance Framework: $compliance_framework"
echo "Retention Period: $retention_period"
echo "Authorized By: $authorized_by"
echo "Process ID: $(uuidgen)"
echo ""
# Validate user exists
if ! id "$username" >/dev/null 2>&1; then
log_action "ERROR: User '$username' does not exist" "ERROR"
return 1
fi
# Pre-deletion validation
if ! pre_deletion_validation "$username"; then
log_action "ERROR: Pre-deletion validation failed for user: $username" "ERROR"
return 1
fi
# Apply policy-based deletion process
apply_deletion_policy "$username" "$policy" "$compliance_framework" "$retention_period" "$authorized_by"
# Generate compliance report
generate_deletion_compliance_report "$username" "$policy" "$compliance_framework" "$authorized_by"
log_action "user deletion process completed for user: $username" "INFO"
}
# Pre-deletion validation and safety checks
pre_deletion_validation() {
local username="$1"
echo "--- Pre-Deletion Validation ---"
# Check if user is system user
local user_id=$(id -u "$username" 2>/dev/null)
if [[ $user_id -lt 500 ]]; then
echo "✗ Cannot delete system user (UID < 500): $username"
return 1
fi
# Check if user is currently logged in
if who | grep -q "^$username "; then
echo "✗ User is currently logged in: $username"
log_action "Deletion blocked: User $username is currently logged in" "WARNING"
return 1
fi
# Check Secure Token requirements
local has_secure_token=$(sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep -c "Enabled")
if [[ $has_secure_token -eq 1 ]]; then
local total_secure_tokens=$(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
if [[ $total_secure_tokens -eq 1 ]]; then
echo "✗ Cannot delete the only Secure Token holder: $username"
log_action "Deletion blocked: $username is the only Secure Token holder" "ERROR"
return 1
fi
fi
# Check for active processes owned by user
local user_processes=$(ps aux | awk -v user="$username" '$1 == user {print $2}' | wc -l | tr -d ' ')
if [[ $user_processes -gt 0 ]]; then
echo "⚠️ Warning: User has $user_processes active processes"
echo "Terminating user processes..."
pkill -u "$username" 2>/dev/null
sleep 2
fi
# Check home directory size for backup planning
local home_dir="/Users/$username"
if [[ -d "$home_dir" ]]; then
local dir_size=$(du -sm "$home_dir" 2>/dev/null | awk '{print $1}')
echo "✓ Home directory size: ${dir_size}MB"
# Check available disk space for backup
local available_space=$(df -m "$BACKUP_DIR" | tail -1 | awk '{print $4}')
if [[ $dir_size -gt $available_space ]]; then
echo "⚠️ Warning: Insufficient space for backup"
echo "Required: ${dir_size}MB, Available: ${available_space}MB"
fi
fi
echo "✓ Pre-deletion validation completed"
return 0
}
# Apply deletion policy
apply_deletion_policy() {
local username="$1"
local policy="$2"
local compliance_framework="$3"
local retention_period="$4"
local authorized_by="$5"
echo "--- Applying Deletion Policy: $policy ---"
# Get policy actions
local policy_actions="${LIFECYCLE_POLICIES[$policy]}"
if [[ -z "$policy_actions" ]]; then
log_action "ERROR: Unknown deletion policy: $policy" "ERROR"
return 1
fi
echo "Policy actions: $policy_actions"
# Execute policy actions
IFS=',' read -ra ACTIONS <<< "$policy_actions"
for action in "${ACTIONS[@]}"; do
case "$action" in
"backup_data")
echo "Executing: Backup user data"
backup_user_data_enterprise "$username" "$compliance_framework"
;;
"delete_account")
echo "Executing: Delete user account"
delete_user_account_enterprise "$username"
;;
"delete_data")
echo "Executing: Delete user data"
delete_user_data_secure "$username"
;;
"preserve_home")
echo "Executing: Preserve home directory"
preserve_user_data "$username"
;;
"disable_account")
echo "Executing: Disable user account"
disable_user_account "$username"
;;
"audit_log")
echo "Executing: Create audit log"
create_audit_log "$username" "$policy" "$authorized_by"
;;
"compliance_report")
echo "Executing: Generate compliance report"
# Will be handled separately
;;
*)
echo "Unknown action: $action"
;;
esac
done
}
# Enterprise backup with encryption and compliance
backup_user_data_enterprise() {
local username="$1"
local compliance_framework="$2"
echo "--- Enterprise Data Backup ---"
local timestamp=$(date +%Y%m%d_%H%M%S)
local backup_name="${username}_enterprise_backup_${timestamp}"
local backup_path="$BACKUP_DIR/$backup_name"
# Create backup with metadata
mkdir -p "$backup_path"
# Copy user data
local user_home="/Users/$username"
if [[ -d "$user_home" ]]; then
echo "Backing up user home directory..."
tar -czf "$backup_path/home_directory.tar.gz" -C "/Users" "$username" 2>/dev/null
fi
# Backup user account information
echo "Backing up account metadata..."
dscl . read "/Users/$username" > "$backup_path/account_metadata.txt" 2>/dev/null
# Create backup manifest
cat > "$backup_path/backup_manifest.json" << EOF
{
"backup_manifest": {
"username": "$username",
"backup_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"backup_type": "enterprise_offboarding",
"compliance_framework": "$compliance_framework",
"backup_location": "$backup_path",
"files_included": [
"home_directory.tar.gz",
"account_metadata.txt",
"backup_manifest.json"
],
"backup_size": "$(du -sh "$backup_path" | awk '{print $1}')",
"hostname": "$(hostname)",
"authorized_by": "$(whoami)",
"backup_integrity": "$(find "$backup_path" -type f -exec md5 {} \; | md5)"
}
}
EOF
# Apply compliance-specific protections
if [[ -n "$compliance_framework" ]]; then
apply_compliance_protections "$backup_path" "$compliance_framework"
fi
echo "✓ Enterprise backup completed: $backup_path"
log_action "backup created for user $username at $backup_path" "INFO"
}
# Secure deletion with compliance requirements
delete_user_data_secure() {
local username="$1"
local user_home="/Users/$username"
echo "--- Secure Data Deletion ---"
if [[ -d "$user_home" ]]; then
echo "Performing secure deletion of user data..."
# Multiple-pass secure deletion (DoD 5220.22-M standard)
if command -v gshred >/dev/null 2>&1; then
echo "Using gshred for secure deletion..."
find "$user_home" -type f -exec gshred -vfz -n 3 {} \; 2>/dev/null
elif command -v shred >/dev/null 2>&1; then
echo "Using shred for secure deletion..."
find "$user_home" -type f -exec shred -vfz -n 3 {} \; 2>/dev/null
else
echo "Secure deletion tools not available, using standard deletion..."
fi
# Remove directory structure
rm -rf "$user_home" 2>/dev/null
echo "✓ Secure deletion completed"
log_action "Secure deletion completed for user data: $user_home" "INFO"
else
echo "No user home directory found: $user_home"
fi
}
# Disable user account instead of deletion
disable_user_account() {
local username="$1"
echo "--- Disabling User Account ---"
# Disable account using dscl
if dscl . create "/Users/$username" AuthenticationAuthority ";DisabledUser;" 2>/dev/null; then
echo "✓ User account disabled: $username"
log_action "User account disabled: $username" "INFO"
else
echo "✗ Failed to disable user account: $username"
log_action "Failed to disable user account: $username" "ERROR"
fi
# Set account shell to /usr/bin/false
dscl . create "/Users/$username" UserShell "/usr/bin/false" 2>/dev/null
# Lock home directory
local user_home="/Users/$username"
if [[ -d "$user_home" ]]; then
chmod 000 "$user_home" 2>/dev/null
echo "✓ Home directory access revoked"
fi
}
# Generate comprehensive compliance report
generate_deletion_compliance_report() {
local username="$1"
local policy="$2"
local compliance_framework="$3"
local authorized_by="$4"
local report_file="$REPORT_DIR/user_deletion_report_${username}_$(date +%Y%m%d_%H%M%S).json"
cat > "$report_file" << EOF
{
"user_deletion_compliance_report": {
"report_metadata": {
"report_id": "$(uuidgen)",
"generated_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"report_type": "user_account_deletion",
"compliance_framework": "$compliance_framework",
"hostname": "$(hostname)",
"script_version": "$SCRIPT_VERSION"
},
"user_information": {
"username": "$username",
"deletion_policy": "$policy",
"authorized_by": "$authorized_by",
"deletion_timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
},
"compliance_details": {
"framework": "$compliance_framework",
"data_retention_requirements": "$(echo "${RETENTION_PERIODS[medium_term]}" | sed 's/indefinite/Legal hold - indefinite retention/')",
"secure_deletion_method": "DoD 5220.22-M standard",
"backup_location": "$BACKUP_DIR",
"audit_trail": "$LOG_FILE"
},
"system_information": {
"os_version": "$(sw_vers -productVersion)",
"hardware_model": "$(system_profiler SPHardwareDataType | grep 'Model Identifier' | awk '{print $3}')",
"secure_token_holders": $(sysadminctl -secureTokenStatus 2>/dev/null | grep -c "Enabled")
}
}
}
EOF
echo "Compliance report generated: $report_file"
log_action "Compliance report generated: $report_file" "INFO"
}
# Fleet user management operations
manage_fleet_users() {
local operation="$1"
local user_list="$2"
local policy="${3:-secure_archival}"
local compliance_framework="${4:-}"
echo "=== Fleet User Management ==="
echo "Operation: $operation"
echo "Policy: $policy"
echo "Compliance Framework: $compliance_framework"
echo ""
case "$operation" in
"bulk_delete")
echo "Processing bulk user deletion..."
IFS=',' read -ra USERS <<< "$user_list"
for username in "${USERS[@]}"; do
echo "Processing user: $username"
enterprise_user_deletion "$username" "$policy" "$compliance_framework"
echo ""
done
;;
"audit_all")
echo "Auditing all user accounts..."
audit_all_users
;;
"compliance_check")
echo "Running compliance check..."
compliance_check_users "$compliance_framework"
;;
*)
echo "Unknown operation: $operation"
return 1
;;
esac
}
# Main execution function
main() {
local action="${1:-help}"
local param1="${2:-}"
local param2="${3:-}"
local param3="${4:-}"
local param4="${5:-}"
local param5="${6:-}"
log_action "=== MacFleet User Lifecycle Management Started ===" "INFO"
log_action "Action: $action" "INFO"
case "$action" in
"delete")
if [[ -z "$param1" ]]; then
echo "Usage: $0 delete <username> [policy] [compliance_framework] [retention_period] [authorized_by]"
echo "Policies: ${!LIFECYCLE_POLICIES[*]}"
echo "Compliance: ${!COMPLIANCE_FRAMEWORKS[*]}"
echo "Retention: ${!RETENTION_PERIODS[*]}"
exit 1
fi
enterprise_user_deletion "$param1" "$param2" "$param3" "$param4" "$param5"
;;
"backup")
if [[ -z "$param1" ]]; then
echo "Usage: $0 backup <username> [compliance_framework]"
exit 1
fi
backup_user_data_enterprise "$param1" "$param2"
;;
"disable")
if [[ -z "$param1" ]]; then
echo "Usage: $0 disable <username>"
exit 1
fi
disable_user_account "$param1"
;;
"fleet")
if [[ -z "$param1" || -z "$param2" ]]; then
echo "Usage: $0 fleet <operation> <user_list> [policy] [compliance_framework]"
echo "Operations: bulk_delete, audit_all, compliance_check"
exit 1
fi
manage_fleet_users "$param1" "$param2" "$param3" "$param4"
;;
"validate")
if [[ -z "$param1" ]]; then
echo "Usage: $0 validate <username>"
exit 1
fi
pre_deletion_validation "$param1"
;;
"prereq")
check_deletion_prerequisites
;;
"help")
echo "Usage: $0 [action] [options...]"
echo "Actions:"
echo " delete <username> [policy] [compliance] [retention] [authorized_by] - Delete user with enterprise policies"
echo " backup <username> [compliance] - Backup user data"
echo " disable <username> - Disable user account"
echo " fleet <operation> <user_list> [policy] [compliance] - Fleet user operations"
echo " validate <username> - Validate deletion prerequisites"
echo " prereq - Check system prerequisites"
echo " help - Show this help"
echo ""
echo "Policies: ${!LIFECYCLE_POLICIES[*]}"
echo "Compliance: ${!COMPLIANCE_FRAMEWORKS[*]}"
echo "Retention: ${!RETENTION_PERIODS[*]}"
;;
*)
log_action "ERROR: Unknown action: $action" "ERROR"
echo "Use '$0 help' for usage information"
exit 1
;;
esac
log_action "=== User lifecycle management completed ===" "INFO"
}
# Execute main function
main "$@"
Important Security Considerations
Secure Token Requirements
#!/bin/bash
# Manage Secure Token requirements for user deletion
manage_secure_tokens() {
echo "=== Secure Token Management ==="
# List all Secure Token holders
echo "Current Secure Token holders:"
sysadminctl -secureTokenStatus 2>/dev/null | grep -E "(Username|Enabled)"
echo ""
echo "--- Secure Token Guidelines ---"
echo "1. Cannot delete the only Secure Token holder"
echo "2. Must have at least one admin with Secure Token"
echo "3. Grant Secure Token before attempting deletion"
echo "4. Secure Token required for FileVault and certain operations"
}
# Grant Secure Token to admin user
grant_secure_token() {
local admin_user="$1"
local target_user="$2"
if [[ -z "$admin_user" || -z "$target_user" ]]; then
echo "Usage: grant_secure_token <admin_user> <target_user>"
return 1
fi
echo "Granting Secure Token to $target_user via $admin_user..."
sysadminctl -secureTokenOn "$target_user" -password -adminUser "$admin_user"
}
# Usage
manage_secure_tokens
Data Retention and Compliance
#!/bin/bash
# Implement data retention policies
implement_retention_policy() {
local policy_name="$1"
local retention_days="${2:-90}"
echo "=== Data Retention Policy Implementation ==="
echo "Policy: $policy_name"
echo "Retention Period: $retention_days days"
# Find old backups for cleanup
local old_backups=$(find "$BACKUP_DIR" -type d -mtime +$retention_days 2>/dev/null)
if [[ -n "$old_backups" ]]; then
echo "Found backups older than $retention_days days:"
echo "$old_backups"
# Archive old backups before deletion (if required by policy)
case "$policy_name" in
"legal_hold")
echo "Legal hold active - no deletion performed"
;;
"compliance_minimum")
echo "Compliance minimum retention - archiving to long-term storage"
;;
*)
echo "Standard retention - marking for deletion"
;;
esac
else
echo "No backups found older than $retention_days days"
fi
}
# Usage
implement_retention_policy "standard" "90"
Important Notes
- Administrator Privileges - User deletion requires administrator privileges and proper authentication
- Secure Token Management - Cannot delete the only Secure Token holder; ensure multiple admin users exist
- Full Disk Access - Service app requires Full Disk Access permission in System Preferences
- Data Backup - Always backup user data before deletion if required by organizational policies
- Compliance Requirements - Different industries have specific data retention and deletion requirements
- Audit Trails - Maintain comprehensive logs of all user deletion activities for compliance
- Recovery Procedures - Test backup and recovery procedures before implementing deletion policies