Set Outlook 2016 as default without having to open Mail.app

koepke
New Contributor II

Anyone have a script for this?

55 REPLIES 55

mm2270
Legendary Contributor II

You can use duti for this.
Otherwise, this information is stored in each user's com.apple.LaunchServices.plist file, under the LSHandlers array. Its not the easiest thing to manipulate, but you can probably create a Configuration Profile to manage it, rather than trying to script it.

jacopo_pulici
Contributor

I use this lines in my applescript Outlook Setup script for the 2011. Pretty sure it works also with 2016.

tell application "Microsoft Outlook"
    set system default everything application to yes
end tell

koepke
New Contributor II

@Jachk Not working on my end for Outlook 2016.

I'll try duti but it's a little frustrating that I have to install a community developed application to change my default mail client.

kstrick
Contributor III

I mentioned this to Microsoft, and they stated the feature got removed in the new version due to sandboxing rules... it is irritating.

koepke
New Contributor II

Thanks @kstrick . Looks like duti is my only option.

mm2270
Legendary Contributor II

I didn't even realize we were talking about the new Office 2016 here. My bad for not reading it more closely. So, the new suite won't set itself as the default mail application I guess is what I'm reading here? Hmm.
You could possibly do it with a Configuration Profile, converted from a custom plist file using mcxToProfile, but I don't know for sure. Once we actually get some licenses in house I will be able to start testing with the new version. Haven't even land hands on it yet.

Josh_Smith
Contributor III

I'm using duti for this with Office 2016.

#makes outlook default mail program
duti -s com.microsoft.outlook mailto
#makes outlook default calendar program
duti -s com.microsoft.outlook ics all
#makes outlook default contacts program
duti -s com.microsoft.outlook vcf all

**Edited to add: Using LaunchAgent to run this once per user at login

koepke
New Contributor II

Thanks @Josh.Smith ! Worked like a charm.

phredman
New Contributor III

Say for instance, we'd like to avoid using duti, anyone have any updates regarding this?

We'd like to standardize on Outlook 2016 and enforce the policy to restrict Mail.app.

Look
Valued Contributor III

I agree, although duti looks like it does the job, it would be nice to just have a couple of lines in a script somewhere to do this.
Apple makes it so darn hard to do something so darn simple at times!

perrycj
Contributor III

bump.

Anyone come up with a scripted option that doesn't involve using duti?

gachowski
Valued Contributor II

Not tested and copied from a source I can't remember were or from who, sorry....

# Setting Outlook as default Mail app..
# Create the LSHandlers array
/usr/libexec/plistbuddy -c "add:LSHandlers array" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
# Set default for mailto links
/usr/libexec/plistbuddy -c "add:LSHandlers:0:LSHandlerURLScheme string mailto" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/plistbuddy -c "add:LSHandlers:0:LSHandlerRoleAll string com.microsoft.outlook" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
# Set Outlook as default for email
/usr/libexec/plistbuddy -c "add:LSHandlers:1:LSHandlerContentType string com.apple.mail.email" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/plistbuddy -c "add:LSHandlers:1:LSHandlerRoleAll string com.microsoft.outlook" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/plistbuddy -c "add:LSHandlers:2:LSHandlerContentType string com.microsoft.outlook16.email-message" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plistcom.apple.LaunchServices.plist
/usr/libexec/plistbuddy -c "add:LSHandlers:2:LSHandlerRoleAll string com.microsoft.outlook" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist

# Set Outlook as default for .vcard
/usr/libexec/plistbuddy -c "add:LSHandlers:3:LSHandlerContentType string public.vcard" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/plistbuddy -c "add:LSHandlers:3:LSHandlerRoleAll string com.microsoft.outlook" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist

# Set Outlook as default for .ics files
/usr/libexec/plistbuddy -c "add:LSHandlers:4:LSHandlerContentType string com.apple.ical.ics" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
/usr/libexec/plistbuddy -c "add:LSHandlers:4:LSHandlerRoleAll string com.microsoft.outlook" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist

# Set Outlook as default calendar app
/usr/libexec/plistbuddy -c "add:LSHandlers:5:LSHandlerContentType string com.microsoft.outlook16.icalendar" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plistcom.apple.LaunchServices.plist
/usr/libexec/plistbuddy -c "add:LSHandlers:5:LSHandlerRoleAll string com.microsoft.outlook" /Users/$username/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist

Look
Valued Contributor III

I have a rather hacked scripted solution... It seems to work but well make sure you test it well first...
Consists of three files in /Library/Scripts/Outlook2016/
An empty launchservices - for when it hasn't been created
A partial launchservices with the outlook mailto entry
A script that takes the closing tags off the end of the launchservices and appends the partial launchservices to the end.
It has really only been tested on 10.11 as that is our deployment environment, however as long as its using the launchservices subfolder it should probably work.... Technically also you could have a more complex partial file if you wanted other handlers in there. I have been calling it at the end of my Outlook 2016 auto config script.

/Library/Scripts/Outlook2016/com.apple.launchservices.EMPTY.plist

<?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>LSHandlers</key>
    <array>
    </array>
</dict>
</plist>

/Library/Scripts/Outlook2016/com.apple.launchservices.PARTIAL.plist

        <dict>
            <key>LSHandlerPreferredVersions</key>
            <dict>
                <key>LSHandlerRoleAll</key>
                <string>-</string>
            </dict>
            <key>LSHandlerRoleAll</key>
            <string>com.microsoft.Outlook</string>
            <key>LSHandlerURLScheme</key>
            <string>mailto</string>
        </dict>
    </array>
</dict>
</plist>

/Library/Scripts/Outlook2016/Outlook_Default.sh

#!/bin/bash
Template_Plist="/Library/Scripts/Outlook2016/com.apple.launchservices.PARTIAL.plist"
Empty_Plist="/Library/Scripts/Outlook2016/com.apple.launchservices.EMPTY.plist"

##### SUBROUTINES START HERE #####

Plist_Exists(){
if [ -f ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist ]; then
return 0
else
return 1
fi
}

#####

Not_Configured(){
if [[ "$(cat ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist | awk '/com.microsoft.Outlook/')" ]]; then
return 1
echo
return 0
fi
}


#####

Configure_Plist(){
echo "back up existing launchservices"
cp ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.OLD
Plist_Length=$(wc -l ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist | awk '{print $1}')
Line_Num=$((Plist_Length + 1))
echo $Line_Num
Edit_Status=0

while [[ ${Line_Num} -gt 1 ]] && [[ ${Edit_Status} -lt 1 ]]; do
if [[ "$(sed -n "${Line_Num}p" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist | awk '//plist/' )" ]]; then
echo "removing close plist"
sed -i "" -e "${Line_Num}d" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
Edit_Status=1
fi
Line_Num=$((Line_Num - 1))
done

if [[ ${Edit_Status} -eq 1 ]] && [[ "$(sed -n "${Line_Num}p" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist | awk '//dict/' )" ]]; then
echo "removing close dict"
sed -i "" -e "${Line_Num}d" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
Edit_Status=2
Line_Num=$((Line_Num - 1))
fi

if [[ ${Edit_Status} -eq 2 ]] && [[ "$(sed -n "${Line_Num}p" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist | awk '//array/' )" ]]; then
echo "removing close array"
sed -i "" -e "${Line_Num}d" ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
Edit_Status=3
fi

if [[ ${Edit_Status} -eq 3 ]]; then
echo "successful edit detected adding additional info"
cat ${Template_Plist} >> ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
echo >> ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
else
echo "unsuccessful edit detected restoring to original"
cp ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.OLD ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
fi
}

##### MAIN PROGRAM STARTS HERE #####

