Skip to main content

Full macOS Model name to Inventory (Custom Field)

Description

Need to know the full name of "Retina, 15-inch, Late 2013)" rather than the Model Identifier "MacBookPro11,3".  The provided script will look up the name and write it to inventory as a custom field

If necessary, please view the following for details on creating Custom Fields.

Information

Since the introduction of Apple's new randomized serial numbers, the method of using Apple's online lookup service does not work with these devices.  However, all modern devices have a store of a product name locally on the device.  The below method will check for the existence of a local name, but if not found, will query Apple instead based upon the Serial Number of the device

Note, that the name stored locally may differ slightly from the one provided by Apple's lookup server.  To give an indication of the difference in details see the below table (sometimes they will match):

Examples:

  
Name as indicated by Apple's servers and About This MacName as stored in local file
MacBook Pro (13-inch, M1, 2020)MacBook Pro (13-inch, M1, 2020)
MacBook Pro (Retina, 15-inch, Mid 2015)15" MacBook Pro with Retina display (Mid 2015)
iMac (21.5-inch, Late 2009)iMac Intel Core 2 Duo (widescreen, Late 2009)
Mac mini (Late 2012)Mac mini (Late 2012)

Virtual Devices

Virtual machines do not have legitimate Apple serial numbers by default and you may use virtual machines with the FileWave client. Since the serial number is used to determine the macOS model, additionally the script has been designed to allow for machines built using VMware.  Similar consideration could be taken for devices built with other viritualisation software: e.g. Parallels, VirtualBox, etc.

Script

Although this uses a local file, for older hardware information may be missing.  In this instance it will attempt to pull the information directly from Apple:

#!/bin/zsh
  
mac_model=$(sysctl -n hw.model)
  
if [[ "$mac_model" =~ ^"VMware" ]]
then
        echo "$mac_model"
        exit 0
fi
  
# File that stores device information.  Old models may not have this file.  Additionally some models only have a description
# Information is not exactly the same as that reported through About This Mac, but is similar enough to suffice in most instances
apple_locale=$(defaults read /Library/Preferences/.GlobalPreferences.plist AppleLocale)
attr_file="/System/Library/PrivateFrameworks/ServerInformation.framework/Versions/A/Resources/${apple_locale}.lproj/SIMachineAttributes.plist"
  
if [ -e "$attr_file" ]
then
 
    # Use marketingModel if available
        model_name=$(/usr/libexec/PlistBuddy -c "Print :${mac_model}:_LOCALIZABLE_:marketingModel" "$attr_file" 2>/dev/null)

    # If not found, use description if available
        if [ -z $model_name ]
        then
                model_name=$(/usr/libexec/PlistBuddy -c "Print :${mac_model}:_LOCALIZABLE_:description" "$attr_file" 2>/dev/null)
        fi
fi

# If not found in plist check ioreg.  Apple seemed to have stopped populating the plist file, but do populate ioreg data now
if [ -z "$model_name" ]
then        
    model_name=$(ioreg -c IOPlatformDevice | awk -F "\"" '/product-name/ || /product-description/ {print $(NF-1); exit}')
fi
 
# If still not found, try to get the details from Apple
if [ -z "$model_name" ]
then
    # Redirect standard error as macOS 10.10.x has an unfixed bug with system_profiler
    serial_number=$(ioreg -l | awk -F "\"" '/IOPlatformSerialNumber/ {print $(NF-1)}')

    # Get serial number length, note wc includes new line character
    # For serials of 11 characters, last 3 digits of serial required
    # For serials of 12 characters, last 4 digits of serial required
    serial_number_length=$(echo $serial_number | wc -c)

    # wc also adds empty spaces
    case $serial_number_length in
  
        *"13"*)
            serial_number=$(echo $serial_number | awk '{print substr( $NF, length($NF) - 3, length($NF) ) }')
            ;;
        *"12"*)
            serial_number=$(echo $serial_number | awk '{print substr( $NF, length($NF) - 2, length($NF) ) }')
            ;;
        *)
            echo "$mac_model"
            exit 0
            ;;
    esac

    model_name=$(curl -s https://support-sp.apple.com/sp/product\?cc=$serial_number | sed 's|.*<configCode>\(.*\)</configCode>.*|\1|')

    # If this still fails, just return the hardware model details
    if [[ "$model_name" =~ "error" ]]
    then
        model_name="$mac_model"
    fi
fi

if [ -z $model_name ]
then
    echo "$mac_model"
else
    echo "$model_name"
fi
 
exit 0