Or, Jamf Pro Extension Attributes for Sophos Endpoint’s “Real Time Scanning > Files” as referenced by Palo Alto GlobalProtect’s “HIP Objects > Real Time Protection”
Background
While adding a new Network Access Controls section to William Smith’s excellent Computer Information script, I was deflated to learn that my current Jamf Pro Extension Attribute for Sophos Endpoint wasn’t looking at the same data point as Palo Alto GlobalProtect’s “HIP Objects > Real Time Protection.”

Jamf Pro Extension Attributes
com.sophos.scan
My first attempt was to determine the status of com.sophos.scan:
#!/usr/bin/env bash
##########################################################################
# A script to collect the process state of Sophos Endpoint. #
# If Sophos Endpoint is not installed, "Not Installed" will be returned. #
##########################################################################
RESULT="Not Installed"
if [[ -d /Applications/Sophos/Sophos\ Endpoint.app ]]; then
sophosScanAgentName=$( /bin/launchctl list | /usr/bin/awk '/com.sophos.scan/{ print $3}' )
if [[ -z "${sophosScanAgentName}" ]]; then
RESULT="Not Found"
else
RESULT=$( /bin/launchctl print system/${sophosScanAgentName} | /usr/bin/awk '/state/{ print $3}' )
fi
fi
/bin/echo "<result>${RESULT}</result>"
This worked well, until I discovered older versions of macOS didn’t include com.sophos.scan.
com.sophos.common.servicemanager
After confirming with Sophos Support that com.sophos.common.servicemanager is common among all OSes we’re running, I re-wrote the EA:
#!/usr/bin/env bash
##########################################################################
# A script to collect the process state of Sophos Endpoint. #
# If Sophos Endpoint is not installed, "Not Installed" will be returned. #
##########################################################################
RESULT="Not Installed"
if [[ -d /Applications/Sophos/Sophos\ Endpoint.app ]]; then
sophosProcessName=$( /bin/launchctl list | /usr/bin/awk '/com.sophos.common.servicemanager/{ print $3}' )
if [[ -z "${sophosProcessName}" ]]; then
RESULT="Not Found"
else
RESULT=$( /bin/launchctl print system/${sophosProcessName} | /usr/bin/awk '/state/{ print $3}' )
fi
fi
/bin/echo "<result>${RESULT}</result>"
OnAccessRunning
After contacting Sophos Support again to inform them that GlobalProtect was looking somewhere else, they pointed me in the direction of their various .PLISTs.
#!/usr/bin/env bash
####################################################################################
# A script to collect the state of Sophos Endpoint's "Real Time Scanning > Files". #
# If Sophos Endpoint is not installed, "Not Installed" will be returned. #
# If "Real Time Scanning > Files" is disabled, "Disabled" will be returned. #
####################################################################################
RESULT="Not Installed"
if [[ -d /Applications/Sophos/Sophos\ Endpoint.app ]]; then
if [[ -f /Library/Preferences/com.sophos.sav.plist ]]; then
sophosOnAccessRunning=$( /usr/bin/defaults read /Library/Preferences/com.sophos.sav.plist OnAccessRunning )
case ${sophosOnAccessRunning} in
"0" ) RESULT="Disabled" ;;
"1" ) RESULT="Enabled" ;;
* ) RESULT="Unknown" ;;
esac
else
RESULT="Not Found"
fi
fi
/bin/echo "<result>${RESULT}</result>"
Computer Information Snippets
Here are a few of the related snippets we’re using in our Computer Information script:
Variables
####################################################################################################
#
# Variables
#
####################################################################################################
loggedInUser=$( /bin/echo "show State:/Users/ConsoleUser" | /usr/sbin/scutil | /usr/bin/awk '/Name :/ && ! /loginwindow/ { print $3 }' )
GlobalProtect Status
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Determine the status of GlobalProtect
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function GlobalProtectStatusCheck (){
appResult="Not Installed"
userResult="${loggedInUser} not logged-in"
globalProtectDisabled="Disabled"
if [[ -d /Applications/GlobalProtect.app ]]; then # GlobalProtect.app found in /Applications
# Read GlobalProtect's version number
appResult=$( /usr/bin/defaults read /Applications/GlobalProtect.app/Contents/Info.plist CFBundleShortVersionString )
appResult="GlobalProtect ${appResult} installed"
# Read `disable-globalprotect` value
globalProtectDisabledStatus=$( /usr/libexec/PlistBuddy -c "print :Palo\ Alto\ Networks:GlobalProtect:PanGPS:disable-globalprotect" /Library/Preferences/com.paloaltonetworks.GlobalProtect.settings.plist )
case "${globalProtectDisabledStatus}" in
0 ) globalProtectDisabled="GlobalProtect enabled" ;;
1 ) globalProtectDisabled="GlobalProtect disabled" ;;
* ) globalProtectDisabled="GlobalProtect status unknown" ;;
esac
# Read the logged-in user's `User`
userResult=$( /usr/bin/defaults read /Users/${loggedInUser}/Library/Preferences/com.paloaltonetworks.GlobalProtect.client User 2>&1 )
if [[ "${userResult}" == *"Does Not Exist" || -z "${userResult}" ]]; then
userResult="${loggedInUser} NOT logged-in to GlobalProtect"
elif [[ ! -z "${userResult}" ]]; then
userResult="${loggedInUser} logged-in to GlobalProtect"
fi
# Read `Portal`
companyPortal=$( /usr/libexec/PlistBuddy -c "print :Palo\ Alto\ Networks:GlobalProtect:PanSetup:Portal" /Library/Preferences/com.paloaltonetworks.GlobalProtect.settings.plist )
# Read `default-gateway-name`
gatewayResult=$( /usr/libexec/PlistBuddy -c "print :${companyPortal}:default-gateway-name" /Users/${loggedInUser}/Library/Preferences/com.paloaltonetworks.GlobalProtect.client.plist 2>&1 )
if [[ "${gatewayResult}" == *"Does Not Exist" ]]; then
gatewayResult="No default gateway specified"
elif [[ ! -z "${gatewayResult}" ]]; then
gatewayResult="${loggedInUser} selected ${gatewayResult} as default gateway"
fi
else # GlobalProtect.app NOT found in /Applications; clear other variables
userResult=""
globalProtectDisabled=""
gatewayResult=""
fi
}
Sophos Endpoint Status
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Determine the status of Sophos Endpoint
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function SophosEndpointStatusCheck (){
sophosEndpointStatus="Not Installed"
if [[ -d /Applications/Sophos/Sophos\ Endpoint.app ]]; then
if [[ -f /Library/Preferences/com.sophos.sav.plist ]]; then
sophosOnAccessRunning=$( /usr/bin/defaults read /Library/Preferences/com.sophos.sav.plist OnAccessRunning )
case ${sophosOnAccessRunning} in
"0" ) sophosEndpointStatus="Disabled" ;;
"1" ) sophosEndpointStatus="Enabled" ;;
* ) sophosEndpointStatus="Unknown" ;;
esac
else
sophosEndpointStatus="Not Found"
fi
fi
}
Cisco AnyConnect / Palo Alto Global Protect VPN IPs
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Test for VPN Clients and IP addresses
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function vpnIP(){
anyConnectTest="/opt/cisco/anyconnect/bin/vpn" # Cisco binary
globalProtectTest="/Applications/GlobalProtect.app" # GlobalProtect app
###
# Cisco AnyConnect
###
if [ -f "${anyConnectTest}" ] ; then
# Cisco AnyConnect installed; read current IP Address
anyConnectIP=$( /opt/cisco/anyconnect/bin/vpn stats | grep "Client Address (IPv4):" | awk '{print $4}' )
if [ "${anyConnectIP}" = "Not" ]; then
# IP address is blank, report no connection
anyConnectStatus="AnyConnect IP: Inactive"
else
# IP address is *not* blank, report the IP address
anyConnectStatus="AnyConnect IP: ${anyConnectIP}"
fi
else
# Cisco AnyConnect is not installed
anyConnectStatus="AnyConnect is NOT installed"
fi
###
# Palo Alto Networks GlobalProtect
# Thanks, @franton!
###
if [ -d "${globalProtectTest}" ] ; then
# Palo Alto Networks GlobalProtect installed; read current IP Address
interface=$( ifconfig | grep -B1 "10." | awk '{ print $1 }' | head -1 )
if [ -z "$interface" ]; then
globalProtectStatus="GlobalProtect: Inactive"
else
globalProtectIP=$( ifconfig | grep -A2 -E "${interface}" | grep inet | awk '{ print $2 }' )
globalProtectStatus="GlobalProtect: ${globalProtectIP}"
fi
else
# Palo Alto Networks GlobalProtect is not installed
globalProtectStatus="GlobalProtect is NOT installed"
fi
ScriptLog "$anyConnectStatus"
ScriptLog "$globalProtectStatus"
}
Time Machine
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Time Machine
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
tmDestinationInfo=$( /usr/bin/tmutil destinationinfo )
if [[ "${tmDestinationInfo}" == *"No destinations configured"* ]]; then
tmStatus="No destination configured"
else
runCommand=$( /usr/bin/tmutil destinationinfo | /usr/bin/grep "Name" | /usr/bin/awk -F ':' '{print $NF}' )
tmStatus="Destination: $runCommand"
fi
if [[ "${tmDestinationInfo}" == *"No destinations configured"* ]]; then
tmLastBackup="Latest Backup: N/A"
else
runCommand=$( /usr/bin/tmutil latestbackup | /usr/bin/awk -F "/" '{print $NF}' )
if [[ -z $runCommand ]]; then
tmLastBackup="Latest Backup: Unknown; connect destination"
else
tmLastBackup="Latest Backup: $runCommand"
fi
fi