โ† macOS & Jamf Pro Pro
๐Ÿ–ฅ๏ธ macOS & Jamf

Advanced Mac Diagnostic Script via Jamf Self Service

Deploy a comprehensive 14-section diagnostic script through Jamf Pro Self Service that analyses hardware, crash logs, AP watchdog events, FileVault, network, security, and more โ€” then saves a full report to the user's Desktop.

โ„น๏ธ
What this does: Runs a full system diagnostic as root via Jamf, covering hardware, crash analysis, AP watchdog events, FileVault, peripherals, network, security, Jamf MDM status, and event logs. Saves a .txt report and a .zip to the user's Desktop, then notifies them via dialog โ€” ready to send to IT support.
What the Script Covers

The script runs 14 diagnostic sections automatically and flags warnings and critical issues as it goes. Here's a quick summary of each section:

01
System Overview
Hardware identity, macOS version, kernel, architecture, uptime, load average, and current logged-in user details.
02
AP Watchdog & Crash Analysis
Kernel panic log count and content, SOCD / AP watchdog events from the last 30 days, all crash reports, and watchdog timeout events from system logs.
03
FileVault & Encryption
FileVault enabled/disabled status, APFS encryption detail, FileVault users list, and secure token status. FileVault is flagged as a known AP watchdog trigger on M1 Macs.
04
Hardware Diagnostics
CPU info, RAM usage breakdown (free/active/inactive/wired/compressed), memory pressure, storage SMART status, disk capacity, GPU info, battery health, and thermal sensor / fan data.
05
Connected Devices & Peripherals
USB devices, Thunderbolt/USB-C devices, Bluetooth devices, external drives, and network interfaces. External USB storage is flagged as a known AP watchdog trigger.
06
Network & Shares
Current Wi-Fi, IP, DNS, gateway, mounted SMB/AFP/NFS shares (flagged as watchdog trigger), network statistics, and active connections.
07
Software & Processes
Checks for known trigger apps (Docker, Xcode, Parallels, VMware, VirtualBox, AV software), top CPU/memory processes, launch agents/daemons, login items, and third-party kernel extensions.
08
Power & Sleep Management
Full pmset settings, sleep/wake history, assertions preventing sleep, power adapter info, and flags for problematic hibernate modes known to trigger AP watchdog.
09
Security & System Integrity
SIP status, Gatekeeper, secure boot policy, MDM enrolment, firewall status, active security certificates, and failed login attempts from the last 7 days.
10
Disk Health & Filesystem
APFS container health, Disk Utility First Aid, filesystem usage, inode usage, large files over 1 GB, and temp/cache sizes.
11
Network Diagnostics
DNS resolution test, ping to Apple and Google, network quality check, Wi-Fi signal detail, VPN status, and hosts file review.
12
Jamf & MDM Status
Jamf binary version, management framework files, last check-in status, installed MDM profiles, and configuration profiles.
13
Event Log Analysis
Critical system errors, kernel errors, application crashes, wake/sleep issues, disk I/O errors, and memory errors โ€” all from the last 7 to 30 days.
14
Diagnostic Summary & Recommendations
Automatically compiles all findings into a prioritised summary with a step-by-step action plan โ€” what to fix first, what to test, and when to book an Apple repair.
๐Ÿ’ก
Output: A .txt report and a .zip are both saved to the user's Desktop automatically. A dialog box notifies the user when complete with an option to open the Desktop folder. The user can email or upload the ZIP straight to IT support.

Save the Script

Copy the full script (see the Full Script section below) and save it as a .sh file.

โ†’
Suggested filename
mac-advanced-diagnostic.sh
โ†’
Make it executable (optional โ€” Jamf handles this)
If testing locally before uploading: chmod +x mac-advanced-diagnostic.sh
โ†’
Encoding
Save as UTF-8 with Unix line endings (LF not CRLF). If editing on Windows, use VS Code or Notepad++ and set line ending to LF before saving.

Add the Script in Jamf Pro

Upload the script into Jamf Pro's script library so it can be attached to a policy.

