From d45f98db7ffbedc054b3727ea3af62f4f4c23f18 Mon Sep 17 00:00:00 2001 From: Andrew Barnett <138056529+AndrewMBarnett@users.noreply.github.com> Date: Wed, 24 Jun 2026 16:10:55 -0500 Subject: [PATCH] Add deferral tracking to available updates EA and add last update check time EA Updated apps-with-available-updates (.sh and .xml) to include deferrals remaining per app, || continue error handling in the loop, a post-loop empty array guard, and printf instead of echo -e for output Added new apps-last-update-check-time extension attribute (.sh and .xml) that returns the last time Alectrona Patch ran an update check, formatted as local time --- .../apps-last-update-check-time.sh | 30 ++++++ .../apps-last-update-check-time.xml | 35 +++++++ .../apps-with-available-updates.sh | 22 +++-- .../apps-with-available-updates.xml | 94 ++++++++++--------- 4 files changed, 131 insertions(+), 50 deletions(-) create mode 100644 Extension-Attributes/apps-last-update-check-time.sh create mode 100644 Extension-Attributes/apps-last-update-check-time.xml diff --git a/Extension-Attributes/apps-last-update-check-time.sh b/Extension-Attributes/apps-last-update-check-time.sh new file mode 100644 index 0000000..6366410 --- /dev/null +++ b/Extension-Attributes/apps-last-update-check-time.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Last Update Check +# +# This attribute returns the last time Alectrona Patch ran an update check. +# +# Exit if Alectrona Patch is not installed +if [[ ! -e /Library/Application\ Support/Alectrona/Patch/patch ]]; then + exit 1 +fi + +# Generate the report +report=$(/Library/Application\ Support/Alectrona/Patch/patch report --updatable 2>/dev/null) +if [[ -z "$report" ]]; then + echo "No report available" + exit 0 +fi + +# Extract the last update check timestamp +lastCheck=$(echo "$report" | /usr/bin/plutil -extract patchInfo.lastUpdateTaskRun raw -o - -) || { + echo "Unknown" + exit 0 +} + +epoch=$(date -j -u -f "%Y-%m-%dT%H:%M:%SZ" "$lastCheck" "+%s") +localTime=$(date -r "$epoch" "+%Y-%m-%d %H:%M:%S %Z") + +echo "$localTime" + +exit 0 diff --git a/Extension-Attributes/apps-last-update-check-time.xml b/Extension-Attributes/apps-last-update-check-time.xml new file mode 100644 index 0000000..60bb513 --- /dev/null +++ b/Extension-Attributes/apps-last-update-check-time.xml @@ -0,0 +1,35 @@ + +Apps Last Update Check Time +This attribute returns the last time Alectrona Patch ran an update check. +string +#!/bin/bash + +# Last Update Check +# +# This attribute returns the last time Alectrona Patch ran an update check. +# +# Exit if Alectrona Patch is not installed +if [[ ! -e /Library/Application\ Support/Alectrona/Patch/patch ]]; then + exit 1 +fi + +# Generate the report +report=$(/Library/Application\ Support/Alectrona/Patch/patch report --updatable 2>/dev/null) +if [[ -z "$report" ]]; then + echo "<result>No report available</result>" + exit 0 +fi + +# Extract the last update check timestamp +lastCheck=$(echo "$report" | /usr/bin/plutil -extract patchInfo.lastUpdateTaskRun raw -o - -) || { + echo "<result>Unknown</result>" + exit 0 +} + +epoch=$(date -j -u -f "%Y-%m-%dT%H:%M:%SZ" "$lastCheck" "+%s") +localTime=$(date -r "$epoch" "+%Y-%m-%d %H:%M:%S %Z") + +echo "<result>$localTime</result>" + +exit 0 + diff --git a/Extension-Attributes/apps-with-available-updates.sh b/Extension-Attributes/apps-with-available-updates.sh index 0a066d0..6757b8c 100644 --- a/Extension-Attributes/apps-with-available-updates.sh +++ b/Extension-Attributes/apps-with-available-updates.sh @@ -1,9 +1,9 @@ #!/bin/bash # Apps With Available Updates - +# # This attribute returns all installed apps that are updatable (out-of-date) using Alectrona Patch. - +# # Exit if Alectrona Patch is not installed if [[ ! -e /Library/Application\ Support/Alectrona/Patch/patch ]]; then exit 1 @@ -27,18 +27,26 @@ fi # Loop through the appInventory array and build the result for ((index=0; index/dev/null) || deferralCount=0 + deferralsRemaining=$(( deferralLimit - deferralCount )) # Add the app to the array - updatableApps+=("ID: $appID\nInstalled Version: $installedVersion\nAvailable Version: $targetVersion\n") + updatableApps+=("ID: $appID"$'\n'"Installed Version: $installedVersion"$'\n'"Available Version: $targetVersion"$'\n'"Deferrals Remaining: $deferralsRemaining"$'\n') done # Join array elements with newlines +if [[ "${#updatableApps[@]}" -eq 0 ]]; then + echo "No updatable apps" + exit 0 +fi + result=$(printf "%s\n" "${updatableApps[@]}") # Return the result -echo -e "$result" +printf "%b\n" "$result" exit 0 \ No newline at end of file diff --git a/Extension-Attributes/apps-with-available-updates.xml b/Extension-Attributes/apps-with-available-updates.xml index 42c4cf6..f366ec6 100644 --- a/Extension-Attributes/apps-with-available-updates.xml +++ b/Extension-Attributes/apps-with-available-updates.xml @@ -2,48 +2,56 @@ Apps With Available Updates This attribute returns all installed apps that are updatable (out-of-date) using Alectrona Patch. string -#!/bin/bash - -# Apps With Available Updates - -# This attribute returns all installed apps that are updatable (out-of-date) using Alectrona Patch. - -# Exit if Alectrona Patch is not installed -if [[ ! -e /Library/Application\ Support/Alectrona/Patch/patch ]]; then - exit 1 -fi - -# Generate the report -report=$(/Library/Application\ Support/Alectrona/Patch/patch report --updatable 2>/dev/null) -if [[ -z "$report" ]]; then - echo "<result>No updatable apps</result>" - exit 0 -fi - -# Get the length of the appInventory array -length=$(echo "$report" | /usr/bin/plutil -extract appInventory raw -o - -) -updatableApps=() - -if [[ "$length" -eq 0 ]]; then - echo "<result>No updatable apps</result>" - exit 0 -fi - -# Loop through the appInventory array and build the result -for ((index=0; index<length; index++)); do - appID=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.id raw -o - -) - installedVersion=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.version raw -o - -) - targetVersion=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.targetVersion raw -o - -) - - # Add the app to the array - updatableApps+=("ID: $appID\nInstalled Version: $installedVersion\nAvailable Version: $targetVersion\n") -done - -# Join array elements with newlines -result=$(printf "%s\n" "${updatableApps[@]}") - -# Return the result -echo -e "<result>$result</result>" - +#!/bin/bash + +# Apps With Available Updates +# +# This attribute returns all installed apps that are updatable (out-of-date) using Alectrona Patch. +# +# Exit if Alectrona Patch is not installed +if [[ ! -e /Library/Application\ Support/Alectrona/Patch/patch ]]; then + exit 1 +fi + +# Generate the report +report=$(/Library/Application\ Support/Alectrona/Patch/patch report --updatable 2>/dev/null) +if [[ -z "$report" ]]; then + echo "<result>No updatable apps</result>" + exit 0 +fi + +# Get the length of the appInventory array +length=$(echo "$report" | /usr/bin/plutil -extract appInventory raw -o - -) +updatableApps=() + +if [[ "$length" -eq 0 ]]; then + echo "<result>No updatable apps</result>" + exit 0 +fi + +# Loop through the appInventory array and build the result +for ((index=0; index<length; index++)); do + appID=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.id raw -o - -) || continue + installedVersion=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.version raw -o - -) || continue + targetVersion=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.targetVersion raw -o - -) || continue + deferralLimit=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.deferralLimit raw -o - -) || continue + deferralCount=$(echo "$report" | /usr/bin/plutil -extract appInventory.$index.deferralCount raw -o - - 2>/dev/null) || deferralCount=0 + deferralsRemaining=$(( deferralLimit - deferralCount )) + + # Add the app to the array + updatableApps+=("ID: $appID"$'\n'"Installed Version: $installedVersion"$'\n'"Available Version: $targetVersion"$'\n'"Deferrals Remaining: $deferralsRemaining"$'\n') +done + +# Join array elements with newlines +if [[ "${#updatableApps[@]}" -eq 0 ]]; then + echo "<result>No updatable apps</result>" + exit 0 +fi + +result=$(printf "%s\n" "${updatableApps[@]}") + +# Return the result +printf "<result>%b</result>\n" "$result" + exit 0