Programatically Adding Spotlight Exclusions

Spotlight has two types of exclusions: Volumes and Directories

I’m executing everything as root here, as I assume these commands will usually be executed by some management software that has Full Disk Access and Root Access.

This post is Catalina specific, since the VolumeConfiguration.plist file is in a different location on previous macOS releases. This is due to the movement of / to /System/Volumes/Data

Volumes can be added and removed as exclusions from Spotlight (while not appearing in System Preferences) with a simple

mdutil -i off "VolumeDirectory"

Directories however are not so simple. If we try the same thing with a directory, we get the error

MBP:~ dan.c$ mdutil -i off "/Users/dan.c/Desktop"

/System/Volumes/Data/Users/dan.c/Desktop:

Error: invalid operation.

Error: unknown indexing state.

The solution is to directly edit /System/Volumes/Data/.Spotlight-V100/VolumeConfiguration.plist

Since defaults doesn’t allow us to read arbitrary plist files (for some reason, if there is a way, please let me know!), we need to use plutil. This gets a bit awkward but it should be possible to programatically add and remove array items with a little bit of bash scripting.

We can add directories like this:

plutil -insert Exclusions.0 -string '/Users/dan.c/Desktop' /System/Volumes/Data/.Spotlight-V100/VolumeConfiguration.plist

and then we need to restart mds:

launchctl stop com.apple.metadata.mds && launchctl start com.apple.metadata.mds

If you load up System Preferences and look in Spotlight > Privacy, we can now see our exclusion has been added.

Using Exclusions.0 over and over again keeps adding to the top of our array, which isn’t really a problem. However, if we want to remove an item, we need to find the string that we want to remove and then remove it by index. See below for an example.

Adding To Array

!/bin/bash
launchctl stop com.apple.metadata.mds && launchctl start com.apple.metadata.mds
vers=$( sw_vers | grep BuildVersion | awk '{print substr($2,0,2)}' )
sdir="/.Spotlight-V100"
if [[ "${vers}" > "18" ]]; then
sdir="/System/Volumes/Data${sdir}"
fi
cd "${sdir}"
# First let's check if the directory we're adding already exists
search_string=$1
let index="`plutil -extract Exclusions xml1 -o - VolumeConfiguration.plist | grep string | grep -wn "${search_string}" | cut -d ':' -f 1` - 1"
if [ $index -lt 0 ]; then
echo Not in array, let\'s add it in.
plutil -insert Exclusions.0 -string ${search_string} "${sdir}/VolumeConfiguration.plist"
else
echo Already in array, not doing anything.
fi
# Now we restart mds to apply the changes
launchctl stop com.apple.metadata.mds && launchctl start com.apple.metadata.mds

Removing From Array

#!/bin/bash
# We can find the index of the item in the array by extracting the key, finding the lines with
# 'string' in them, and then finding the search string.
cd /System/Volumes/Data/.Spotlight-V100
search_string=$1
let index="`plutil -extract Exclusions xml1 -o - VolumeConfiguration.plist | grep string | grep -wn "${search_string}" | cut -d ':' -f 1` - 1"
echo The index of $search_string is $index
if [ $index -lt 0 ]; then
echo Not in array, not doing anything.
else
echo Found $search_string in array, removing it
plutil -remove Exclusions.${index} /System/Volumes/Data/.Spotlight-V100/VolumeConfiguration.plist
fi
# Now we restart mds to apply the changes
launchctl stop com.apple.metadata.mds && launchctl start com.apple.metadata.mds

Comments

Popular posts from this blog

WireGuard Kernel Module on 64-bit Raspberry Pi Kernel