Tutorial

New updates and improvements to Roundfleet.

Important notice

The code examples and scripts provided in these tutorials are for educational purposes only. Roundfleet is not responsible for any issues, damages, or security vulnerabilities that may arise from the use, modification, or implementation of these examples. Always review and test code in a secure environment before using it in production systems.

Manage FileVault Encryption on macOS

FileVault provides full-disk encryption for macOS devices, protecting sensitive data even if the device is lost or stolen. This tutorial shows how to automate FileVault management across your Roundfleet using command-line scripts.

Understanding FileVault

FileVault encrypts the entire startup disk using XTS-AES-128 encryption with a 256-bit key. Key benefits include:

  • Data Protection - Encrypts all data on the startup disk
  • Compliance - Meets enterprise security requirements
  • Performance - Hardware-accelerated encryption on modern Macs
  • Recovery - Multiple recovery options available

Basic FileVault Commands

Check FileVault Status

#!/bin/bash

# Check current FileVault status
fdesetup status

# Get detailed encryption information
diskutil apfs listCryptoUsers /

Enable FileVault

#!/bin/bash

# Basic FileVault enable command
sudo fdesetup enable --user "username" --password "password"

# Enable with specific keychain
sudo fdesetup enable --user "username" --password "password" --keychain /Library/Keychains/System.keychain

Disable FileVault

#!/bin/bash

# Basic FileVault disable command
sudo fdesetup disable --user "username" --password "password"

Enterprise FileVault Management Script

Complete script for managing FileVault across your Roundfleet:

#!/bin/bash

# FileVault Management Script for Roundfleet
# Compatible with macOS 10.14+

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

# Function to log messages
log_message() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Function to get current user
get_current_user() {
    stat -f "%Su" /dev/console
}

# Function to check if user has secure token
check_secure_token() {
    local username="$1"
    
    if sysadminctl -secureTokenStatus "$username" 2>/dev/null | grep -q "ENABLED"; then
        return 0
    else
        return 1
    fi
}

# Function to check FileVault status
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
}

# Function to get encryption progress
get_encryption_progress() {
    fdesetup status | grep -o '[0-9]\+%' | head -1
}

# Function to validate user credentials
validate_user_credentials() {
    local username="$1"
    local password="$2"
    
    # Check if user exists
    if ! id "$username" &>/dev/null; then
        log_message "✗ User does not exist: $username"
        return 1
    fi
    
    # Check if user has admin privileges
    if ! dsmemberutil checkmembership -U "$username" -G admin &>/dev/null; then
        log_message "✗ User is not an administrator: $username"
        return 1
    fi
    
    # Check if user has secure token
    if ! check_secure_token "$username"; then
        log_message "✗ User does not have secure token: $username"
        return 1
    fi
    
    # Verify password (basic check)
    if [[ -z "$password" ]]; then
        log_message "✗ Password cannot be empty for user: $username"
        return 1
    fi
    
    log_message "✓ User credentials validated: $username"
    return 0
}

# Function to enable FileVault
enable_filevault() {
    local username="$1"
    local password="$2"
    local force_enable="$3"
    
    log_message "Starting FileVault enablement for user: $username"
    
    # Check current status
    local current_status
    current_status=$(check_filevault_status)
    
    case "$current_status" in
        "enabled")
            log_message "! FileVault is already enabled"
            if [[ "$force_enable" != "true" ]]; then
                return 0
            fi
            ;;
        "encrypting")
            log_message "! FileVault encryption is already in progress"
            local progress
            progress=$(get_encryption_progress)
            log_message "  Encryption progress: ${progress:-Unknown}"
            return 0
            ;;
        "decrypting")
            log_message "✗ Cannot enable FileVault while decryption is in progress"
            return 1
            ;;
    esac
    
    # Validate user credentials
    if ! validate_user_credentials "$username" "$password"; then
        return 1
    fi
    
    # Enable FileVault
    log_message "Enabling FileVault..."
    
    if fdesetup enable -user "$username" -password "$password" -keychain "$KEYCHAIN_PATH" 2>/dev/null; then
        log_message "✓ FileVault enable command executed successfully"
        
        # Wait a moment and check status
        sleep 5
        local new_status
        new_status=$(check_filevault_status)
        
        case "$new_status" in
            "enabled")
                log_message "✓ FileVault is now enabled"
                ;;
            "encrypting")
                local progress
                progress=$(get_encryption_progress)
                log_message "✓ FileVault encryption started (${progress:-0%})"
                ;;
            *)
                log_message "! FileVault status unclear: $new_status"
                ;;
        esac
        
        return 0
    else
        log_message "✗ Failed to enable FileVault"
        return 1
    fi
}