if Plist_Exists; then
echo "launchservices detected"
else
echo "no launchservices detected importing empty launchservices"
mkdir -p ~/Library/Preferences/com.apple.LaunchServices/
cp $Empty_Plist ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist
fi

if Not_Configured; then
echo "not configured, starting configuration"
Configure_Plist
else
echo "already configured exiting"
fi

##### MAIN PROGRAM ENDS HERE #####

rtrouton
Valued Contributor III

I've now built an Automator application to handle this. It uses a script based on @Josh.Smith's and includes an embedded duti binary in the application. It's available via the link below:

https://github.com/rtrouton/set_microsoft_outlook_as_default_application

I've also written a post about it:

Setting Microsoft Outlook as the default application for email, contacts and calendars via Automator

Xopher
New Contributor III

@rtrouton
Thanks your work its much appreciated. Can I ask about a Casper deployment recommendation? I figure package it up and run 'once per user' at login unless it only needs to be run 'once period' under a default admin account? That is the part I’m not clear on. If run 'once period' for example, then I can just add to 2016 install workflow where it runs post install, before a user is involved.
Thanks again

Look
Valued Contributor III

App defaults are per user. I don't think JAMF's "Once per user" option is "Once per user per machine" (unless something has changed) which makes it not so useful...
You best bet if your using some kind of Exchange Autoconfig is to tag it onto the end ofthat process.

mm2270
Legendary Contributor II

deadlast
New Contributor

I have a non-high-tech solution to this, I just set my browser to call outlook when faced with a mailto function. Works like a charm in the browser.

bkp
New Contributor II

Has anyone tested the plistbuddy script from user gachowski posted 11/30/15?

Now that we're finally upgrading our MSOffice to 2016, this is quickly becoming a major issue.

gachowski
Valued Contributor II

@bkp

I tried it but was having having issues with com.apple.launchservices.secure.plist as it wouldn't let users change to a different mail app and it was messing up other uses of that .plist ... I stopped using it.. :( sorry

I bet if you tested it more you could get it working ... : )

C

bkp
New Contributor II

@gachowski, Thanks for the script... it did lead me in the right direction!

During testing I found a few problems...
1. $username isn't set anywhere. For JAMF, this should be $3
2. There are 2 lines with extra "com.apple.LaunchServices.plist" at the end. If you run the script (with username properly set) it will create an extra file which isn't used by anything and doesn't change anything.
3. The add commands will all fail if the entries exist (which they most certainly will)

I could have tested for the existence of each entry then acted accordingly, but since we just want to overwrite them anyway, it was simpler to delete,add each one.

