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
In 10.30.x and later, the /Library/Application Support/JAMF/Self Service/Managed Plug-ins directory has disappeared.
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
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> |
Fortunately, I was able to figure out a way to do the following:
- Parse the document for the bookmark XML objects.
- Split them out into individual XML files.
- 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:
- If necessary, create a directory for storing backup copies of the Self Service bookmark files.
- Make copies of the Self Service bookmark files.
- Name the copied files using the title of the Self Service bookmark.
- 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.
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> |
The script is available below, and at the following address on GitHub:
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 groups has not been specified." | |
echo "Downloaded groups will be stored in $SelfServiceBookmarkBackupDirectory." | |
fi | |
self_service_bookmark_file="$HOME/Library/Application Support/com.jamfsoftware.selfservice.mac/CocoaAppCD.storedata" | |
if [[ -f "$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" | |
fi | |
exit $error |