# Function to disable FileVault
disable_filevault() {
    local username="$1"
    local password="$2"
    local force_disable="$3"
    
    log_message "Starting FileVault disablement for user: $username"
    
    # Check current status
    local current_status
    current_status=$(check_filevault_status)
    
    case "$current_status" in
        "disabled")
            log_message "! FileVault is already disabled"
            if [[ "$force_disable" != "true" ]]; then
                return 0
            fi
            ;;
        "decrypting")
            log_message "! FileVault decryption is already in progress"
            local progress
            progress=$(get_encryption_progress)
            log_message "  Decryption progress: ${progress:-Unknown}"
            return 0
            ;;
        "encrypting")
            log_message "✗ Cannot disable FileVault while encryption is in progress"
            return 1
            ;;
    esac
    
    # Validate user credentials
    if ! validate_user_credentials "$username" "$password"; then
        return 1
    fi
    
    # Disable FileVault
    log_message "Disabling FileVault..."
    
    if fdesetup disable -user "$username" -password "$password" 2>/dev/null; then
        log_message "✓ FileVault disable command executed successfully"
        
        # Wait a moment and check status
        sleep 5
        local new_status
        new_status=$(check_filevault_status)
        
        case "$new_status" in
            "disabled")
                log_message "✓ FileVault is now disabled"
                ;;
            "decrypting")
                local progress
                progress=$(get_encryption_progress)
                log_message "✓ FileVault decryption started (${progress:-0%})"
                ;;
            *)
                log_message "! FileVault status unclear: $new_status"
                ;;
        esac
        
        return 0
    else
        log_message "✗ Failed to disable FileVault"
        return 1
    fi
}

# Function to get system information
get_system_info() {
    log_message "=== System Information ==="
    log_message "Hostname: $(hostname)"
    log_message "macOS Version: $(sw_vers -productVersion)"
    log_message "Current User: $(get_current_user)"
    log_message "FileVault Status: $(check_filevault_status)"
    
    # Get FileVault users
    local fv_users
    fv_users=$(fdesetup list 2>/dev/null)
    if [[ -n "$fv_users" ]]; then
        log_message "FileVault Enabled Users:"
        echo "$fv_users" | while read -r line; do
            log_message "  $line"
        done
    fi
}

# Function to display usage
usage() {
    echo "Usage: $0 {enable|disable|status} [options]"
    echo ""
    echo "Commands:"
    echo "  enable    Enable FileVault"
    echo "  disable   Disable FileVault"
    echo "  status    Check FileVault status"
    echo ""
    echo "Options:"
    echo "  -u, --user USERNAME      Specify username"
    echo "  -p, --password PASSWORD  Specify password"
    echo "  -f, --force             Force operation even if already in desired state"
    echo "  -h, --help              Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0 enable -u admin -p password123"
    echo "  $0 disable -u admin -p password123 -f"
    echo "  $0 status"
}

# Main function
main() {
    local command="$1"
    local username=""
    local password=""
    local force="false"
    
    # Parse 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 "Unknown option: $1"
                usage
                exit 1
                ;;
        esac
    done
    
    # Execute command
    case "$command" in
        "enable")
            if [[ -z "$username" ]] || [[ -z "$password" ]]; then
                echo "Error: Username and password required for enable command"
                usage
                exit 1
            fi
            
            log_message "=== Starting FileVault Enable Operation ==="
            get_system_info
            
            if enable_filevault "$username" "$password" "$force"; then
                log_message "=== FileVault Enable Operation Completed Successfully ==="
                exit 0
            else
                log_message "=== FileVault Enable Operation Failed ==="
                exit 1
            fi
            ;;
        "disable")
            if [[ -z "$username" ]] || [[ -z "$password" ]]; then
                echo "Error: Username and password required for disable command"
                usage
                exit 1
            fi
            
            log_message "=== Starting FileVault Disable Operation ==="
            get_system_info
            
            if disable_filevault "$username" "$password" "$force"; then
                log_message "=== FileVault Disable Operation Completed Successfully ==="
                exit 0
            else
                log_message "=== FileVault Disable Operation Failed ==="
                exit 1
            fi
            ;;
        "status")
            get_system_info
            exit 0
            ;;
        *)
            echo "Error: Invalid command: $command"
            usage
            exit 1
            ;;
    esac
}

# Execute main function
main "$@"

Quick FileVault Scripts

Simple Enable Script

#!/bin/bash

USERNAME="admin"
PASSWORD="your_password_here"

if fdesetup enable -user "$USERNAME" -password "$PASSWORD"; then
    echo "FileVault enabled successfully"
else
    echo "Failed to enable FileVault"
    exit 1
fi

Simple Status Check

#!/bin/bash

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

if echo "$STATUS" | grep -q "FileVault is On"; then
    echo "✓ FileVault is enabled"
    exit 0
elif echo "$STATUS" | grep -q "FileVault is Off"; then
    echo "✗ FileVault is disabled"
    exit 1
else
    echo "! FileVault status unclear"
    exit 2
fi

Recovery Key Management

Generate Personal Recovery Key

#!/bin/bash

# Enable FileVault with personal recovery key
sudo fdesetup enable -user "$USERNAME" -password "$PASSWORD" -outputplist > /tmp/filevault_key.plist

# Extract recovery key
RECOVERY_KEY=$(grep -A1 "RecoveryKey" /tmp/filevault_key.plist | tail -1 | sed 's/.*<string>\(.*\)<\/string>.*/\1/')

