Home > Jamf Pro, Mac administration, Scripting > Backing up Self Service bookmarks for Jamf Pro 10.30.0 and later

Backing up Self Service bookmarks for Jamf Pro 10.30.0 and later

A while ago, I wrote a post on how to back up your Jamf Pro Self Service bookmarks. I’ve been using that process to back up my bookmarks and it’s been working fine until after my upgrade to Jamf Pro 10.30.0. At that point, my script stopped working. When I checked into it and talked with some colleagues, it became apparent that Jamf had made a change with how they stored bookmark information for Self Service.

In 10.29.x and earlier, Jamf had stored bookmarks as individual plist files in the following location:

/Library/Application Support/JAMF/Self Service/Managed Plug-ins

Screen Shot 2020 09 27 at 11 31 16 AM

In 10.30.x and later, the /Library/Application Support/JAMF/Self Service/Managed Plug-ins directory has disappeared.

Screen Shot 2021 06 23 at 10 37 24 AM

Jamf now stores bookmark information inside an XML file named CocoaAppCD.storedata in the user’s home folder at the following location:

~/Library/Application Support/com.jamfsoftware.selfservice.mac/CocoaAppCD.storedata

Screen Shot 2021 06 23 at 10 35 51 AM

Inside the CocoaAppCD.storedata file, the bookmarks are stored as XML objects similar to what is shown below:

<object type="SSBOOKMARK" id="z169">
<attribute name="url" type="string">https://www.bananas.com</attribute>
<attribute name="priority" type="int64">5</attribute>
<attribute name="displayinbrowser" type="bool">1</attribute>
<attribute name="name" type="string">Bananas.com</attribute>
<attribute name="jssdescription" type="string">Bananas.com</attribute>
<attribute name="installstatus" type="int64">0</attribute>
<attribute name="id" type="int64">2</attribute>
<attribute name="iconurl" type="string">https://ics.services.jamfcloud.com/icon/hash_95740013589cddd19b2192016788dd9e91e735f8ff5213f92005f4eb92ac16b6</attribute>
<attribute name="compliance" type="bool">0</attribute>
<attribute name="buttontext" type="string">Open</attribute>
</object>

view raw
Bananas.com.xml
hosted with ❤ by GitHub

Screen Shot 2021 06 23 at 4 22 03 PM

Fortunately, I was able to figure out a way to do the following:

  1. Parse the document for the bookmark XML objects.
  2. Split them out into individual XML files.
  3. Name the files using the title of the Self Service bookmark.

For more details, please see below the jump.

To make backups of the Self Service bookmarks, I’ve written a script which performs the following tasks:

  1. If necessary, create a directory for storing backup copies of the Self Service bookmark files.
  2. Make copies of the Self Service bookmark files.
  3. Name the copied files using the title of the Self Service bookmark.
  4. Store the copied bookmarks in the specified directory.

Once the script is run, you should see copies of the Self Service bookmark files appearing in the script-specified location. This location can be manually set or created automatically by the script.

Screen Shot 2021 06 23 at 11 11 08 AM

Screen Shot 2021 06 23 at 11 33 09 AM

When examined, the files should look similar to this:

<?xml version="1.0" encoding="UTF-8"?>
<object type="SSBOOKMARK" id="z169">
<attribute name="url" type="string">https://www.bananas.com</attribute>
<attribute name="priority" type="int64">5</attribute>
<attribute name="displayinbrowser" type="bool">1</attribute>
<attribute name="name" type="string">Bananas.com</attribute>
<attribute name="jssdescription" type="string">Bananas.com</attribute>
<attribute name="installstatus" type="int64">0</attribute>
<attribute name="id" type="int64">2</attribute>
<attribute name="iconurl" type="string">https://ics.services.jamfcloud.com/icon/hash_95740013589cddd19b2192016788dd9e91e735f8ff5213f92005f4eb92ac16b6</attribute>
<attribute name="compliance" type="bool">0</attribute>
<attribute name="buttontext" type="string">Open</attribute>
</object>

view raw
Bananas.com.xml
hosted with ❤ by GitHub

The script is available below, and at the following address on GitHub:

https://github.com/rtrouton/rtrouton_scripts/tree/master/rtrouton_scripts/Casper_Scripts/Jamf_Pro_Self_Service_Bookmark_Backup

Jamf_Pro_Self_Service_Bookmark_Backup.sh:

#!/bin/bash
# This script is designed to do the following:
#
# 1. If necessary, create a directory for storing backup copies of Jamf Pro Self Service bookmark files.
# 2. Make copies of the Self Service bookmark files.
# 3. Name the copied files using the title of the Self Service bookmark.
# 4. Store the copied bookmarks in the specified directory.
#
# If you choose to specify a directory to save the Self Service bookmarks into,
# please enter the complete directory path into the SelfServiceBookmarkBackupDirectory
# variable below.
SelfServiceBookmarkBackupDirectory=""
# If the SelfServiceBookmarkBackupDirectory isn't specified above, a directory will be
# created and the complete directory path displayed by the script.
error=0
if [[ -z "$SelfServiceBookmarkBackupDirectory" ]]; then
SelfServiceBookmarkBackupDirectory=$(mktemp -d)
echo "A location to store downloaded bookmarks has not been specified."
echo "Downloaded bookmarks will be stored in $SelfServiceBookmarkBackupDirectory."
fi
self_service_bookmark_file="$HOME/Library/Application Support/com.jamfsoftware.selfservice.mac/CocoaAppCD.storedata"
if [[ -r "$self_service_bookmark_file" ]]; then
tmp_dir="/private/tmp/bookmark-workdir-$(date +%y%m%d%H%M%S)"
mkdir -p "$tmp_dir"
# For the next command, add a trailing slash for
# the the tmp_dir variable if it's not there.
length=${#tmp_dir}
last_char=${tmp_dir:length-1:1}
[[ $last_char != "/" ]] && tmp_dir="$tmp_dir/";
sed -n '/SSBOOKMARK/,/object/p' "$self_service_bookmark_file" | awk -v a=$tmp_dir '/SSBOOKMARK/{filename=a""++i".xml"}; {print >filename}'
#remove trailing slash if needed from the bookmark and tmp directories
SelfServiceBookmarkBackupDirectory=${SelfServiceBookmarkBackupDirectory%%/}
tmp_dir=${tmp_dir%%/}
for file in "$tmp_dir"/*
do
# Add XML declaration to first line if not already present in the file.
# This will allow xmllint to format the XML in human-readable format.
if [[ -z $(cat $file | grep "<?xml version="1.0" encoding="UTF-8"?>") ]]; then
echo -e "<?xml version="\""1.0"\"" encoding="\""UTF-8"\""?>\n$(cat $file)" > $file
fi
bookmark_name=$(cat $file | awk -F '[<>]' '/"name"/{print $3}')
xmllint –format "$file" > "$file"_formatted.xml
mv "$file"_formatted.xml "$SelfServiceBookmarkBackupDirectory/$bookmark_name".xml
if [[ $? -eq 0 ]]; then
echo "$bookmark_name.xml processed and stored in $SelfServiceBookmarkBackupDirectory."
else
echo "ERROR! Problem occurred when processing $self_service_bookmark_file file!"
error=1
fi
done
rm -rf "$tmp_dir"
else
echo "Cannot read $self_service_bookmark_file"
fi
exit $error

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: