Menu Close

Recon at Reboot (1.0.1)

Creates a LaunchDaemon and a self-destructing Bash script to run a recon at next Reboot, after confirming your Jamf Pro server is available

Background

With surprising frequency, updating a computer’s inventory with the Jamf Pro server the next time a computer reboots can be quite handy. For example:

The self-destructing script below will create a LaunchDaemon and a client-side Bash script to run a recon at the next reboot, after confirming your Jamf Pro server is available.

Script Modifications

After making the following modifications, upload the script to your Jamf Pro server.

plistDomain Variable

Modify both occurrences of the plistDomain variable to match your organization’s Reverse Domain Name Notation, for example: org.churchofjesuschrist.

sleep (optional)

The script is set to make 10 attempts to check for a connection to your Jamf Pro server, pausing for 30 seconds after each attempt (for a total of 5 minutes); modify to your liking.

Script Execution (1 of 2)

The initial script execution is controlled by the Script payload in the various Jamf Pro policies to which you add the Recon at Reboot script.

Recon at Reboot script included in the macOS Monterey 12.5.1 (21G83) Install policy

The output of the initial script execution is similar to the following, which indicates the creation of both the LaunchDaemon — in the /Library/LaunchDaemons/ directory — and the self-destructing client-side script — in the /private/var/tmp/ directory.

Recon at Reboot (1.0.1)
Create the LaunchDaemon ...
Set LaunchDaemon file permissions ...
Create the script ...
Set script file permissions ...
Create Log File at /private/var/tmp/org.churchofjesuschrist.reconAtReboot.log ...
LaunchDaemon and Script created.

Script Execution (2 of 2)

The second (and final) script execution is controlled by the RunAtLoad LaunchDaemon.

While waiting to confirm connectivity to your Jamf Pro server, the log located in /private/var/tmp is similar to the following:

Created org.churchofjesuschrist.reconAtReboot.log on 2022-08-25-015120
Starting Recon at Reboot (1.0.1) at 2022-08-25-015322

After confirming your Jamf Pro server is available, inventory is updated and then both the client-side script and LaunchDaemon are removed; the log file remains in the /private/var/tmp directory for later inspection.

Created org.churchofjesuschrist.reconAtReboot.log on 2022-08-25-015120
Starting Recon at Reboot (1.0.1) at 2022-08-25-015322
Jamf Pro server is available, proceeding; 
Check for Jamf Pro server connection; Resuming Recon at Reboot; Updating inventory; Delete org.churchofjesuschrist.reconAtReboot.plist; Delete script; End-of-line.

Custom Trigger

We also have a Jamf Pro policy with a custom trigger of reconAtReboot set to Ongoing and scoped to All computers which we frequently leverage in various other scripts and policies.

Jamf Pro policy with custom Trigger

Script

Latest version available on GitHub.

#!/bin/bash
####################################################################################################
#
# ABOUT
#
#   Creates a self-destructing LaunchDaemon and script to run a Recon
#   at next Reboot (after confirming your Jamf Pro server is available)
#
####################################################################################################
#
# HISTORY
#
# Version 1.0.0, 10-Nov-2016, Dan K. Snelson (@dan-snelson)
#   Original version
#
# Version 1.0.1, 12-Aug-2022, Dan K. Snelson (@dan-snelson)
#   Added check for Jamf Pro server connection
#
####################################################################################################



####################################################################################################
#
# Variables
#
####################################################################################################

scriptVersion="1.0.1"
plistDomain="org.churchofjesuschrist"       # Hard-coded domain name
plistLabel="reconAtReboot"                  # Unique label for this plist
plistLabel="$plistDomain.$plistLabel"       # Prepend domain to label
timestamp=$( /bin/date '+%Y-%m-%d-%H%M%S' ) # Used in log file



####################################################################################################
#
# Program
#
####################################################################################################

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Logging preamble
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "Recon at Reboot (${scriptVersion})"



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Create launchd plist to call a shell script
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "Create the LaunchDaemon ..."

/bin/echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
    <dict>
        <key>Label</key>
        <string>${plistLabel}</string>
        <key>ProgramArguments</key>
        <array>
            <string>/bin/sh</string>
            <string>/private/var/tmp/reconAtReboot.bash</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
    </dict>