echo "Recovery Key: $RECOVERY_KEY"

# Securely store recovery key
echo "$RECOVERY_KEY" | sudo tee /var/root/filevault_recovery_key.txt
sudo chmod 600 /var/root/filevault_recovery_key.txt

# Clean up
rm -f /tmp/filevault_key.plist

Enable Institutional Recovery Key

#!/bin/bash

# Create institutional recovery key
CERT_PATH="/path/to/institutional_certificate.cer"

if [[ -f "$CERT_PATH" ]]; then
    sudo fdesetup enable -user "$USERNAME" -password "$PASSWORD" -certificate "$CERT_PATH"
    echo "FileVault enabled with institutional recovery key"
else
    echo "Institutional certificate not found: $CERT_PATH"
    exit 1
fi

Troubleshooting Common Issues

Fix Secure Token Issues

#!/bin/bash

USERNAME="admin"

# Grant secure token to user
sudo sysadminctl -secureTokenOn "$USERNAME" -password -

# Verify secure token
if sysadminctl -secureTokenStatus "$USERNAME" | grep -q "ENABLED"; then
    echo "✓ Secure token enabled for $USERNAME"
else
    echo "✗ Failed to enable secure token for $USERNAME"
fi

Handle Blank Password Error

#!/bin/bash

USERNAME="admin"

# Check if user has a password set
if dscl . -read "/Users/$USERNAME" AuthenticationAuthority | grep -q "No such key"; then
    echo "User $USERNAME has no password set"
    echo "Setting password..."
    sudo dscl . -passwd "/Users/$USERNAME" "" "new_password_here"
fi

Monitoring and Reporting

FileVault Status Report

#!/bin/bash

# Generate FileVault status report
REPORT_FILE="/tmp/filevault_report.txt"

{
    echo "=== FileVault Status Report ==="
    echo "Generated: $(date)"
    echo "Hostname: $(hostname)"
    echo ""
    
    echo "=== FileVault Status ==="
    fdesetup status
    echo ""
    
    echo "=== Enabled Users ==="
    fdesetup list
    echo ""
    
    echo "=== Secure Token Status ==="
    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 "User: $user - Token: ${token_status:-UNKNOWN}"
        fi
    done
    
} > "$REPORT_FILE"

echo "Report generated: $REPORT_FILE"

Common Error Solutions

ErrorCauseSolution
"Blank password"User has no passwordSet password with dscl . -passwd
"Master keychain found"Keychain ambiguityAdd -keychain parameter
"Secure token required"User lacks secure tokenGrant token with sysadminctl
"Already encrypted"FileVault already onUse -force or check status first
"Encryption in progress"Concurrent operationWait for completion

Security Best Practices

  • Use strong passwords for FileVault-enabled accounts
  • Store recovery keys securely in enterprise key management
  • Test scripts on isolated devices before fleet deployment
  • Monitor encryption progress to ensure completion
  • Backup recovery keys before making changes
  • Validate user permissions before attempting operations

Performance Considerations

  • Initial encryption can take several hours
  • System performance may be impacted during encryption
  • Schedule operations during maintenance windows
  • Monitor disk space (encryption requires free space)
  • Consider SSD vs HDD performance differences

Important Notes

  • FileVault requires admin privileges and secure tokens
  • Recovery keys are essential for data recovery
  • Encryption/decryption cannot be interrupted safely
  • Test all scripts thoroughly before production use
  • Always have a backup recovery plan

Related Tutorials

FileVault Encryption Management on macOS

Monitor FileVault encryption status, track encryption progress, and manage disk encryption compliance across Roundfleet devices with advanced enterprise security features.

Jul 7, 2025

File Encryption Management on macOS

Learn how to encrypt and decrypt files on macOS using OpenSSL, implement enterprise encryption policies, manage encryption keys, and ensure data security compliance across your fleet.

Jul 7, 2025

Secure Archive Management on macOS

Learn how to create, manage, and secure archives on macOS devices using password-protected ZIP files with enterprise-grade security, batch operations, compliance tracking, and fleet-wide archive management capabilities.

Jul 7, 2025

Secure Token Management on macOS

Learn how to manage and grant secure tokens to users on macOS devices using sysadminctl for enterprise security, FileVault management, and cryptographic operations authentication.

Jul 7, 2025

Secure Data Erasure on macOS

Learn how to securely erase free space and manage data privacy on macOS devices using advanced secure erasure tools with compliance monitoring, privacy protection, and fleet-wide data security capabilities.

Jul 7, 2025

Screen Lock Security on macOS

Configure and enforce screen lock password requirements, sleep security policies, and automated lock mechanisms on macOS devices using AppleScript automation and enterprise security frameworks.

Jul 7, 2025

File Protection on macOS

Implement comprehensive file and application protection on macOS devices using immutable flags, access controls, and enterprise security policies for organizational data protection.

Jul 7, 2025

File Ownership Management on macOS

Learn how to change file and folder ownership, manage permissions, and implement comprehensive ownership policies on macOS devices using command-line scripts for secure file system management.

Jul 7, 2025