So, here is my script which has been tested on a few computers and successfully set Outlook 2016 to be the default mail app. (But I wouldn't call it thoroughly tested yet by any stretch.)

Enjoy!
B

#!/bin/bash

# clear old LaunchServices
# DO NOT USE...
#/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -all local,system,user

# Set plist path ($3 = username)
plistPath="/Users/$3/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist"

# Delete the LSHandlers array
# DO NOT USE...
#/usr/libexec/plistbuddy -c "delete:LSHandlers" "$plistPath" >/dev/null 2>&1

echo "Setting Outlook as default Mail app..."

# Delete the entries in case they already exist. Suppress errors if entries do not exist.

# default for mailto links
/usr/libexec/plistbuddy -c "delete:LSHandlers:0:LSHandlerURLScheme" "$plistPath" >/dev/null 2>&1
/usr/libexec/plistbuddy -c "delete:LSHandlers:0:LSHandlerRoleAll" "$plistPath" >/dev/null 2>&1

# default for email
/usr/libexec/plistbuddy -c "delete:LSHandlers:1:LSHandlerContentType" "$plistPath" >/dev/null 2>&1
/usr/libexec/plistbuddy -c "delete:LSHandlers:1:LSHandlerRoleAll" "$plistPath" >/dev/null 2>&1
/usr/libexec/plistbuddy -c "delete:LSHandlers:2:LSHandlerContentType" "$plistPath" >/dev/null 2>&1
/usr/libexec/plistbuddy -c "delete:LSHandlers:2:LSHandlerRoleAll" "$plistPath" >/dev/null 2>&1

# default for .vcard
/usr/libexec/plistbuddy -c "delete:LSHandlers:3:LSHandlerContentType" "$plistPath" >/dev/null 2>&1
/usr/libexec/plistbuddy -c "delete:LSHandlers:3:LSHandlerRoleAll" "$plistPath" >/dev/null 2>&1

# default for .ics files
/usr/libexec/plistbuddy -c "delete:LSHandlers:4:LSHandlerContentType" "$plistPath" >/dev/null 2>&1
/usr/libexec/plistbuddy -c "delete:LSHandlers:4:LSHandlerRoleAll" "$plistPath" >/dev/null 2>&1

# default calendar app
/usr/libexec/plistbuddy -c "delete:LSHandlers:5:LSHandlerContentType" "$plistPath" >/dev/null 2>&1
/usr/libexec/plistbuddy -c "delete:LSHandlers:5:LSHandlerRoleAll" "$plistPath" >/dev/null 2>&1


# Create the entries

# Create the LSHandlers array (suppress errors if exists)
/usr/libexec/plistbuddy -c "add:LSHandlers array" "$plistPath" >/dev/null 2>&1

# Set default for mailto links
/usr/libexec/plistbuddy -c "add:LSHandlers:0:LSHandlerURLScheme string mailto" "$plistPath"
/usr/libexec/plistbuddy -c "add:LSHandlers:0:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"

# Set Outlook as default for email
/usr/libexec/plistbuddy -c "add:LSHandlers:1:LSHandlerContentType string com.apple.mail.email" "$plistPath"
/usr/libexec/plistbuddy -c "add:LSHandlers:1:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"
/usr/libexec/plistbuddy -c "add:LSHandlers:2:LSHandlerContentType string com.microsoft.outlook16.email-message" "$plistPath"
/usr/libexec/plistbuddy -c "add:LSHandlers:2:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"

# Set Outlook as default for .vcard
/usr/libexec/plistbuddy -c "add:LSHandlers:3:LSHandlerContentType string public.vcard" "$plistPath"
/usr/libexec/plistbuddy -c "add:LSHandlers:3:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"

# Set Outlook as default for .ics files
/usr/libexec/plistbuddy -c "add:LSHandlers:4:LSHandlerContentType string com.apple.ical.ics" "$plistPath"
/usr/libexec/plistbuddy -c "add:LSHandlers:4:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"

# Set Outlook as default calendar app
/usr/libexec/plistbuddy -c "add:LSHandlers:5:LSHandlerContentType string com.microsoft.outlook16.icalendar" "$plistPath"
/usr/libexec/plistbuddy -c "add:LSHandlers:5:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"

PhillyPhoto
Contributor III

@bkp - an issue I discovered with your script is it's deleting the Self Service reference. So now SS links prompt for an application to open with. I think it's just because your script goes to a specific point in the array instead of searching for the key you're trying to delete. So if SS is somewhere between 0 & 5, it gets deleted.

bkp
New Contributor II

Arrrg!!! Sorry everyone... ya this doesn't seem to be working for me either any more. I guess I just got lucky on the test machine.

And now that I've been promoted, I honestly don't have time to troubleshoot. I'll pass this along to one of my guys and see what he can figure out.

@gachowski Have you had a chance to work with it any more?

gachowski
Valued Contributor II

Nope, sorry I kinda gave up on it ..

: (

C

kierank
New Contributor

@bkp @gachowski

Messy, but I think I have the script working, any proofreading welcome and appreciated:

High level summary of what's happening...
Iterates through each index, if they are a content type or handler of interest it deletes them. It then adds the handlers after the last index (assumes that if 10 indexes are empty it's the end of the list, there might be a better way to do this).

#!/bin/bash

DEBUG=false
DEBUG_PATH=~/Desktop/debug.csv
DEBUG_DRYRUN=false

i=0;
dnecount=0;
services=(mailto com.apple.mail.email public.vcard com.apple.ical.ics com.microsoft.outlook16.icalendar) # services array
plistPath="/Users/$3/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist"


if $DEBUG; then
    echo "!!!!!!!!!! LIST BEFORE !!!!!!!!!!"
    /usr/libexec/plistbuddy -c "print:LSHandlers" "$plistPath"
    echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
fi

#
# Deletes LaunchServices Entries if they are in array "services"
#
if $DEBUG; then echo "Index,Scheme/ContentType,Role" > $DEBUG_PATH; fi #DEBUG
while true; do

    result=$(/usr/libexec/plistbuddy -c "print:LSHandlers:$i" "$plistPath">/dev/null 2>&1)
    commandResult=$?

    if [ $commandResult -ne 0 ]; then # Check if result command had an error -- this is when we want to stop
        if $DEBUG; then echo "Command Error Number $dnecount"; fi #DEBUG
        ((dnecount++))
        if [ $dnecount -gt 9 ]; then
            if $DEBUG; then echo "Breaking..."; fi #DEBUG
            break
        fi
    else
        dnecount=0;
        scheme=$(/usr/libexec/plistbuddy -c "print:LSHandlers:$i" "/Users/$3/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist" | grep -m1 "LSHandlerURLScheme" | cut -d"=" -f 2 | sed 's/ //g')
        contentType=$(/usr/libexec/plistbuddy -c "print:LSHandlers:$i" "/Users/$3/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist" | grep -m1 "LSHandlerContentType" | cut -d"=" -f 2 | sed 's/ //g')
        role=$(/usr/libexec/plistbuddy -c "print:LSHandlers:$i" "/Users/$3/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist" | grep -m1 "LSHandlerRoleAll" | cut -d"=" -f 2 | sed 's/ //g')

        if [[ " ${services[@]} " =~ " ${scheme} " ]] || [[ " ${services[@]} " =~ " ${contentType} " ]]; then # Check if scheme is in our scheme array 
            if $DEBUG; then echo "Scheme Found: $scheme. Deleting..."; fi #DEBUG
            if $DEBUG_DRYRUN; then
                echo "Dry run, not deleting entries..." # donothing
            else
                /usr/libexec/plistbuddy -c "delete:LSHandlers:${i}:LSHandlerURLScheme" "$plistPath" >/dev/null 2>&1
                /usr/libexec/plistbuddy -c "delete:LSHandlers:${i}:LSHandlerContentType" "$plistPath" >/dev/null 2>&1
                /usr/libexec/plistbuddy -c "delete:LSHandlers:${i}:LSHandlerRoleAll" "$plistPath" >/dev/null 2>&1
            fi
        fi

        if $DEBUG; then echo "$i,$scheme$contentType,$role" >> $DEBUG_PATH; fi #DEBUG
    fi
    ((i++))
done

if $DEBUG_DRYRUN; then
    echo "Dry run, not modifying plist..." #donothing
else
    ((i-=9)) # Return index back to where values cease
    # Create the entries

    # Create the LSHandlers array (suppress errors if exists)
    /usr/libexec/plistbuddy -c "add:LSHandlers array" "$plistPath" >/dev/null 2>&1

    # Set default for mailto links
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerURLScheme string mailto" "$plistPath"
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"
    #/usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerPreferredVersions:LSHandlerRoleAll string -" "$plistPath"

    # Set Outlook as default for email
    ((i++)) # increment index
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerContentType string com.apple.mail.email" "$plistPath"
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"
    #/usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerPreferredVersions:LSHandlerRoleAll string -" "$plistPath"
    ((i++)) # increment index
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerContentType string com.microsoft.outlook16.email-message" "$plistPath"
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"
    #/usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerPreferredVersions:LSHandlerRoleAll string -" "$plistPath"

    # Set Outlook as default for .vcard
    ((i++)) # increment index
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerContentType string public.vcard" "$plistPath"
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"
    #/usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerPreferredVersions:LSHandlerRoleAll string -" "$plistPath"

    # Set Outlook as default for .ics files
    ((i++)) # increment index
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerContentType string com.apple.ical.ics" "$plistPath"
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"
    #/usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerPreferredVersions:LSHandlerRoleAll string -" "$plistPath"

    # Set Outlook as default calendar app
    ((i++)) # increment index
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerContentType string com.microsoft.outlook16.icalendar" "$plistPath"
    /usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerRoleAll string com.microsoft.outlook" "$plistPath"
    #/usr/libexec/plistbuddy -c "add:LSHandlers:${i}:LSHandlerPreferredVersions:LSHandlerRoleAll string -" "$plistPath"

    if $DEBUG; then
        echo "!!!!!!!!!!  LIST AFTER !!!!!!!!!!"
        /usr/libexec/plistbuddy -c "print:LSHandlers" "$plistPath"
        echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    fi
fi

thoule
Valued Contributor II

Your script looks good and it's changing the plist as designed. I rewrote it to scan for the most recently used email app and set that to the default. Problem is that launchServices doesn't appear to be reading this plist. It does save data there if I change via Apple's Mail preferences. I've done the lsregister -kill -r command to rebuild launchservices database, but it still won't read in the new setting - even after multiple reboots and threats of reformatting. If you come up with a way for the Mac to actually read this setting, I'd love to hear it.

thoule
Valued Contributor II

I spoke with an Apple Engineer who told me settings need to be done via LaunchServices API - a plist edit won't do it, although you can see them in com.apple.launchservices.secure.plist.

So I wrote a program to make those API calls. https://github.com/tmhoule/LaunchSetter It's version 0.1 . Seems to work well despite plenty to do to make it easier to use. Feedback welcomed. Especially positive feedback. 007cef7e0b6747c78de53f457f3a53d5

ClassicII
Contributor III

@thoule Did you use this on 10.12 ? I am getting some errors while trying to run the "get https" or any other function.

Thanks!

thoule
Valued Contributor II

Yes - I'm running it on 10.12. Haven't seen any issues. please post errors to the github issues tracker and I'll take a look.

Also, here's a python script to set outlook as the default mailto handler. Run it as the user with a LaunchA - don't run as a JSS script or you'll set the default email program for user 'root'.

#!/usr/bin/python

##Import Launch Services framework
from LaunchServices import *

##Set default application for "mailto://" scheme
LSSetDefaultHandlerForURLScheme("mailto", "com.microsoft.Outlook")

apizz
Valued Contributor

I also found this duti clone using Swift: https://github.com/ftiff/cdef

Works for our purposes.

ClassicII
Contributor III

@thoule

That python script worked perfectly thank you very much for posting it!!!

DanJ_LRSFC
Contributor II

@thoule would using sudo with the -u option to specify the username not work, to launch the Python script in the correct context?

Also, is that the only command needed to make Outlook 2016 the default, or are some other calls such as LSSetDefaultRoleHandlerForContentType needed as well?

scheb
New Contributor III

@DanJ_LRSFC I was able to get this working:

#!/bin/bash

userName=$(stat -f %Su /dev/console)

py_script="
##Import Launch Services framework
from LaunchServices import *

##Set default application for "mailto://" scheme
LSSetDefaultHandlerForURLScheme("mailto", "com.microsoft.Outlook")
"

sudo -u $userName -H python -c "$py_script"

Also, I manually changed the default mail client in the Mail.app preferences from Mail to Outlook, and when I did a compare of the com.apple.launchservices.secure.plist file before and after, only the mailto had changed.

HTH,

Adam

PhillyPhoto
Contributor III

@thoule & @scheb - This is my script, building off yours. This will also set Outlook to handle emails, contacts and calendar files.

#!/bin/bash

userName=$(stat -f %Su /dev/console)

py_script="
from LaunchServices import LSSetDefaultRoleHandlerForContentType
from LaunchServices import LSSetDefaultHandlerForURLScheme
LSSetDefaultHandlerForURLScheme('mailto', 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('com.apple.mail.email', 0x00000002, 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('public.vcard', 0x00000002, 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('com.apple.ical.ics', 0x00000002, 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('com.microsoft.outlook16.icalendar', 0x00000002, 'com.microsoft.Outlook')
"
echo "Configuring mail settings for "$userName
sudo -u $userName -H python -c "$py_script"

I also came across these tools that includes one to set Outlook as the default. Testing it out, it seems to only configure mailto, so I'm sticking with my more complete script.

ClassicII
Contributor III

The mailto works great but still having a heck of a time trying to figure out how to make outlook the default cal opener. The script above does not work for cal. :(

JustDeWon
Contributor III

@ClassicII .. This should help you out with that... It works for the calendar as well..

tlarkin
Honored Contributor
Also, here's a python script to set outlook as the default mailto handler. Run it as the user with a LaunchA - don't run as a JSS script or you'll set the default email program for user 'root'.

original code:

#!/usr/bin/python

##Import Launch Services framework
from LaunchServices import *

##Set default application for "mailto://" scheme
LSSetDefaultHandlerForURLScheme("mailto", "com.microsoft.Outlook")

You can get around this with out having to run auser from launchctl I think I do not have outlook to test though. You could try this:

modified code:

#!/usr/bin/python
from LaunchServices import *
from SystemConfiguration import SCDynamicStoreCopyConsoleUser
from Foundation import NSHomeDirectoryForUser

currentuser, uid, gid = SCDynamicStoreCopyConsoleUser(None, None, None)
home_folder = NSHomeDirectoryForUser(currentuser)
domain = str('%s' + '/Library/Preferences/com.microsoft.Outlook') % (home_folder)
LSSetDefaultHandlerForURLScheme("mailto", domain)

Someone will have to test this though as I have no idea if this works, I don't use Outlook.

john_bio
New Contributor III

Based on the above i seem to have something thats working.

This can be run through the JSS as a policy, and will run as the correct user although it should only run on the login trigger to ensure that the policy does not run on the login screen without a user actually logged in.

#!/bin/sh
loggedInUser=`python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`
echo "Running for user ${loggedInUser}"

# Some installs of OS X seem to be missing PyObjC but others done.
# Will try and install to ensure the rest of the script does not fail.
easy_install -pip
su ${loggedInUser} -c 'pip install pyobjc --user --quiet'

# Apples recommended method for working out the currently logged in user. 
# Using Python to call the ObjC system call that will return the actual user even if run as root.
# https://developer.apple.com/library/content/qa/qa1133/_index.html
loggedInUser=`python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`

# Define the contents of a python script here that sets Outlook
# as the default client to Send as E-Mail in other apps, as well
# as open .ics calendar files and .vcard contact files.
py_script="
import os
import sys

from LaunchServices import *

##Set default application for 'mailto://' scheme
LSSetDefaultHandlerForURLScheme('mailto', 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('com.apple.mail.email', 0x00000002, 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('public.vcard', 0x00000002, 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('com.apple.ical.ics', 0x00000002, 'com.microsoft.Outlook')
LSSetDefaultRoleHandlerForContentType('com.microsoft.outlook16.icalendar', 0x00000002, 'com.microsoft.Outlook')
"

# Run the above python as the currently logged in console user.
sudo -u ${loggedInUser} -H python -c "$py_script"

rapa
New Contributor II

I tried this with macOS 10.12.6 and Outlook 15.41 .... no luck :-(