</plist>" > /Library/LaunchDaemons/$plistLabel.plist



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Set the permission on the file
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "Set LaunchDaemon file permissions ..."

/usr/sbin/chown root:wheel /Library/LaunchDaemons/$plistLabel.plist
/bin/chmod 644 /Library/LaunchDaemons/$plistLabel.plist
/bin/chmod +x /Library/LaunchDaemons/$plistLabel.plist



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Create reboot script
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "Create the script ..."

cat << '==endOfScript==' > /private/var/tmp/reconAtReboot.bash
#!/bin/bash
####################################################################################################
#
# ABOUT
#
#    Recon at Reboot
#
####################################################################################################
#
# HISTORY
#
# Version 1.0.0, 10-Nov-2016, Dan K. Snelson
#   Original version
#
# Version 1.0.1, 12-Aug-2022, Dan K. Snelson (@dan-snelson)
#   Added check for Jamf Pro server connection
#
####################################################################################################



####################################################################################################
#
# Variables
#
####################################################################################################

scriptVersion="1.0.1"
plistDomain="org.churchofjesuschrist"       # Hard-coded domain name
plistLabel="reconAtReboot"                  # Unique label for this plist
plistLabel="$plistDomain.$plistLabel"       # Prepend domain to label
timestamp=$( /bin/date '+%Y-%m-%d-%H%M%S' ) # Used in log file
scriptResult=""


####################################################################################################
#
# Functions
#
####################################################################################################

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Check for a Jamf Pro server connection
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

jssConnectionStatus () {

    scriptResult+="Check for Jamf Pro server connection; "

    unset jssStatus
    jssStatus=$( /usr/local/bin/jamf checkJSSConnection 2>&1 | /usr/bin/tr -d '\n' )

    case "${jssStatus}" in

        *"The JSS is available."        )   jssAvailable="yes" ;;
        *"No such file or directory"    )   jssAvailable="not installed" ;;
        *                               )   jssAvailable="unknown" ;;

    esac

}



####################################################################################################
#
# Program
#
####################################################################################################

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Logging preamble
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "Starting Recon at Reboot (${scriptVersion}) at $timestamp" >> /private/var/tmp/$plistLabel.log



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Hard-coded sleep of 25 seconds for auto-launched applications to start
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

sleep "25"



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Check for a Jamf Pro server connection
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

jssConnectionStatus

counter=1

until [[ "${jssAvailable}" == "yes" ]] || [[ "${counter}" -gt "10" ]]; do
    scriptResult+="Check ${counter} of 10: Jamf Pro server NOT reachable; waiting to re-check; "
    sleep "30"
    jssConnectionStatus
    ((counter++))
done



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# If Jamf Pro server is available, update inventory
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

if [[ "${jssAvailable}" == "yes" ]]; then

    echo "Jamf Pro server is available, proceeding; " >> /private/var/tmp/$plistLabel.log

    scriptResult+="Resuming Recon at Reboot; "

    scriptResult+="Updating inventory; "

    /usr/local/bin/jamf recon

else

    scriptResult+="Jamf Pro server is NOT available; exiting."

fi



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Delete launchd plist
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

scriptResult+="Delete $plistLabel.plist; "
/bin/rm -fv /Library/LaunchDaemons/$plistLabel.plist



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Delete script
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

scriptResult+="Delete script; "
/bin/rm -fv /private/var/tmp/reconAtReboot.bash



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Exit
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

scriptResult+="End-of-line."

echo "${scriptResult}" >> /private/var/tmp/$plistLabel.log

exit 0
==endOfScript==



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Set the permission on the script
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "Set script file permissions ..."
/usr/sbin/chown root:wheel /private/var/tmp/reconAtReboot.bash
/bin/chmod 644 /private/var/tmp/reconAtReboot.bash
/bin/chmod +x /private/var/tmp/reconAtReboot.bash



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Create Log File
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "Create Log File at /private/var/tmp/$plistLabel.log ..."
touch /private/var/tmp/$plistLabel.log
echo "Created $plistLabel.log on $timestamp" > /private/var/tmp/$plistLabel.log



# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Exit
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

echo "LaunchDaemon and Script created."

exit 0
Posted in Jamf Pro, Scripts, Tips & Tricks

Related Posts