Help your users easily provide Microsoft Support their Office configuration files while maintaining user privacy

Background
After implementing Microsoft’s recommended macro security in Office for Mac settings via a Configuration Profile, then having affected users run Paul’s Office-Reset packages via Jamf Pro’s Self Service, some users are still observing the dreaded Run-time error 32815 triple-prompts for Visual Basic for Applications when opening blank documents in Word, Excel or PowerPoint.

While again re-running — or re-re-running — the Office-Reset policies suppress the error, we started working with Microsoft Support to determine root-cause as the issue seems to reemerge immediately after each Office update.
TL;DR: We’re currently convinced it’s Adobe Acrobat DC’s fault
Capture User’s Office Configuration
We started by focusing on Word and the request from Microsoft Support was to capture the content of the following folders both before and after the next Office upgrade:
~/Library/Containers/com.microsoft.Word~/Library/Group Containers/UBF8T346G9.Office/User Content.localized/*/Library/Application Support/Microsoft/Office365/User Content.localized/*
~/Library/Containers
Since a sandboxed app can only write to its own directories, the ~/Library/Containers/com.microsoft.Word/Data folder contains aliases to several user folders, including ~/Desktop, ~/Downloads and the highly personal ~/Pictures directory:
❯ ls -lah ~/Library/Containers/com.microsoft.Word/Data total 16 drwx------ 13 dan staff 416B Sep 2 01:15 . drwx------@ 5 dan staff 160B Sep 2 01:15 .. lrwxr-xr-x 1 dan staff 19B Jul 19 08:37 Desktop -> ../../../../Desktop drwx------ 2 dan staff 64B Jul 19 08:37 Documents lrwxr-xr-x 1 dan staff 21B Jul 19 08:37 Downloads -> ../../../../Downloads drwx------ 33 dan staff 1.0K Jul 28 14:52 Library lrwxr-xr-x 1 dan staff 18B Jul 19 08:37 Movies -> ../../../../Movies lrwxr-xr-x 1 dan staff 17B Jul 19 08:37 Music -> ../../../../Music lrwxr-xr-x 1 dan staff 20B Jul 19 08:37 Pictures -> ../../../../Pictures drwx------ 2 dan staff 64B Jul 19 08:37 SystemData drwx------ 2 dan staff 64B Jul 19 08:37 tmp
--symlinks
As entertaining as this Personally Identifiable Information (PII) may be to a Microsoft Support engineer, we elected to exclude the contents of aliased directories by adding the --symlinks option to the zip command.

--exclude
After a review by our internal Security team, we choose to also exclude the Cookies and WebKit directories:
The
Cookiesfolder may contain authentication cookiesThe
Webkitfolder could include authentication data from our IdP
Note: While the user’s shortname is plainly visible in the output, this is most likleyl already known to Microsoft.
Script
Add the following script to Jamf Pro, adjusting the workspace URL as provided by Microsoft Support. (Latest version available on GitHub.)
#!/bin/bash
####################################################################################################
#
# ABOUT
#
# Microsoft Office User Configuration Capture
#
####################################################################################################
#
# HISTORY
#
# Version 1.0.0, 02-Sep-2022, Dan K. Snelson
# Original version
#
# Version 1.0.1, 02-Sep-2022, Dan K. Snelson
# Exclude "Webkit" and "Cookies" (per Obi-Bryson)
#
####################################################################################################
####################################################################################################
#
# Variables
#
####################################################################################################
scriptVersion="1.0.1"
scriptResult=""
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
loggedInUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }' )
loggedInUserHome=$( dscl . -read /Users/$loggedInUser | grep NFSHomeDirectory: | cut -c 19- | head -n 1 )
serialNumber=$( system_profiler SPHardwareDataType | grep "Serial Number" | awk -F ": " '{ print $2 }' )
timestamp=$( date '+%Y-%m-%d-%H%M%S' )
filename="microsoft_case_86753099_${serialNumber}-${timestamp}"
####################################################################################################
#
# Functions
#
####################################################################################################
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Check for / install swiftDialog (thanks, @acodega!)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function dialogCheck(){
# Get the URL of the latest PKG From the Dialog GitHub repo
dialogURL=$( curl --silent --fail "https://api.github.com/repos/bartreardon/swiftDialog/releases/latest" | awk -F '"' "/browser_download_url/ && /pkg\"/ { print \$4; exit }" )
# Expected Team ID of the downloaded PKG
expectedDialogTeamID="PWA5E9TQ59"
# Check for Dialog and install if not found
if [[ ! -e "/Library/Application Support/Dialog/Dialog.app" ]]; then
scriptResult+="Installing Dialog; "
# Create temporary working directory
workDirectory=$( basename "$0" )
tempDirectory=$( mktemp -d "/private/tmp/$workDirectory.XXXXXX" )
# Download the installer package
curl --location --silent "$dialogURL" -o "$tempDirectory/Dialog.pkg"
# Verify the download
teamID=$( spctl -a -vv -t install "$tempDirectory/Dialog.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' )
# Install the package if Team ID validates
if [[ "$expectedDialogTeamID" = "$teamID" ]] || [[ "$expectedDialogTeamID" = "" ]]; then
installer -pkg "$tempDirectory/Dialog.pkg" -target /
else
jamfDisplayMessage "Dialog Team ID verification failed."
exit 1
fi
# Remove the temporary working directory when done
rm -Rf "$tempDirectory"
else
scriptResult+="Dialog version $(dialog --version) found; proceeding..."
fi
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Display Message: Dialog
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function displayMessageDialog() {
rm /var/tmp/dialog.log
title="${1}"
message="${2}"
icon=$( defaults read /Library/Preferences/com.jamfsoftware.jamf.plist self_service_app_path )
scriptResult+="Display \"${title}\" message to ${loggedInUser}; "
dialog --title "${title}" --message "${message}" --icon "${icon}" --ontop --moveable
echo "quit:" >> /var/tmp/dialog.log
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# JAMF Display Message (for fallback in case swiftDialog fails to install)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function jamfDisplayMessage() {
scriptResult+="${1}"
jamf displayMessage -message "${1}" &
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Reveal File in Finder
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
function revealMe() {
/usr/bin/su - "${loggedInUser}" -c '/usr/bin/open -R "'"${1}"'" '
}
####################################################################################################
#
# Program
#
####################################################################################################
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Logging preamble
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
scriptResult+="Microsoft Office User Configuration Capture (${scriptVersion}); "
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Confirm script is running as root
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if [[ $(id -u) -ne 0 ]]; then
scriptResult+="This script should be run as root; exiting."
echo "${scriptResult}"
exit 1
fi
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Validate logged-in user
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if [[ -z "${loggedInUser}" || "${loggedInUser}" == "loginwindow" ]]; then
scriptResult+="No user logged-in; exiting."
echo "${scriptResult}"
exit 0
fi
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Validate swiftDialog is installed
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
dialogCheck
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Compress Microsoft Word-related directories
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
scriptResult+="Compress Microsoft Word-related directories; "
zip --quiet --recurse-paths --symlinks "${loggedInUserHome}/Desktop/${filename}.zip" "/Library/Application Support/Microsoft/Office365/User Content.localized" "${loggedInUserHome}/Library/Group Containers/UBF8T346G9.Office/User Content.localized" "${loggedInUserHome}/Library/Containers/com.microsoft.Word" --exclude "${loggedInUserHome}/Library/Containers/com.microsoft.Word/Data/Library/Cookies/*" --exclude "${loggedInUserHome}/Library/Containers/com.microsoft.Word/Data/Library/WebKit/*"
scriptResult+="Microsoft Word-related directories saved to: ${loggedInUserHome}/Desktop/${filename}.zip; "
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Display End-user Message
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
displayMessageDialog "Microsoft Case No. 86753099 (${scriptVersion})" "## Log Gathering Complete \n\nYour computer logs have been saved
to your Desktop as: \n\n\`${filename}.zip\` \n\nPlease [upload](https://support.microsoft.com/files?workspace=ridiculously-long-URL-goes-here) the file to Microsoft."
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Reveal Compressed File
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
scriptResult+="Reveal Compressed File; "
revealMe "${loggedInUserHome}/Desktop/${filename}.zip"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Exit
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
scriptResult+="Complete!"
echo "${scriptResult}"
exit 0
Policy
Create a new Jamf Pro policy, add the script and make the policy available in Self Service.

Self Service Description
Adjust the workspace URL as provided by Microsoft Support.
## Office for Mac: Default templates' macros re-enabled with each upgrade Please click the **Capture** button to save the following directories to your Mac's Desktop: - `/Library/Application Support/Microsoft/Office365/User Content` - `~/Library/Containers/Microsoft Word` - `~/Library/Group Containers/UBF8T346G9.Office/User Content` Once complete, a compressed file with a name similar to `microsoft_case_86753099 … .zip` will be saved to your Mac's Desktop. Please [upload](https://support.microsoft.com/files?workspace=ridiculously-long-URL-goes-here) the `microsoft_case_86753099 … .zip` file to Microsoft.
User Message
The script will gather the directories and leverage swiftDialog (installing, if necessary) to display a Self Service-branded message to the users which includes a link to upload the output directly to Microsoft:
