Default Font Outlook Mac

rpoladiya
New Contributor

Hi
We use Mac and Windows with Outlook in our school
In the group policy I can configure default fonts for Windows

How can I configure Default Fonts for Mac for all the users in the organization

Kind regards,

1 ACCEPTED SOLUTION

sdagley
Esteemed Contributor II
24 REPLIES 24

sdagley
Esteemed Contributor II

Hi how do I get the script to work? I added it to scripts in Jamf but it doesn't work. The message that pops up says that the registry does not exists for MicrosoftRegistrationDB.reg and no such file or directory, Registry could not be created

rpoladiya
New Contributor

@sdagley - I have played with the script and sorted it

Thank you so so much for this
Kind regards,

dfracassa
New Contributor III

Hi everyone,

Would someone be able to explain how to deploy this OutlookFontPoke script for Arial 11?

I am failing to understand the logic of the script, it's dirving me insane.

Thank you

DavidN
Contributor

I'm trying to get this to run at login. Here is what I have but it is not working.

<?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>com.mycompany.fontpoke</string> <key>Program</key> <string>/Users/Shared/OutlookFontPoke.sh</string> <key>ProgramArguments</key> <array> <string>'Arial' '12.0pt' 'black'</string> </array> <key>RunAtLoad</key> <true/>
</dict>
</plist>

I have also tried splitting the program arguments out as separate strings in the array, and also removing the ' ' . No luck.

sdagley
Esteemed Contributor II

@DavidN A couple of problems in what you're trying:
- The OutlookFontPoke.sh script looks to be designed to be run by the logged in user's account, but if you're running from a LaunchDaemon it'll be running as root
- You shouldn't use both the Program and ProgramArguments keys. ProgramArguments is what you should be using, and the first 2 items in your array would be:

<string>/bin/sh</string>
<string>/Users/Shared/OutlookFontPoke.sh</string>
...

A good guide to LaunchAgents/Daemons is https://launchd.info
You'll also find the article Running a Command as another User helpful.

DavidN
Contributor

Thanks for the response. I am running this as a launchAgent and have tried it both in /Library/LaunchAgents as well as ~/Library/LaunchAgents. I have also tried the syntax you have above /bin/sh with the script. It also needs parameters passed into it.

'Arial' '12.0pt' 'black'

I thought the parameters would be ProgramArguments while the Program would be the script itself. Is that not correct?

DavidN
Contributor

Here's the answer:

:)

<?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>com.mycompany.fontpoke</string> <key>ProgramArguments</key> <array> <string>/Users/Shared/OutlookFontPoke.sh</string> <string>Arial</string> <string>12.0pt</string> <string>black</string>

</array> <key>RunAtLoad</key> <true/>
</dict>
</plist>

dfracassa
New Contributor III

Hi everyone,

Would someone be able to explain how to deploy this OutlookFontPoke script for Arial 11?

I am failing to understand the logic of the script, it's dirving me insane.

Thank you

jmilks
New Contributor II

Trying to use OutlookFontPoke both locally and through Jamf.  Getting "OutlookFontPoke: command not found" when trying to run OutlookFontPoke from pbowden using the example command:

https://github.com/pbowden-msft/OutlookFontPoke

Thinking that I was doing something wrong I tried using outlookFontSet from quedayone but getting the same error:

https://github.com/quedayone/jamf-pro-scripts/blob/master/outlookFontSet.sh

 

Just need to set a default font for Outlook (I was able to get Word and PP to accept Normal.dotm and Normal.potx but Outlook doesn't seem to load NormalEmail.dotm anymore as a template...)

jmilks
New Contributor II

In working with Paul Bowden (author of OutlookFontPoke), we were able to come up with a deployable version of this script.  This is how we did it:

1. Drop OutlookFontPoke and TemplateRegDB.reg on the system in an accessible location (I kept it in the folder OutlookFontPoke-master and dropped it in Users/Shared)

2. In Jamf Scripts, create a script with these commands:

#!/bin/bash
#send command to OutlookFontPoke v2.1 by Paul Bowden
#https://github.com/pbowden-msft/OutlookFontPoke/archive/refs/heads/master.zip
#pbowden@microsoft.com

#Get Current User
loggedInUser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
echo $loggedInUser " is logged in"

#fix permissions
chmod +x /Users/Shared/OutlookFontPoke-master/OutlookFontPoke

# Run command as current logged in user
sudo -u $loggedInUser /Users/Shared/OutlookFontPoke-master/OutlookFontPoke 'Helvetica' '11.0pt' 'gray'

# Cleanup files
rm -rf /Users/Shared/OutlookFontPoke-master

exit 0

3. Add both the package and script (script priority set to after) to a policy to run at your needed cadence.  This is a one time set and is not enforced so the user can change it in Outlook settings.

I am trying to make it a bit more future proof by adding in Parameter Values but it am having issues passing into or with ' ' (any suggestions would be greatly appreciated, can't remember/find how)

dfracassa
New Contributor III

This worked perfectly. Thank you so much for simplifying it.

Not sure if I did something unusual but I think I got it to work with parameters and didn't need any of the extra stuff from your comment.

  • I added the actual script to Jamf (as is from the repo)
  • Modified FONTNAME to use $4, FONTSIZE to $5, and FONTCOLOR to $6
  • Defined the parameters in Jamf
  • Put the script in a policy and filled in the parameters
  • Ran it from Self Service
  • Restarted Outlook and verified the fonts had changed

Is the fact that I ran it from Self Service a factor here?

No, running from Self Service makes no difference.

I used a newer Version of the OutlookFontPoke from here:

https://github.com/AlyaKoni/OutlookFontPoke/tree/master

I created a PKG for that script which installs into

/usr/local/OutlookFontPoke/

My Script for setting up Font parameters via Jamf Policy:

#!/bin/bash
#send command to OutlookFontPoke v2.1 by Paul Bowden
#https://github.com/pbowden-msft/OutlookFontPoke/archive/refs/heads/master.zip
#pbowden@microsoft.com

# Variables
nameFont=$4 	#eg "Arial"
echo "### nameFont - $nameFont"
sizeFont=$5		#eg "11.0pt"
echo "### sizeFont - $sizeFont"
colorFont=$6	#eg "gray"
echo "### colorFont - $colorFont"
pathToScript="/usr/local/OutlookFontPoke/OutlookFontPoke-2.1.sh"

#Get Current User
loggedInUser=$(/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }')
echo $loggedInUser " is logged in"

#fix permissions
chmod +x "$pathToScript"

# Run command as current logged in user
sudo -u $loggedInUser $pathToScript $nameFont $sizeFont $colorFont

exit 0

My settings for the Script in the Jamf Console look like this:

Screenshot 2025-03-11 at 17.36.26.png

 And the Policy settings are like this:

Screenshot 2025-03-11 at 17.37.26.png

The Script runs once per day and log in, this ensures that things are ready before Outlook starts.

I didn't think so but I wasn't sure if triggering it from Self Service might run it AS the user.

Anyway, it worked for me without creating a package or any of that extra stuff though. I just used the original (https://github.com/pbowden-msft/OutlookFontPoke) but changed lines 125-127:

FONTNAME="$4"
FONTSIZE="$5"
FONTCOLOR="$6"

Bretterson_0-1741713500607.png  Bretterson_2-1741713574069.png

I did it on my user, which already had Outlook setup and everything, I just changed all the font preferences before running it. I just feel like I must be missing something, because I'm not that good of a script writer for it to be that easy of a fix.

Well I figured out why I didn't have to do all the extra stuff: Outlook was already setup and had preferences configured on my account. I had someone login to the computer with their account and the script failed because the registry file didn't exist.

No matter what I do I can't seem to get this to work if set before an account has been added in Outlook. Should that work or is it expected it will be used post login?

@Bretterson I run the policy on Macs which have MS Outlook already installed and with the Trigger Login. As far as I found out, it is only requires to have the Outlook App installed, it is not required to have Outlook already configured with an account.

Hmmm. I still can't seem to get it working before an account has been added to Outlook. The script creates the file without issue, but the application doesn't take the changes. The file permissions match the ones that were on the the copy of MicrosoftRegistrationDB.reg I had prior to using the script (as in the file Outlook generated back when I added the user).

Are you using the App Store version of Outlook or a standard installer? I wonder if it behaves differently.

EDIT: I tried uninstalling Outlook and letting Jamf reinstall via Jamf App Installers rather than MAS, still no luck 😖

@Bretterson we use the Office PKG Installer. To get my workflow to work, it is not required to have a Profile in Outlook.

In case Outlook is not installed I get the following log:

Screenshot 2025-03-25 at 11.58.12.png

 After installing Outlook the script shows an error:

Screenshot 2025-03-25 at 12.34.28.png

Then I activated Outlook and created a Profile, the result in the Outlook Settings are like expected:

Screenshot 2025-03-25 at 12.35.54.png

Jamf App Installers looks to be using a PKG installer as well, so that probably isn't the issue.

I actually modified the script to download the TemplateDB.reg directly from GitHub and use parameters from a Jamf policy. All of that is working fine... other than the messages that the registry and registry path don't exist, I don't get any errors at all, regardless of whether I run it with or without Outlook installed. But for some reason Outlook doesn't process the changes unless I run it after an account has been added. Maybe I'll see what happens if I just run it locally. I don't want to give up but I'm low on ideas.

PS: You can delete line 163 from the script, it seems to be an errant character.

Would you mind trying my modified version of the script to see if it works for you without an Outlook profile? You don't need to package it or anything extra and it pulls the settings from parameters 4-6, just like the one you're using.

#!/bin/sh
#set -x

TOOL_NAME="Microsoft Outlook 365/2021/2019/2016 for Mac Default Font Changer"
TOOL_VERSION="2.1"

## Copyright (c) 2022 Microsoft Corp. All rights reserved.
## Scripts are not supported under any Microsoft standard support program or service. The scripts are provided AS IS without warranty of any kind.
## Microsoft disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a 
## particular purpose. The entire risk arising out of the use or performance of the scripts and documentation remains with you. In no event shall
## Microsoft, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever 
## (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary 
## loss) arising out of the use of or inability to use the sample scripts or documentation, even if Microsoft has been advised of the possibility
## of such damages.
## Feedback: pbowden@microsoft.com

# Constants
USER=$( whoami )
REGISTRYPATH="/Users/$USER/Library/Group Containers/UBF8T346G9.Office"
REGISTRY="$REGISTRYPATH/MicrosoftRegistrationDB.reg"
OUTLOOKPATH="/Applications/Microsoft Outlook.app"
SCRIPTPATH=$( cd $(dirname $0) ; pwd -P )

# Create a temporary directory and download Registry template
TEMPDIR=$(mktemp -d)
cd "$TEMPDIR" || exit
#cd $SCRIPTPATH
curl -OL https://github.com/pbowden-msft/OutlookFontPoke/raw/refs/heads/master/TemplateRegDB.reg
#chmod +x TemplateRegDB.reg

function ShowUsage {
# Shows tool usage and parameters
	echo $TOOL_NAME - $TOOL_VERSION
	echo "Purpose: Sets the default compose and reply/forward fonts in Outlook 365/2021/2019/2016 for Mac"
	echo "Usage: OutlookFontPoke [-dump] <font-name> <font-size> <font-color> [<user>]"
	echo "Example: OutlookFontPoke 'Helvetica' '11.0pt' 'gray'"
	echo "Example: OutlookFontPoke 'Helvetica' '11.0pt' 'gray' 'aUser'"
	echo
	exit 0
}

function CheckRegistryExists {
# Check if Registry exists
	if [ ! -e "$REGISTRYPATH" ]; then
		echo "WARNING: Registry path DOES NOT exist at $REGISTRYPATH. Attempting to create..."
		mkdir -p "$REGISTRYPATH"
		chown -R $USER "$REGISTRYPATH"
	fi
	if [ ! -e "$REGISTRY" ]; then
		echo "WARNING: Registry DOES NOT exist at path $REGISTRY. Attempting to create..."
		cp "$TEMPDIR"/TemplateRegDB.reg "$REGISTRY"
		chown -R $USER "$REGISTRYPATH"
		if [ "$?" != "0" ]; then
			echo "ERROR: Registry could not be created."
			exit 1
		fi
	fi
}

function CheckLaunchState {
# Checks to see if a process is running
	local RUNNING_RESULT=$(ps ax | grep -v grep | grep "$1")
	if [ "${#RUNNING_RESULT}" -gt 0 ]; then
		echo "1"
	else
		echo "0"
	fi
}

function GetNodeId {
# Get node_id value from Registry
	local NAME="$1"
	local PARENT="$2"
	local NODEVALUE=$(sqlite3 "$REGISTRY" "SELECT node_id from HKEY_CURRENT_USER WHERE name='$NAME' AND parent_id=$PARENT;")
	if [ "$NODEVALUE" == '' ]; then
		echo "0"
	else
		echo "$NODEVALUE"
	fi
}

function GetNodeVal {
# Get node value from Registry
	local NAME="$1"
	local NODEID="$2"
	local NODEVALUE=$(sqlite3 "$REGISTRY" "SELECT node_id from HKEY_CURRENT_USER_values WHERE name='$NAME' AND parent_id=$NODEID;")
	if [ "$NODEVALUE" == '' ]; then
		echo "0"
	else
		echo "$NODEVALUE"
	fi
}

function InsertNode {
# Insert new node into Registry
	local NAME="$1"
	local PARENT="$2"
	sqlite3 "$REGISTRY" "INSERT INTO HKEY_CURRENT_USER ('parent_id','name') VALUES ($PARENT,'$NAME');"
}

function InsertValue {
# Insert new value into Registry
	local NODE="$1"
	local NAME="$2"
	local TYPE="$3"
	local VALUE="$4"
	sqlite3 "$REGISTRY" "INSERT or REPLACE INTO HKEY_CURRENT_USER_values ('node_id','name','type','value') VALUES ($NODE,'$NAME',$TYPE,'$VALUE');"
}

function DeleteValue {
# Delete value from Registry
	local NAME="$1"
	local NODEID="$2"
	sqlite3 "$REGISTRY" "DELETE FROM HKEY_CURRENT_USER_values WHERE name='$NAME' and node_id=$NODEID;"
}

function GetValue {
# Get value from Registry
	local NAME="$1"
	local NODEID="$2"
	local NODEVALUE=$(sqlite3 "$REGISTRY" "SELECT value from HKEY_CURRENT_USER_values WHERE name='$NAME' AND node_id=$NODEID;")
	if [ "$NODEVALUE" == '' ]; then
		echo "0"
	else
		echo "$NODEVALUE"
	fi
}

# Evaluate command-line arguments
if [[ $# = 0 ]]; then
	ShowUsage
elif [[ $# = 1 ]]; then
	if [ "$1" == "-dump" ]; then
		DUMP=true
	else
		ShowUsage
	fi
else
	DUMP=false
	FONTNAME="$4"
	FONTSIZE="$5"
	FONTCOLOR="$6"
	DOUSER="$3"
	
	if [ "$FONTCOLOR" == '' ]; then
		FONTCOLOR="windowtext"
	fi
	
	if [ "$DOUSER" != '' ]; then
		USER=$DOUSER
		REGISTRYPATH="/Users/$USER/Library/Group Containers/UBF8T346G9.Office"
		REGISTRY="$REGISTRYPATH/MicrosoftRegistrationDB.reg"
	fi
fi

## Main
# Check that MicrosoftRegistryDB.reg actually exists. If it doesn't, attempt to create it.
CheckRegistryExists
# Walk the registry to find the id of the node that we need
KEY_SOFTWARE=$(GetNodeId "Software" '-1')
KEY_MICROSOFT=$(GetNodeId "Microsoft" "$KEY_SOFTWARE")
KEY_OFFICE=$(GetNodeId "Office" "$KEY_MICROSOFT")
KEY_VERSION=$(GetNodeId "16.0" "$KEY_OFFICE")
KEY_COMMON=$(GetNodeId "Common" "$KEY_VERSION")
KEY_MAILSETTINGS=$(GetNodeId "MailSettings" "$KEY_COMMON")
# The MailSettings node doesn't exist by default, so if it's not already there, create it
if [ "$KEY_MAILSETTINGS" == "0" ] && [ $DUMP = false ]; then
	InsertNode "MailSettings" "$KEY_COMMON"
fi

KEY_MAILSETTINGS=$(GetNodeId "MailSettings" "$KEY_COMMON")

# If the fonts are already set, remove the existing values
KEY_COMPOSEFONTCOMPLEX=$(GetValue "ComposeFontComplex" "$KEY_MAILSETTINGS")
if [ "$KEY_COMPOSEFONTCOMPLEX" != "0" ]; then
	if [ $DUMP = true ]; then
		echo "==Begin ComposeFontComplex=="
		echo "$KEY_COMPOSEFONTCOMPLEX"
		echo "==End ComposeFontComplex=="
	else
		DeleteValue "ComposeFontComplex" "$KEY_MAILSETTINGS"
		DeleteValue "ComposeFontSimple" "$KEY_MAILSETTINGS"
	fi
fi
KEY_REPLYFONTCOMPLEX=$(GetValue "ReplyFontComplex" "$KEY_MAILSETTINGS")
if [ "$KEY_REPLYFONTCOMPLEX" != "0" ]; then
	if [ $DUMP = true ]; then
		echo "==Begin ReplyFontComplex=="
		echo "$KEY_REPLYFONTCOMPLEX"
		echo "==End ReplyFontComplex=="
	else
		DeleteValue "ReplyFontComplex" "$KEY_MAILSETTINGS"
		DeleteValue "ReplyFontSimple" "$KEY_MAILSETTINGS"
	fi
fi
KEY_TEXTFONTCOMPLEX=$(GetValue "TextFontComplex" "$KEY_MAILSETTINGS")
if [ "$KEY_TEXTFONTCOMPLEX" != "0" ]; then
	if [ $DUMP = true ]; then
		echo "==Begin TextFontComplex=="
		echo "$KEY_TEXTFONTCOMPLEX"
		echo "==End TextFontComplex=="
	else
		DeleteValue "TextFontComplex" "$KEY_MAILSETTINGS"
		DeleteValue "TextFontSimple" "$KEY_MAILSETTINGS"
	fi
fi

if [ $DUMP = false ]; then
	# Set new font values - first one is for the Compose Font, the second is for the Reply/Forward font
	InsertValue "$KEY_MAILSETTINGS" "ComposeFontComplex" "3" "<html><head><style>/* Style Definitions */span.PersonalComposeStyle{mso-style-name:\"Personal Compose Style\";mso-style-type:personal-compose;mso-style-noshow:yes;mso-style-unhide:no;mso-ansi-font-size:$FONTSIZE;mso-bidi-font-size:11.0pt;font-family:\"$FONTNAME\";mso-ascii-font-family:\"$FONTNAME\";mso-hansi-font-family:\"$FONTNAME\";mso-bidi-font-family:\"Times New Roman\";mso-bidi-theme-font:minor-bidi;color:$FONTCOLOR;font-weight:normal;font-style:normal;text-decoration:none;text-underline:none;}--></style></head></html>"
	InsertValue "$KEY_MAILSETTINGS" "ReplyFontComplex" "3" "<html><head><style>/* Style Definitions */span.PersonalReplyStyle{mso-style-name:\"Personal Reply Style\";mso-style-type:personal-reply;mso-style-noshow:yes;mso-style-unhide:no;mso-ansi-font-size:$FONTSIZE;mso-bidi-font-size:11.0pt;font-family:\"$FONTNAME\";mso-ascii-font-family:\"$FONTNAME\";mso-hansi-font-family:\"$FONTNAME\";mso-bidi-font-family:\"Times New Roman\";mso-bidi-theme-font:minor-bidi;color:$FONTCOLOR;font-weight:normal;font-style:normal;text-decoration:none;text-underline:none;}--></style></head></html>"
	InsertValue "$KEY_MAILSETTINGS" "TextFontComplex" "3" "<html><head><style>/* Style Definitions */p.MsoPlainText, li.MsoPlainText, div.MsoPlainText{mso-style-noshow:yes;mso-style-priority:99;mso-style-link:\"Plain Text Char\";margin:0cm;mso-pagination:widow-orphan;font-size:$FONTSIZE;mso-bidi-font-size:11.0pt;font-family:\"$FONTNAME\",sans-serif;mso-bidi-font-family:\"Times New Roman\";mso-bidi-theme-font:minor-bidi;mso-font-kerning:1.0pt;mso-ligatures:standardcontextual;mso-fareast-language:EN-US;}--></style></head></html>"

	echo "Default Outlook font set successfully."

	# If Outlook is already running, show a warning that the settings won't take effect until a restart occurs
	RUNSTATE=$(CheckLaunchState "$OUTLOOKPATH")
	if [ "$RUNSTATE" == "1" ]; then
		echo "Outlook must be restarted to read the new font preference."
	fi
fi


exit 0

flade
New Contributor

works for me on monterey, but not on ventura.. anyone got that working on ventura?

jmilks
New Contributor II

I did have more consistent success injecting the fonts in question to /Users/$userName/Library/Group\ Containers/UBF8T346G9.Office/FontCache/4/CloudFonts/.  The fonts I am using are not a default font set though...  Then I setup an EA and smart group to test for existence of those fonts before setting the default.