2.1
Open Scripts
Log in to your Jamf Pro server โ†’ go to Settings (โš™๏ธ top right) โ†’ Computer Management โ†’ Scripts โ†’ click + New.
2.2
General tab โ€” fill in details
Display Name: Advanced Mac Diagnostic v2.0
Category: Diagnostics (create this category first if it doesn't exist)
Info: Full system diagnostic โ€” AP watchdog, hardware, network, security, Jamf MDM. Saves report to Desktop.
Notes: Run as root via Self Service. Output saved to /var/tmp/mac_diagnostics/ and user Desktop.
2.3
Script tab โ€” paste the script
Click the Script tab and paste the full script content into the editor. The shebang line #!/bin/bash must be the very first line.
2.4
Options tab โ€” set priority
Priority: After โ€” runs after other policy items complete.
Parameter Labels: Leave blank โ€” this script uses no parameters.
2.5
Save
Click Save. The script is now in the Jamf library and ready to attach to a policy.

Create a Policy for Self Service

Create a policy that runs the script on demand from the Jamf Self Service app โ€” so users or helpdesk can trigger it themselves without needing admin credentials.

3.1
Create a new policy
Go to Computers โ†’ Policies โ†’ + New.
3.2
General tab โ€” set trigger and frequency
Display Name: Run Advanced Mac Diagnostic
Enabled: โœ… Yes
Trigger: โ˜‘ Self Service (uncheck all others)
Execution Frequency: Ongoing โ€” allows users to run it multiple times
Category: Diagnostics
3.3
Scripts tab โ€” attach the script
Click Scripts โ†’ Configure โ†’ find Advanced Mac Diagnostic v2.0 โ†’ click Add. Leave priority as After.
3.4
Maintenance tab โ€” run recon after
Under Maintenance โ†’ Update Inventory โ€” the script already calls jamf recon internally, so this is optional but adds a safety net.
3.5
Self Service tab โ€” configure display
Make the policy available in Self Service: โœ… Yes
Button Name (Before): Run Diagnostic
Button Name (After): Run Again
Description: Runs a full system diagnostic and saves a report to your Desktop. The report covers hardware, crashes, network, security, and more. Takes 2โ€“4 minutes. Send the ZIP file to IT Support when done.
Category in Self Service: IT Support (or whichever category suits your environment)
Feature on main page: Optional โ€” useful if this is a key helpdesk tool
๐Ÿ’ก
Icon tip: Add a clear icon on the Self Service tab (wrench or magnifying glass) so users can find it easily. Jamf accepts PNG/JPEG under 1 MB.

Scope the Policy

Control which computers the policy appears on in Self Service.

โ†’
Scope tab โ€” targets
Target Computers: Select All Managed Clients to make it available to everyone, or target a specific smart group (e.g. All macOS Laptops or Users Reporting Crashes).

Best practice: Start with a small pilot group โ€” your own Mac or a test device โ€” before rolling out to all users.
โ†’
Exclusions (optional)
Exclude any computers that shouldn't have this in Self Service โ€” e.g. lab machines, kiosks, or servers.
โ†’
Save the policy
Click Save. The policy is now live in Self Service for the scoped devices.

Run from Self Service & Verify Output

Test the policy on a scoped device to confirm the script runs correctly and the report appears on the Desktop.

5.1
Open Self Service on the Mac
Launch the Self Service app (Applications โ†’ Self Service or via Spotlight). Find the policy under the category you set โ€” IT Support or similar.
5.2
Click "Run Diagnostic"
The script runs in the background as root. It takes approximately 2โ€“4 minutes depending on system size and log volume. The screen won't show visible progress โ€” this is normal.
5.3
Wait for the dialog box
When complete, a dialog appears on screen: "โœ… Advanced Diagnostic Complete!" with the filename and an option to open the Desktop folder.
5.4
Check the Desktop
Two files will appear on the Desktop:
MacDiagnostic_<hostname>_<timestamp>.txt โ€” full readable report
MacDiagnostic_<hostname>_<timestamp>.zip โ€” compressed copy ready to send
5.5
Review the Summary section
Open the .txt file and scroll to Section 14 โ€” Diagnostic Summary & Recommendations. This is where all flagged issues are listed with colour-coded severity and a numbered action plan.
๐Ÿ’ก
If the script fails silently: Check the Jamf policy log โ€” in Jamf Pro go to Computers โ†’ the device โ†’ History โ†’ Policy Logs โ†’ find the policy and click Show Logs. Any script errors will appear there. The raw log is also saved to /var/tmp/mac_diagnostics/ on the device.
โš ๏ธ
Permissions note: The script runs as root via Jamf. Some commands like bputil and Recovery-mode tools will return limited output when not in Recovery โ€” this is expected and does not indicate a script error.

mac-advanced-diagnostic.sh

Copy the entire script below. The shebang #!/bin/bash must remain as the very first line with no blank line before it.

#!/bin/bash
# =============================================================================
#  ADVANCED MAC DIAGNOSTIC SCRIPT โ€” Jamf Pro Self Service
#  Version: 2.0
#  Purpose: Full system diagnostics, AP watchdog, hardware & software analysis
#  Run As: Root (via Jamf)
# =============================================================================

# โ”€โ”€ CONFIG โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
TIMESTAMP=$(date '+%Y%m%d_%H%M%S')
CURRENT_USER=$(stat -f '%Su' /dev/console)
HOSTNAME=$(hostname -s)
REPORT_DIR="/var/tmp/mac_diagnostics"
REPORT_FILE="$REPORT_DIR/diagnostic_${HOSTNAME}_${TIMESTAMP}.txt"
DESKTOP_COPY="/Users/$CURRENT_USER/Desktop/MacDiagnostic_${HOSTNAME}_${TIMESTAMP}.txt"
LOG_DIR="/var/tmp/mac_diagnostics/logs"

mkdir -p "$REPORT_DIR" "$LOG_DIR"

# โ”€โ”€ HELPER FUNCTIONS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
section()     { echo ""; echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”"; echo "  โ–ถ  $1"; echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”"; }
subsection()  { echo ""; echo "  โ”€โ”€ $1 โ”€โ”€"; }
flag_warn()   { echo "  โš ๏ธ  WARNING : $1"; }
flag_ok()     { echo "  โœ… OK      : $1"; }
flag_crit()   { echo "  ๐Ÿ”ด CRITICAL: $1"; }
flag_info()   { echo "  โ„น๏ธ  INFO    : $1"; }

# โ”€โ”€ BEGIN REPORT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
{

# SECTION 1 โ€” SYSTEM OVERVIEW
section "1. SYSTEM OVERVIEW"
subsection "Hardware Identity"
system_profiler SPHardwareDataType 2>/dev/null | grep -E \
  "Model Name|Model Identifier|Chip|Total Number of Cores|Memory|Serial Number|Hardware UUID"
subsection "macOS Version"
sw_vers; echo "Kernel: $(uname -r)"; echo "Architecture: $(uname -m)"
subsection "Uptime & Load"
uptime; sysctl -n vm.loadavg
subsection "Current Logged-in User"
echo "User: $CURRENT_USER"; echo "UID: $(id -u $CURRENT_USER 2>/dev/null)"
echo "Groups: $(id -Gn $CURRENT_USER 2>/dev/null)"

# SECTION 2 โ€” AP WATCHDOG & CRASH ANALYSIS
section "2. AP WATCHDOG & CRASH ANALYSIS"
subsection "Panic Log Summary"
PANIC_COUNT=$(find /Library/Logs/DiagnosticReports -name "*panic*" 2>/dev/null | wc -l | tr -d ' ')
echo "Total kernel panic logs: $PANIC_COUNT"
if [ "$PANIC_COUNT" -gt 5 ]; then flag_crit "High kernel panics ($PANIC_COUNT)"
elif [ "$PANIC_COUNT" -gt 2 ]; then flag_warn "Multiple panics ($PANIC_COUNT)"
elif [ "$PANIC_COUNT" -gt 0 ]; then flag_warn "Some panics ($PANIC_COUNT)"
else flag_ok "No kernel panics"; fi
subsection "SOCD / AP Watchdog Events (Last 30 Days)"
SOCD_COUNT=$(log show --predicate 'eventMessage contains "SOCD" OR eventMessage contains "AP watchdog"' \
  --last 30d 2>/dev/null | grep -c "SOCD\|watchdog" || echo 0)
echo "SOCD/Watchdog events: $SOCD_COUNT"
if [ "$SOCD_COUNT" -gt 3 ]; then flag_crit "Frequent SOCD events โ€” hardware issue likely"
elif [ "$SOCD_COUNT" -gt 0 ]; then flag_warn "SOCD events detected โ€” monitor closely"
else flag_ok "No SOCD events in last 30 days"; fi
subsection "SOCD Event Detail"
log show --predicate 'eventMessage contains "SOCD" OR eventMessage contains "AP watchdog" OR eventMessage contains "watchdog expired"' \
  --last 30d 2>/dev/null | tail -20
subsection "Last Kernel Panic Content"
LAST_PANIC=$(find /Library/Logs/DiagnosticReports -name "*panic*" 2>/dev/null \
  -exec ls -t {} + 2>/dev/null | head -1)
if [ -n "$LAST_PANIC" ]; then echo "Most recent: $LAST_PANIC"; head -50 "$LAST_PANIC" 2>/dev/null
else echo "No panic logs found."; fi

# SECTION 3 โ€” FILEVAULT & ENCRYPTION
section "3. FILEVAULT & ENCRYPTION"
subsection "FileVault Status"
FV_STATUS=$(fdesetup status 2>/dev/null); echo "$FV_STATUS"
if echo "$FV_STATUS" | grep -q "On"; then
  flag_warn "FileVault ENABLED โ€” known AP watchdog trigger on M1 Macs"
  flag_info "Consider disabling FileVault to test if crashes stop"
else flag_ok "FileVault is OFF"; fi
subsection "APFS Encryption Detail"
diskutil apfs list 2>/dev/null | grep -E "Container|Volume|Encrypted|FileVault|Role|Capacity"
subsection "Secure Token Status"
sysadminctl -secureTokenStatus "$CURRENT_USER" 2>/dev/null

# SECTION 4 โ€” HARDWARE DIAGNOSTICS
section "4. HARDWARE DIAGNOSTICS"
subsection "CPU Information"
sysctl -n machdep.cpu.brand_string 2>/dev/null || system_profiler SPHardwareDataType | grep "Chip"
echo "Physical CPUs: $(sysctl -n hw.physicalcpu)"; echo "Logical CPUs: $(sysctl -n hw.logicalcpu)"
subsection "Memory (RAM)"
TOTAL_RAM=$(sysctl -n hw.memsize | awk '{print $1/1073741824 " GB"}'); echo "Total RAM: $TOTAL_RAM"
vm_stat 2>/dev/null | awk '/Pages free/{free=$3}/Pages active/{active=$3}/Pages inactive/{inactive=$3}/Pages wired/{wired=$4}/Pages occupied/{compressed=$5}END{p=4096;printf "Free: %.2f GB\nActive: %.2f GB\nInactive: %.2f GB\nWired: %.2f GB\nCompressed: %.2f GB\n",free*p/1073741824,active*p/1073741824,inactive*p/1073741824,wired*p/1073741824,compressed*p/1073741824}'
subsection "Memory Pressure"
MEM_PRESSURE=$(memory_pressure 2>/dev/null | head -5); echo "$MEM_PRESSURE"
if echo "$MEM_PRESSURE" | grep -q "critical\|WARNING"; then flag_crit "Memory pressure HIGH"
elif echo "$MEM_PRESSURE" | grep -q "warn"; then flag_warn "Memory pressure elevated"
else flag_ok "Memory pressure normal"; fi
subsection "Storage โ€” Capacity"
df -h 2>/dev/null | grep -v "devfs\|map\|/private"
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
if [ "$DISK_USAGE" -gt 90 ]; then flag_crit "Disk at ${DISK_USAGE}% โ€” critically low!"
elif [ "$DISK_USAGE" -gt 80 ]; then flag_warn "Disk at ${DISK_USAGE}% โ€” low space"
else flag_ok "Disk at ${DISK_USAGE}%"; fi
subsection "Battery Health"
BATTERY=$(system_profiler SPPowerDataType 2>/dev/null)
if echo "$BATTERY" | grep -q "Battery"; then
  echo "$BATTERY" | grep -E "Condition|Cycle Count|Full Charge|Maximum Capacity|Charging"
else echo "No battery detected (Desktop Mac)"; fi
subsection "Thermal Sensors & Fan"
powermetrics --samplers smc -n 1 -i 500 2>/dev/null | grep -E "CPU die|GPU die|Fan|thermal|temp" | head -15

# SECTION 5 โ€” CONNECTED DEVICES & PERIPHERALS
section "5. CONNECTED DEVICES & PERIPHERALS"
subsection "USB Devices"
system_profiler SPUSBDataType 2>/dev/null | grep -E "Product ID|Vendor ID|Manufacturer|Speed|^\s+[A-Z]"
USB_DRIVES=$(system_profiler SPUSBDataType 2>/dev/null | grep -i "storage\|disk\|drive" | wc -l)
if [ "$USB_DRIVES" -gt 0 ]; then
  flag_warn "$USB_DRIVES external storage device(s) โ€” known AP watchdog trigger"
  flag_info "Try disconnecting external drives and monitor for crashes"; fi
subsection "Bluetooth Devices"
system_profiler SPBluetoothDataType 2>/dev/null | grep -E "Address|Connected|^\s+[A-Z][a-z]"
subsection "Network Interfaces"
ifconfig 2>/dev/null | grep -E "^[a-z]|inet |status"

# SECTION 6 โ€” NETWORK & SHARES
section "6. NETWORK & SHARES"
subsection "Current Network"
echo "WiFi: $(networksetup -getairportnetwork en0 2>/dev/null)"
echo "IP: $(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null)"
echo "DNS: $(scutil --dns 2>/dev/null | grep nameserver | head -3)"
subsection "Mounted Network Shares"
SHARES=$(mount 2>/dev/null | grep -E "smb|afp|nfs")
if [ -n "$SHARES" ]; then echo "$SHARES"; flag_warn "Network shares mounted โ€” SMB is a known AP watchdog trigger"
else flag_ok "No network shares mounted"; fi

# SECTION 7 โ€” SOFTWARE & PROCESSES
section "7. SOFTWARE & PROCESSES"
subsection "Known Trigger Applications"
TRIGGERS_FOUND=0
for APP in "Docker" "Xcode" "Parallels Desktop" "VMware Fusion" "VirtualBox"; do
  if [ -d "/Applications/${APP}.app" ]; then
    flag_warn "$APP INSTALLED โ€” potential AP watchdog trigger"; TRIGGERS_FOUND=$((TRIGGERS_FOUND+1))
  else flag_ok "$APP: Not installed"; fi
done
for AV in "McAfee" "Symantec" "Norton" "Kaspersky" "Avast"; do
  if find /Applications -maxdepth 1 -iname "*$AV*" 2>/dev/null | grep -q .; then
    flag_warn "$AV Antivirus INSTALLED โ€” can conflict with macOS kernel"; TRIGGERS_FOUND=$((TRIGGERS_FOUND+1)); fi
done
echo "Total trigger apps found: $TRIGGERS_FOUND"
subsection "Top CPU Processes"
ps aux 2>/dev/null | sort -rk 3 | head -10 | awk '{printf "%-35s CPU:%-6s MEM:%-6s\n", $11, $3, $4}'
subsection "Third-Party Kernel Extensions"
THIRD_PARTY_KEXTS=$(kextstat 2>/dev/null | grep -v "com.apple" | wc -l | tr -d ' ')
kextstat 2>/dev/null | grep -v "com.apple" | head -15
if [ "$THIRD_PARTY_KEXTS" -gt 0 ]; then flag_warn "$THIRD_PARTY_KEXTS third-party kexts loaded โ€” potential instability"
else flag_ok "No third-party kernel extensions"; fi
subsection "macOS Updates Available"
softwareupdate -l 2>/dev/null | head -15

# SECTION 8 โ€” POWER & SLEEP MANAGEMENT
section "8. POWER & SLEEP MANAGEMENT"
subsection "Power Management Settings"
pmset -g 2>/dev/null
subsection "Sleep/Wake History (Last 20)"
pmset -g log 2>/dev/null | grep -E "Sleep|Wake|DarkWake" | tail -20
subsection "Assertions Preventing Sleep"
pmset -g assertions 2>/dev/null
HIBERNATE=$(pmset -g | grep "hibernatemode" | awk '{print $2}')
if [ "$HIBERNATE" = "3" ]; then flag_warn "Hibernate mode 3 โ€” can trigger watchdog on M1. Try: sudo pmset -a hibernatemode 0"; fi

# SECTION 9 โ€” SECURITY & SYSTEM INTEGRITY
section "9. SECURITY & SYSTEM INTEGRITY"
subsection "System Integrity Protection"
SIP_STATUS=$(csrutil status 2>/dev/null); echo "$SIP_STATUS"
if echo "$SIP_STATUS" | grep -q "disabled"; then flag_crit "SIP is DISABLED โ€” system vulnerable!"
else flag_ok "SIP is enabled"; fi
subsection "Gatekeeper"
GATE=$(spctl --status 2>/dev/null); echo "$GATE"
if echo "$GATE" | grep -q "disabled"; then flag_warn "Gatekeeper disabled"
else flag_ok "Gatekeeper enabled"; fi
subsection "MDM Enrollment"
profiles status -type enrollment 2>/dev/null
subsection "Firewall"
/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2>/dev/null

# SECTION 10 โ€” DISK HEALTH & FILESYSTEM
section "10. DISK HEALTH & FILESYSTEM"
subsection "APFS Health"
diskutil apfs list 2>/dev/null
subsection "Filesystem Usage"
df -hi 2>/dev/null | grep -v "devfs\|map\|/private"
subsection "Large Files (over 1GB)"
find / -maxdepth 8 -size +1g -not -path "*/proc/*" -not -path "*/System/*" 2>/dev/null | \
  xargs ls -lh 2>/dev/null | sort -rk5 | head -15
subsection "Cache & Temp Size"
du -sh /private/tmp 2>/dev/null; du -sh ~/Library/Caches 2>/dev/null

# SECTION 11 โ€” NETWORK DIAGNOSTICS
section "11. NETWORK DIAGNOSTICS"
subsection "DNS Test"
dig apple.com +short 2>/dev/null | head -3 || host apple.com 2>/dev/null | head -3
subsection "Ping Test"
ping -c 3 apple.com 2>/dev/null | tail -3; ping -c 3 8.8.8.8 2>/dev/null | tail -3
subsection "Wi-Fi Details"
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport \
  -I 2>/dev/null | grep -E "SSID|BSSID|channel|RSSI|lastTxRate"
subsection "VPN Status"
scutil --nc list 2>/dev/null | head -10

# SECTION 12 โ€” JAMF & MDM STATUS
section "12. JAMF & MDM STATUS"
subsection "Jamf Version"
jamf version 2>/dev/null || echo "Jamf binary not found"
subsection "Last Jamf Check-in"
jamf checkJSSConnection 2>/dev/null || \
  defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url 2>/dev/null
subsection "MDM Profiles"
profiles list -output stdout 2>/dev/null | head -30

# SECTION 13 โ€” EVENT LOG ANALYSIS
section "13. EVENT LOG ANALYSIS"
subsection "Critical System Errors (7 Days)"
log show --predicate 'messageType == 16' --last 7d --style syslog 2>/dev/null | grep -v "^Filtering" | tail -20
subsection "Application Crashes (7 Days)"
log show --predicate 'eventMessage contains "crashed" OR eventMessage contains "segfault"' \
  --last 7d 2>/dev/null | grep -v "^Filtering" | tail -15
subsection "Wake/Sleep Issues (7 Days)"
log show --predicate 'eventMessage contains "Wake" OR eventMessage contains "sleep"' \
  --last 7d 2>/dev/null | grep -v "^Filtering" | grep -i "error\|fail\|timeout" | tail -15
subsection "Memory Events (7 Days)"
log show --predicate 'eventMessage contains "memory pressure" OR eventMessage contains "jettisoned"' \
  --last 7d 2>/dev/null | grep -v "^Filtering" | tail -15

# SECTION 14 โ€” DIAGNOSTIC SUMMARY & RECOMMENDATIONS
section "14. DIAGNOSTIC SUMMARY & RECOMMENDATIONS"
echo ""; echo "โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”"
echo "โ”‚                    FINDINGS SUMMARY                             โ”‚"
echo "โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜"; echo ""
ISSUES=0
if fdesetup status 2>/dev/null | grep -q "On"; then
  echo "๐Ÿ”ด [HIGH]   FileVault ENABLED"; echo "           โ†’ sudo fdesetup disable"; ISSUES=$((ISSUES+1)); fi
if [ "$PANIC_COUNT" -gt 2 ]; then
  echo "๐Ÿ”ด [HIGH]   $PANIC_COUNT kernel panics"; echo "           โ†’ Book Apple Genius Bar"; ISSUES=$((ISSUES+1)); fi
if [ "$SOCD_COUNT" -gt 0 ] 2>/dev/null; then
  echo "๐Ÿ”ด [HIGH]   SOCD/AP Watchdog events ($SOCD_COUNT)"; echo "           โ†’ Apple hardware repair likely needed"; ISSUES=$((ISSUES+1)); fi
if [ -d "/Applications/Docker.app" ]; then
  echo "๐ŸŸก [MED]    Docker Desktop installed"; echo "           โ†’ Quit Docker, test for 48hrs"; ISSUES=$((ISSUES+1)); fi
if [ "$USB_DRIVES" -gt 0 ] 2>/dev/null; then
  echo "๐ŸŸก [MED]    External USB storage connected"; echo "           โ†’ Disconnect and monitor for 1 week"; ISSUES=$((ISSUES+1)); fi
if mount 2>/dev/null | grep -qE "smb|afp|nfs"; then
  echo "๐ŸŸก [MED]    SMB/NFS shares mounted"; echo "           โ†’ sudo umount -A"; ISSUES=$((ISSUES+1)); fi
if csrutil status 2>/dev/null | grep -q "disabled"; then
  echo "๐Ÿ”ด [HIGH]   SIP DISABLED"; echo "           โ†’ Re-enable in Recovery โ†’ csrutil enable"; ISSUES=$((ISSUES+1)); fi
if [ "$DISK_USAGE" -gt 90 ] 2>/dev/null; then
  echo "๐Ÿ”ด [HIGH]   Disk usage critical (${DISK_USAGE}%)"; echo "           โ†’ Free up space immediately"; ISSUES=$((ISSUES+1)); fi
echo ""
if [ "$ISSUES" -eq 0 ]; then
  echo "โœ… No major issues detected. If crashes persist, book Apple repair."
else
  echo "๐Ÿ“Š Issues found: $ISSUES"; echo ""
  echo "๐Ÿ”ง ACTION PLAN:"
  echo "   1. Disable FileVault if enabled"
  echo "   2. Disconnect all external devices"
  echo "   3. Quit/uninstall trigger apps (Docker, Xcode, VMs)"
  echo "   4. Unmount network shares"
  echo "   5. Monitor 1 week after each change"
  echo "   6. Still crashing โ†’ Apple Store with this report"; fi
echo ""; echo "๐Ÿ“ Report: $REPORT_FILE"; echo "๐Ÿ“ Desktop: $DESKTOP_COPY"
echo ""; echo "Report: $(date) | macOS: $(sw_vers -productVersion) | Host: $HOSTNAME | User: $CURRENT_USER"

} 2>&1 | tee "$REPORT_FILE"

# โ”€โ”€ COPY TO DESKTOP โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
cp "$REPORT_FILE" "$DESKTOP_COPY"
chown "$CURRENT_USER" "$DESKTOP_COPY"

# โ”€โ”€ COMPRESS REPORT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
ZIP_FILE="/Users/$CURRENT_USER/Desktop/MacDiagnostic_${HOSTNAME}_${TIMESTAMP}.zip"
zip -j "$ZIP_FILE" "$REPORT_FILE" 2>/dev/null
chown "$CURRENT_USER" "$ZIP_FILE"

# โ”€โ”€ JAMF RECON โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
jamf recon 2>/dev/null

# โ”€โ”€ NOTIFY USER โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
osascript <<EOF
display dialog "โœ… Advanced Diagnostic Complete!

๐Ÿ“„ Report saved to your Desktop:
$(basename $DESKTOP_COPY)

๐Ÿ“ฆ Compressed ZIP also saved:
$(basename $ZIP_FILE)

Please send the ZIP file to your IT Support team." \
buttons {"Open Desktop", "OK"} default button "Open Desktop" \
with title "Mac Diagnostic Report" with icon note
if result = {button returned:"Open Desktop"} then
  tell application "Finder" to open folder "Desktop" of home
end if
EOF

exit 0