Skip to content

Instantly share code, notes, and snippets.

@osdouglas
Last active July 14, 2025 22:10
Show Gist options
  • Save osdouglas/5c13dae00e68f943e845093b0a45eb8c to your computer and use it in GitHub Desktop.
Save osdouglas/5c13dae00e68f943e845093b0a45eb8c to your computer and use it in GitHub Desktop.
FileVault diagnostics collection
#!/bin/bash
set -euo pipefail
# Collect serial number
SERIAL=$(system_profiler SPHardwareDataType | awk '/Serial/ {print $NF}')
HOSTNAME=$(scutil --get ComputerName 2>/dev/null || echo "UnknownHost")
OUTDIR="/tmp/fv-diagnostics-${SERIAL}-$(date +%s)"
ZIPFILE="/tmp/${SERIAL}.zip"
mkdir -p "$OUTDIR"
logcmd() {
echo "$ $1" >> "$OUTDIR/$2"
eval "$1" >> "$OUTDIR/$2" 2>&1 || echo "(command failed or permission denied)" >> "$OUTDIR/$2"
echo >> "$OUTDIR/$2"
}
# 1. System identity
logcmd "scutil --get ComputerName" system.txt
logcmd "scutil --get LocalHostName" system.txt
logcmd "scutil --get HostName" system.txt
logcmd "system_profiler SPHardwareDataType" system.txt
logcmd "sw_vers" system.txt
# 2. FileVault + SecureToken state
logcmd "fdesetup status" fdesetup.txt
logcmd "sudo fdesetup list" fdesetup.txt
logcmd "sudo sysadminctl -secureTokenStatus $(whoami)" securetoken.txt
logcmd "diskutil apfs list" diskutil.txt
# Derive disk (typically diskXsY where Y is the slice)
DISKDATA=$(diskutil info /System/Volumes/Data | awk '/Part of Whole:/ {print $NF}')
[[ -n "$DISKDATA" ]] && logcmd "diskutil apfs listcryptousers ${DISKDATA}s5" cryptousers.txt || echo "(could not resolve Data volume)" >> "$OUTDIR/cryptousers.txt"
logcmd "diskutil apfs listVolumeGroups" volumegroups.txt
logcmd "csrutil status" sip.txt
logcmd "csrutil authenticated-root status" sip.txt
logcmd "diskutil apfs listSnapshots /" snapshots.txt
# 3. Preboot structure check
PREBOOT_DIR=$(find /System/Volumes/Preboot -maxdepth 1 -type d -regex '.*/[A-F0-9-]\{36\}' | head -n1)
if [[ -n "$PREBOOT_DIR" && -d "$PREBOOT_DIR" ]]; then
logcmd "ls -lh ${PREBOOT_DIR}/System/Library/CoreServices/boot.efi" preboot.txt
logcmd "stat -f \"%Sm %N\" ${PREBOOT_DIR}/var/db/CryptoUserInfo.plist" preboot.txt
logcmd "stat -f \"%Sm %N\" ${PREBOOT_DIR}/System/Library/Caches/com.apple.corestorage/EncryptedRoot.plist.wipekey" preboot.txt
logcmd "plutil -p ${PREBOOT_DIR}/var/db/CryptoUserInfo.plist" preboot.txt
else
echo "❌ No valid Preboot directory found" >> "$OUTDIR/preboot.txt"
fi
# 4. User + UUID mapping
logcmd "dscl . -list /Users UniqueID" users.txt
logcmd "dscl . -read /Users/$(whoami) GeneratedUID" users.txt
# 5. Boot policy + Secure Enclave
logcmd "sudo bputil -d" bputil.txt
# 6. Falcon + system extensions
if [[ -x /Applications/Falcon.app/Contents/Resources/falconctl ]]; then
logcmd "sudo /Applications/Falcon.app/Contents/Resources/falconctl info" falcon.txt
logcmd "sudo /Applications/Falcon.app/Contents/Resources/falconctl stats" falcon.txt
fi
logcmd "systemextensionsctl list" systemextensions.txt
# Package the output and clean previous ZIP if any
set +e
[[ -f "$ZIPFILE" ]] && rm -f "$ZIPFILE"
zip -r "$ZIPFILE" "$OUTDIR" >/dev/null 2>&1
if [[ -f "$ZIPFILE" ]]; then
echo "✅ Output saved to $ZIPFILE"
open `dirname "$ZIPFILE"`
else
echo "❌ Failed to create ZIP. Check directory permissions."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment