a week ago
Greetings Jamf Nation!
I have been woking on a more comprehensive Falcon repair script to assist in detecting and/or trying to repair any potential issues found in the sensors. This is strictly a WIP and I would love to get everyone's feedback on ideas or items that I might have missed. This script is borrowing heavily from Dan K Snelson, so kudos for him creating the original concept...I just want to take it a "one step further"...
#!/bin/zsh
#
# Written by: Scott Kendall
# Date Created: 01/21/2025
# Date Last Revised: 01/23/2025
#
# Borrowed heavily from @snelson: source code @ https://snelson.us/2023/03/crowdstrike-falcon-kickstart-0-0-2/
#
######################################################################################################
#
# Gobal "Common" variables (do not change these!)
#
######################################################################################################
export PATH=/usr/bin:/usr/local/bin:/bin:/usr/sbin:/sbin
SUPPORT_DIR="<your support log folder>"
LOG_DIR="${SUPPORT_DIR}/logs"
LOG_FILE="${LOG_DIR}/FalcanSensor.log"
LOG_STAMP=$(echo $(/bin/date +%Y%m%d))
falconBinary="/Applications/Falcon.app/Contents/Resources/falconctl"
falcanJAMFtrigger="crowdstrike"
exitCode="0"
####################################################################################################
#
# Functions
#
####################################################################################################
function create_log_directory ()
{
# Ensure that the log directory and the log files exist. If they
# do not then create them and set the permissions.
#
# RETURN: None
# If the log directory doesnt exist - create it and set the permissions
[[ ! -d "${LOG_DIR}" ]] && /bin/mkdir -p "${LOG_DIR}"
/bin/chmod 755 "${LOG_DIR}"
# If the log file does not exist - create it and set the permissions
[[ ! -f "${LOG_FILE}" ]] && /usr/bin/touch "${LOG_FILE}"
/bin/chmod 644 "${LOG_FILE}"
}
function logMe ()
{
# Basic two pronged logging function that will log like this:
#
# 20231204 12:00:00: Some message here
#
# This function logs both to STDOUT/STDERR and a file
# The log file is set by the $LOG_FILE variable.
#
# RETURN: None
echo "${1}" 1>&2
echo "$(/bin/date '+%Y-%m-%d %H:%M:%S'): ${1}" | tee -a "${LOG_FILE}"
}
function preflight_check ()
{
# Pre-flight Check: Confirm script is running as root
[[ $(id -u) -ne 0 ]] && {logMe "PRE-FLIGHT CHECK: This script must be run as root; exiting."; exit 1}
# Pre-flight Check: Confirm CrowdStrike Falcon System Extension is running
systemExtensionTest=$( systemextensionsctl list | grep -o "com.crowdstrike.falcon.Agent.*" | cut -f2- -d" " )
if [[ -n "${systemExtensionTest}" ]]; then
systemExtensionStatus="${systemExtensionTest}"
else
systemExtensionStatus="Not Found"
logMe "Falcon not installed: Loading policy from JAMF"
fi
logMe "CrowdStrike Falcon System Extension Status: ${systemExtensionStatus}"
###################################################
# Pre-flight Check: Complete
###################################################
logMe "PRE-FLIGHT CHECK: Complete"
}
function log_sensor_updates()
{
logMe "Falcon Sensor Operational: ${1}"
logMe "Updating inventory …"
jamf recon
}
function connection_test()
{
test=$("nc -vz ts01-b.cloudsink.net 443")
[["${test}" == *"succedded!"* ]] && echo "true" || echo "false"
}
function load_sensor()
{
echo $( ${falconBinary} load --verbose)
}
function load_jamf_policy ()
{
jamf policy -trigger "${falcanJAMFtrigger}"
}
function get_agent_info ()
{
echo $( $falconBinary stats agent_info 2>&1 )
}
####################################################################################################
#
# Program
#
####################################################################################################
create_log_directory
preflight_check
exitCode="0"
###################################################
# Process CrowdStrike Falcon System Extension Status
###################################################
logMe "Processing System Extension Status …"
systemExtensionStatus=$(systemextensionsctl list | grep -o "com.crowdstrike.falcon.Agent.*" | cut -f2- -d" ")
# Check the extension status first and evaluate
case ${systemExtensionStatus} in
*"[activated enabled]"* )
logMe "CrowdStrike Falcon System Extension enabled"
logMe "Validating Sensor Operation …"
sensorOperationalStatus=$( get_agent_info ) #| awk '/Sensor operational:/{print $3}')
# check for specific issues in regards to the status
case ${sensorOperationalStatus:l} in
*"true"* )
# sensors are loaded and functioning correclty
log_sensor_updates "${sensorOperationalStatus}"
;;
*"sensor has not loaded."* | *"sensor is unknown."* | *"sensor is unloaded."* )
# Sensors are not loaded properly
sensorOperationalStatus=$( load_sensor)
logMe "Attempting to Load the Falcon Sensor"
log_sensor_updates "${sensorOperationalStatus}"
;;
*"not licensed"* )
# product is not licensed...perform a license command and then make sure that the sensors are loaded
logMe "Attempting to License the Falcon Sensor"
falconKickStartLicense=$( $falconBinary license "$( defaults read /Library/Managed\ Preferences/com.crowdstrike.falcon.plist ccid )" --noload --verbose)
log_sensor_updates "${falconKickStartLicense}"
logMe "Attempting to Load the Falcon Sensor"
sensorOperationalStatus=$( load_sensor)
log_sensor_updates "${sensorOperationalStatus}"
;;
esac
;;
*"uninstall on reboot"* )
# It looks like a restart might be in order
logMe "The system needs to be restarted for the sensor to load properly"
exitCode="1"
;;
*"waiting for user"* )
# it appears that everything is working OK, but the user needs to start doing "something"
logMe "Falcon Sensor Status: ${sensorOperationalStatus}"
;;
"Not Found" )
# Crowdstrike not found, so lets try to remove any previous install and try to reinstall it
logMe "CrowdStrike Falcon System Extension NOT found: Attempting Re-installation"
falconKickStartUninstall=$( ${falconBinary} uninstall -verbose )
log_sensor_updates "${falconKickStartUninstall}"
logMe "Re-installing CrowdStrike Falcon …"
load_jamf_policy
exitCode="1"
;;
* )
# Catch all if we got a different error
logMe "Attempting to kickstart Falcon Sensor …"
falconKickStartLicense=$( ${falconBinary} license )
logMe "Falcon Kickstart License Result: ${falconKickStartLicense}"
falconKickStartLoad=$( load_sensor )
logMe "Falcon Kickstart Load Result: ${falconKickStartLoad}"
if [[ "${falconKickStartLoad}" == "Falcon sensor is loaded" ]]; then
sensorOperationalStatus=$( get_agent_info )
[[ "${sensorOperationalStatus}" == "true" ]] && logMe "Falcon Sensor Status: ${sensorOperationalStatus}"
else
exitCode="1"
fi
esac
logMe "Exit Code: ${exitCode}"
exit "${exitCode}"
a week ago
I used to do something similar where I had an extension attribute that reported an error and if there was an error it went to a smart group that triggered a policy to uninstall and reinstall. That fixed 90% of issues.
a week ago
Anyone looking to deploy, and or remove/remediate, CrowdStrike on Macs should really do themselves a favor and look at @franton's guide on scripting that process with the CS API :
https://richard-purves.com/2022/05/03/downloading-crowdstrike-via-api-for-fun-and-profit/
And the associated GitHub repo:
https://github.com/franton/Crowdstrike-API-Scripts?tab=readme-ov-file