#!/bin/bash # Parses Apple internal model numbers to the public device model parse_cfgutil_data() { local raw_data="$1" # cfgutil returns 2 items, device type and serial. This parses device type to model # and then macthes together the rows given by cfgutil to build output # This also replaces cfgutil error 604 with device in recovery/dfu mode since it is expected echo "$raw_data" | awk -F": " ' BEGIN { # Create the lookup dictionary before processing the text name["iPhone12,8"] = "iPhone SE (2nd generation)" name["iPhone13,1"] = "iPhone 12 mini" name["iPhone13,2"] = "iPhone 12" name["iPhone13,3"] = "iPhone 12 Pro" name["iPhone13,4"] = "iPhone 12 Pro Max" name["iPhone14,2"] = "iPhone 13 Pro" name["iPhone14,3"] = "iPhone 13 Pro Max" name["iPhone14,4"] = "iPhone 13 mini" name["iPhone14,5"] = "iPhone 13" name["iPhone14,6"] = "iPhone SE (3rd generation)" name["iPhone14,7"] = "iPhone 14" name["iPhone14,8"] = "iPhone 14 Plus" name["iPhone15,2"] = "iPhone 14 Pro" name["iPhone15,3"] = "iPhone 14 Pro Max" name["iPhone15,4"] = "iPhone 15" name["iPhone15,5"] = "iPhone 15 Plus" name["iPhone16,1"] = "iPhone 15 Pro" name["iPhone16,2"] = "iPhone 15 Pro Max" name["iPhone17,1"] = "iPhone 16 Pro" name["iPhone17,2"] = "iPhone 16 Pro Max" name["iPhone17,3"] = "iPhone 16" name["iPhone17,4"] = "iPhone 16 Plus" name["iPhone17,5"] = "iPhone 16e" name["iPhone18,1"] = "iPhone 17 Pro" name["iPhone18,2"] = "iPhone 17 Pro Max" name["iPhone18,3"] = "iPhone 17" name["iPhone18,4"] = "iPhone Air" name["iPhone18,5"] = "iPhone 17e" } /^deviceType:/ { section="type"; row=1; next } /^serialNumber:/ { section="serial"; row=1; next } /^$/ { next } section=="type" { internal_model = $NF # Check if the internal model exists in our dictionary if (internal_model in name) { models[row] = name[internal_model] } else { # Fallback to the raw ID if it is not in the list models[row] = internal_model } row++ } section=="serial" { if ($NF == "The device is not booted into the System. (ConfigurationUtilityKit.error 604)") { print "Model: " models[row] " | Serial: In Recovery/DFU Mode" } else { print "Model: " models[row] " | Serial: " $NF } row++ } ' } # This parses the device model from the extra inforamtion contained in the serial number entry in ioreg parse_ios_usb_row() { local raw_string="$1" local cpid="" local bdid="" local srnm="" local model="Unknown Device" # Extract CPID if [[ $raw_string =~ CPID:([0-9A-Fa-f]+) ]]; then cpid="${BASH_REMATCH[1]}" fi # Extract BDID if [[ $raw_string =~ BDID:([0-9A-Fa-f]+) ]]; then bdid="${BASH_REMATCH[1]}" fi # Extract SRNM if [[ $raw_string =~ SRNM:\[([A-Za-z0-9]+)\] ]]; then srnm="${BASH_REMATCH[1]}" fi # Mapping CPID & BDID to model if [[ -n "$cpid" && -n "$bdid" ]]; then case "${cpid}-${bdid}" in "8030-10"|"8030-14") model="iPhone SE (2nd Gen)" ;; "8030-01"|"8030-02") model="iPhone 11" ;; "8030-04") model="iPhone 11 Pro" ;; "8030-06") model="iPhone 11 Pro Max" ;; "8030-"*) model="Unknown A13 Device" ;; "8101-14"|"8101-16") model="iPhone 12 mini" ;; "8101-0C"|"8101-0E") model="iPhone 12" ;; "8101-10") model="iPhone 12 Pro" ;; "8101-12") model="iPhone 12 Pro Max" ;; "8101-"*) model="Unknown A14 Device" ;; "8110-10") model="iPhone SE (3rd Gen)" ;; "8110-14"|"8110-15") model="iPhone 13 mini" ;; "8110-16"|"8110-17") model="iPhone 13" ;; "8110-0A"|"8110-0B") model="iPhone 13 Pro" ;; "8110-0C"|"8110-0D") model="iPhone 13 Pro Max" ;; "8110-18") model="iPhone 14" ;; "8110-1A") model="iPhone 14 Plus" ;; "8110-"*) model="Unknown A15 Device" ;; "8120-0C") model="iPhone 14 Pro" ;; "8120-0E") model="iPhone 14 Pro Max" ;; "8120-08") model="iPhone 15" ;; "8120-0A") model="iPhone 15 Plus" ;; "8120-"*) model="Unknown A16 Device" ;; "8130-02") model="iPhone 15 Pro" ;; "8130-04") model="iPhone 15 Pro Max" ;; "8130-"*) model="Unknown A17 Pro Device" ;; "8140-08") model="iPhone 16" ;; "8140-0A") model="iPhone 16 Plus" ;; "8140-0C") model="iPhone 16 Pro" ;; "8140-0E") model="iPhone 16 Pro Max" ;; "8140-"*) model="Unknown A18 Device" ;; *) model="Unknown (${cpid}-${bdid})" ;; esac fi # Handling if no serial number was found if [[ -z "$srnm" ]]; then srnm="N/A" fi echo "Model: $model | Serial: $srnm" } CMD_NAME="cfgutil" HARDCODED_PATH="/Applications/Apple Configurator.app/Contents/MacOS/cfgutil" EXECUTABLE="" echo $'\nConnected non-recovery mode iOS devices\n-----------------------------------------' # Check if cfgutil is available if command -v "$CMD_NAME" >/dev/null 2>&1; then EXECUTABLE="$CMD_NAME" elif [ -f "$HARDCODED_PATH" ] && [ -x "$HARDCODED_PATH" ]; then EXECUTABLE="$HARDCODED_PATH" else echo "Unable to scan for non-recovery mode iOS devices!" echo "Error: Could not locate cfgutil, make sure Apple Configurator is installed" fi # Handle iOS non-recovery devices using cfgutil if [ -n "$EXECUTABLE" ]; then CFG_OUTPUT=$("$EXECUTABLE" -f get deviceType serialNumber 2>&1) # Handle no discovered devices if [[ "$CFG_OUTPUT" == *"cfgutil: error: no devices found"* ]]; then echo "No non-recovery mode iOS devices detected! Make sure passcode locked devices are unlocked." else FORMATTED_DEVICES=$(parse_cfgutil_data "$CFG_OUTPUT") if [ -n "$FORMATTED_DEVICES" ]; then echo "$FORMATTED_DEVICES" else echo "Devices detected, but they are in Recovery/DFU mode." fi fi fi echo $'\nConnected recovery mode iOS devices\n-----------------------------------------' # Handle iOS recovery mode devices DEVICES=$(ioreg -p IOUSB -n "Apple Mobile Device (Recovery Mode)" -l -r | grep "USB Serial Number") if [ -z "$DEVICES" ]; then echo "No connected recovery mode iOS devices" else while IFS= read -r row; do if [[ -z "$row" ]]; then continue fi parse_ios_usb_row "$row" done <<< "$DEVICES" fi echo $'\nConnected Android devices\n-----------------------------------------' # Handle Pixel devices ioreg -p IOUSB | grep -o "Pixel[^@]*" | while read -r device_name; do echo "Model: $device_name | Serial: $(ioreg -p IOUSB -n "$device_name" | grep "kUSBSerialNumberString" | awk -F\" '{print $4}')" done # Handle Samsung devices ioreg -p IOUSB -n "SAMSUNG_Android" -l -r | grep "kUSBSerialNumberString" | awk -F\" '{print "Model: Samsung | Serial: " $4}' # Handle Samsung Recovery mode ioreg -p IOUSB | grep -Eo "\bSM-[A-Z][0-9]{3}[A-Z0-9]{1,2}\b" | while read -r device_name; do echo "Model: Samsung | Serial: $(ioreg -p IOUSB -n "$device_name" -l -r | grep "kUSBSerialNumberString" | awk -F\" '{print $4}')" done echo ""