Hi Jamf Team,
I am encountering an issue with a script that I am using in a Jamf extension attribute. The script is not returning output always “No_Certificate_Found” when processed through Jamf. I need assistance to validate the issue and understand why it is not picking up the results properly.
When I trigger an inventory update through Jamf's built-in functun, no results are returned. However, when I manually run the command via Jamf using “sudo jamf recon”, I am able to retrieve the expected results. Similarly, the script works when executed via Self Service.
It seems that the script is not functioning properly when built in inventory option is enabled and not running as user in Jamf. Could you please assit this issue? I have attached the script.
Thank you for your assistance.
#!/bin/bash
# Expiry Date | Certificate Name | SHA-256 Hash | Keychain Path
#20-Jan-2024 | Manikandan R | 40C6326E5B3458F07A1D2E4DDBEF59728A425C92612FA022263C73BA51FEB8E | "/Users/test/Library/Keychains/login.keychain-db" |test
#20-Jan-2024 | Manikandan R | B6E53632BDC2A20670CEAF2DCA9FFE92BE130DF100D6B3777646D6541921745 | "/Users/test/Library/Keychains/login.keychain-db" |test
# Output file
output_file="/Users/Shared/expired_certificates_info.txt"
sorted_file="/Users/Shared/sorted_expired_certificates_info.txt"
# Ensure the directory and output files have proper permissions for all users
chmod 777 /Users/Shared
touch "$output_file" "$sorted_file"
chmod 666 "$output_file" "$sorted_file"
# Create or clear the output file and add the header
> "$output_file"
# Current date for comparison
current_date=$(date +"%Y-%m-%d")
# Use security command to find all certificates and process each one
# Function to process certificates in a given keychain
process_certificates_in_keychain() {
local keychain="$1"
local user_home="$2"
# Extract certificates using security command
sudo -u "$user_home" /usr/bin/security find-certificate -a -Z "$keychain" | while IFS= read -r line; do
# Extract the SHA-256 hash
if [[ $line == *"SHA-256 hash:"* ]]; then
sha256=$(echo "$line" | awk '{print $3}')
fi
# Extract the certificate name
if [[ $line == *"alis"* ]]; then
cert_name=$(echo "$line" | sed 's/.*"alis"<blob>="\\([^"]*\\)".*/\\1/')
fi
# Extract the keychain path
if [[ $line == *"keychain"* ]]; then
keychain_path=$(echo "$line" | awk -F' ' '{print $NF}')
fi
# Once we have both the SHA-256 hash and certificate name, fetch the expiry date
if [[ -n $cert_name && -n $sha256 ]]; then
expiry_date=$(/usr/bin/security find-certificate -a -c "$cert_name" -p -Z | \\
sed -n 'H; /^SHA-256/h; ${g;p;}' | \\
/usr/bin/openssl x509 -noout -enddate 2>/dev/null | \\
cut -f2 -d= | xargs -I {} sh -c 'if [ -n "{}" ]; then date -jf "%b %e %T %Y %Z" "{}" +"%Y-%m-%d"; fi')
# Only print if all information is found and if the certificate is expired
if [[ -n $expiry_date && "$expiry_date" < "$current_date" ]]; then
# Format expiry date to DD-MMM-YYYY
formatted_expiry_date=$(date -jf "%Y-%m-%d" "$expiry_date" +"%d-%b-%Y")
echo "$formatted_expiry_date | $cert_name | $sha256 | $keychain_path |$user_home" >> "$output_file"
fi
# Reset variables for the next certificate
expiry_date=""
cert_name=""
sha256=""
keychain_path=""
fi
done
}
# Get all users with a home directory on the system and UID greater than 500
user_list=$(dscl . list /Users | grep -v '_')
# Process certificates for each user
for user in $user_list; do
# Get the UID of the user
user_uid=$(dscl . -read /Users/"$user" UniqueID | awk '{print $2}')
# Check if the UID is greater than 500
if [ "$user_uid" -gt 500 ]; then
# Get the user's home directory
user_home=$(dscl . read /Users/"$user" NFSHomeDirectory | cut -d ' ' -f 2)
# Get the list of keychains for the user
keychains=($(sudo -u "$user" security list-keychains | tr -d '"' | tr ' ' '\\n'))
# Process each keychain for certificates
for keychain in "${keychains[@]}"; do
process_certificates_in_keychain "$keychain" "$user"
done
fi
done
# Sort the output file by expiry date (low to high) and save to a temporary file
sort -t '|' -k 1 "$output_file" > "$sorted_file"
# Replace the original output file with the sorted file
mv "$sorted_file" "$output_file"
output=$(cat "$output_file")
# Check if the output file is empty
if [[ -s "$output_file" ]]; then
# Display output
echo "<result>$output</result>"
else
echo "<result>No_Certificate_Found</result>"
fi