Custom Screensavers in Sonoma

New Contributor III

Previously the script below from another message made it possible to have custom screensaver files (Photos) that would rotate.  This no longer works in macOS Sonoma.  Does anyone know a new method to have the screensaver call photos from a particular folder in somona via a script or another way.


## get current user
user=`ls -l /dev/console | cut -d " " -f 4`

## get macOS version(s)
osMajor=$(/usr/bin/sw_vers -productVersion | /usr/bin/awk -F"." '{print $2}')
osMinor=$(/usr/bin/sw_vers -productVersion | /usr/bin/awk -F"." '{print $3}')

## set key items for screensaver
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write CleanExit -string "YES"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write PrefsVersion -int 100
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write showClock -string "NO"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write idleTime -int 60

## configure screensaver framework based on macOS version
if [[ $osMajor -eq 14 ]] && [[ $osMinor -ge 2 ]]; then
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex" type -int 0
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0

## additional configuration settings for screensaver framework
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write tokenRemovalAction -int 0
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write LastViewedPhotoPath -string ""
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write SelectedFolderPath -string "/Users/Shared/Screensaver"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write SelectedSource -int 3
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write ShufflesPhotos -bool "false"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write styleKey -string "Classic"
/usr/bin/sudo /usr/bin/killall -hup cfprefsd
exit 0


Valued Contributor II

This one has been a real butt kicker. Using the scripts found here: I created a workflow that we have been able to use to set our screen saver to some images that run as a slideshow. We distribute the new screen saver assets using a package, which deploys the images to /Library/Screen Savers/Default Collections/ScreenSaver. The scripts from itjimbo work pretty well but I noticed that there was one key piece of information that appeared to be left out of the setup process. That was the path to the screen saver assets. Oddly, just using the script called "Set Screen Saver and Keep User's Wallpaper" after running the first script to get the base64 encoded in the plist file at ~/Library/Application Support/ and adding the base64 to the second script, it worked, but on some computers the screen saver would switch to just a series of colors. These colors are from the png files located at /System/Library/Screen Savers/Default Collections. It seems that macOS will just revert to this default location if it doesn't know where to look for images. I took our working script that we used with macOS Ventura and changed the path to the iLifeSlideshows component from /System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex to /System/Library/ExtensionKit/Extensions/iLifeSlideshows.appex. The old script also had steps to write the key preferences we needed including the path to the screen saver assets. So far, the combination of the "Set Screen Saver and Keep User's Wallpaper" running first then our original script modified to work with Sonoma appears to be working. I'm sure it won't be 100% glitch free but after some tweaking, I think we may have our solution.

View solution in original post


Contributor II

Also interested in this very thing...

New Contributor III

Try to use Ssaver by liquidx webviewscreensaver from github

New Contributor II

following this as well

New Contributor III

why not set screensaver based on the ilifeslideshow location?

#Created by Chris Mariano
#Screensaver script for Jamf Pro
#Last updated: 2023-Oct-06
#Added Sonoma support

#set variables
current_user=$(stat -f "%Su" /dev/console)
photoloc= ##set image location here

#set screensaver preferences    
sudo -u "$current_user" defaults write CleanExit -string "YES"
sudo -u "$current_user" defaults write PrefsVersion -int 100
sudo -u "$current_user" defaults write showClock -string "NO"
sudo -u "$current_user" defaults write idleTime -int 600

#set screensaver to iLifeSlideshows
if [ -d "$scr10" ]; then
    echo "$scr10 exists."
    sudo -u "$current_user" defaults write moduleDict -dict moduleName -string "iLifeSlideshows" path -string $scr10 type -int 0
elif [ -d "$scr12" ]; then
    echo "$scr12 exists."
    sudo -u "$current_user" defaults write moduleDict -dict moduleName -string "iLifeSlideshows" path -string $scr12 type -int 0
elif [ -d "$scr14" ]; then
    echo "$scr14 exists."
    sudo -u "$current_user" defaults write moduleDict -dict moduleName -string "iLifeSlideshows" path -string $scr14 type -int 0

#set screensaver preferences    
sudo -u "$current_user" defaults write tokenRemovalAction -int 0
sudo -u "$current_user" defaults write LastViewedPhotoPath -string ""
sudo -u "$current_user" defaults write SelectedFolderPath -string $photoloc
sudo -u "$current_user" defaults write SelectedSource -int 3
sudo -u "$current_user" defaults write ShufflesPhotos -bool "false"
sudo -u "$current_user" defaults write styleKey -string "Classic"

#kill cfprefsd
sudo -u "$current_user" killall cfprefsd
killall cfprefsd
echo "Configuration updated successfully for user00: $current_user"
exit 0



New Contributor III

Thanks, I will try this out in our test environment, but I will not be able to do that until Tuesday.

The script does set the settings as show, the .plist files are created in ~/Library/Preferences.

However, it does not set the screen saver to match these settings. For me, the saver keeps the settings it already had, in this case, the default out of box settings.

Anyone see something different?

New Contributor III

I agree with this, and I also believe that the plist are located in ~/Library/Preferences/ByHost with the UDID as part of the plist name. I changed them but the screensaver still keeps the default.

New Contributor III

I tested this script this morning and it does not change from the default screensavers in Sonoma.    I did make sure to set the photoloc= variable. 

New Contributor III

Following this topic.  I'd just like to find a way to shuffle the builtin landscape desktops/screensavers.

Valued Contributor II

we have a ticket open wit Apple as this no longer works, so far nothing from them

New Contributor II

I just did some testing and got my Custom Folder screensaver to set via a config profile. I drop the images via pkg and run the script I have been using previously. When I set the config profile with the below setting my Image folder was already selected in system settings in the Photos screensaver. I am going to test this on a few others to see if it duplicates or I am just specialScreenshot 2023-10-13 at 3.33.53 PM.png

Any further info? We tried exactly that and it did not work. Where did you drop the images?

We opened a case with Apple and have some info, will post the full exchange.

New Contributor II

Turns out I couldn't duplicate it. I can makes the photos screen saver point to the folder of images I want but can't get it to change screensavers from Sonoma Horizon to Photos without intervention

Our email exchange with Apple on this. Apple replies are in Italics.

Hello –

Have some questions on Screen Savers in macOS Sonoma.

In prior OS’s we are setting some custom .plist keys located in ~/Library/Preferences:

This gave us the ability point the photo screen saver to a local folder and display corporate content/messages.

With Sonoma, this is no longer working.

Setting the keys does nothing.

Also, have noticed that when setting a similar config manually through the Screen Saver System Settings GUI, it does create such files in a new location:


When we attempt to set the same keys there via script, the .plist files are there, but the settings in the GUI never change and activating the screen saver does not show our images.

Saw that the iLifeSlideShows.appex location had changed in Sonoma, so accounted for that as well.

Is this method of setting a screen saver config no longer an option?

Will we not be able to do something similar with macOS Sonoma?

Any advice, helpful info on this?



Thank you for your email. 

I understand that when using the script to change the screensaver in macOS Sonoma, the script is not working as expected. If my understanding is incorrect, please let me know. 


After investigating this, it seems that the commands are not supported anymore in macOS Sonoma and instead of using the commands, Apple’s MDM protocol provides a Screensaver payload which can be used to configure which module is used by the system.


Each MDM will have their own method for setting these values in your configuration profile. If you let me know which MDM you are utilising I can search for an appropriate document to provide for this payload.


As always, let me know if you have any questions, additional information or concerns.



Hello –

Using Jamf Pro.

Yes, we are aware of this MDM payload, however it does not give the choice of selecting a custom folder or apply the desired “classic” effect of using a location with multiple photos to shuffle through.

It would appear that one can only use a “.saver” type of module, please correct me if I am wrong.

I am assuming one could not just create a folder at this location, drop pictures into it and then use the Config. Profile to point to that Fidelity created folder? Or can you…?

Image below of the default setting when you check the box next to ‘Start screen saver after:’ under the ‘Login Window’ Config. Profile setting.


Thank you for additional information.

The documentation states the supported screen saver format is .saver 

  <string>/System/Library/Screen Savers/Example-Name.saver</string>

I have also attempted to create a folder for pictures and pointed config profile to that path, however I was not successful therefore I can confirm that as mentioned above you will need to use .saver format.



Yeah, I am unable to create a folder in that location (or copy a file) which I assume is by design.

So, what about the path below? Can a .saver file be dropped there and use the Config. Profile to point to it as its path?

/Library/Screen Savers




Thank you for your patience.

I have done few tests using two MDMs Jamf and WorkSpaceOne and I have noticed that there seems to be an issue when trying to configure the path to a screen server using Jamf. From what I see the profiles created by Jamf are missing “moduleName” which is mandatory -


Please see the test and the results below:


Screen saver used during test:

  build in  macOS “hello.saver”

  3rd party called “Noise.saver”


1 Used Jamf to set up screen saver - failed ( as mentioned above ) 

2 Then I used WSOne 



- defined default path to build in screen saver:

/System/Library/Screen Savers/Hello.saver  - work as expected


- defined custom path to system screen saver ( copied system screen saver to Shared folder)

/Users/Shared/Screen Savers/Hello.saver  - work as expected


- defined custom path to custom 3rd party screen saver 

/Users/Shared/Screen Savers/Noise.saver  - work as expected


- defined custom path to custom 3rd party screen saver 

/Library/Screen Savers/Noise.saver  - work as expected 


Based on the mentioned test you can specify custom location to the either build in or 3rd party screensaver and that should work.


I hope that helps and please let me know if that is working for you.



So you are saying the location we inquired on, /Library/Screen Savers can be used to hold a .saver file, and be used……but that the Config. Profile from Jamf is lacking the ability to call any .saver file from any location?

Whether the built in OS location of /System/Library/Screen Savers or somewhere else entirely?

Or, another way, It can’t specify any module, so the location as of now, does not matter as the Jamf pushed setting can’t set the .saver at any location?


You mention:

So you are saying the location we inquired on, /Library/Screen Savers can be used to hold a .saver file, and be used……but that the Config. Profile from Jamf is lacking the ability to call any .saver file from any location?


I can confirm that during my tests I was able to use the location you mention for the screen saver ( see screenshot attached ) - the profile I used was compliant with the . During my tests I noticed that the profile I created using Jamf was missing required moduleName key and was not working as expected.


If you are setting screen saver using Jamf and this is not working for you it likely may be the reason. If this is the case please submit the ticket with Jamf Support for further investigation.


Whether the built in OS location of /System/Library/Screen Savers or somewhere else entirely?  I understand that you want to know where default macOS screen savers are stored. This is the location ( but is SIP protected ).


Or, another way, It can’t specify any module, so the location as of now, does not matter as the Jamf pushed setting can’t set the .saver at any location?  As mentioned above during my tests I was not successful to set any Screen Saver location ( using Jamf generated profile ) but when I used profile that is compliant with recommendation form I was able to set the screen saver in the various locations as mentioned in my previously email. 


If you are using Jamf to create the profile please download the profile and verify if moduleName key is present in the profile,  if not please reach out to Jamf.

In case you need assistance verifying if the moduleName key is missing please let me know and provide the profile copy you are using.

So beyond the apparent Jamf Config. Profile issue it looks like the options are to create a .saver file that somehow points to a folder of images (is that even a thing?) or create a .saver file with the images each time we want them to change. 

Unless someone has a better solution? 

New Contributor III


I am facing the same issue, and haven't found a solution yet.
I also contacted Apple and was given the same solution, which is to create a .saver file that points to a folder with the images that you want to set as screensaver.
I haven't found the time to test this yet, but I'll do that as soon as I have a minute this week.

New Contributor II

For the general question of "how to set screensaver options in Sonoma", we've discovered some solutions by reverse-engineering the new Sonoma screensaver plist.

Discussion here:

New Contributor III

Any luck on custom screensaver on macOS Sonoma?

Shri Sivakumaran

New Contributor II

If you are willing to go the paid route and need a screensaver now, iScreensaver 6.8.6 has full support for macOS Sonoma, and lets you sequence images, movies, 3D models (GLB format) etc.



New Contributor II


I was able to set Wallpaper and Screen saver in Sonoma with a mix of above comments.

I was already using ilifeslideshow to set screen savers for previous macOS versions.

Assuming that I use one picture by brand for both wallpaper and screen saver.

The example below is for one brand.

Picture is located in /Library/Pictures/Brand1.extension1

It is also copied in /Library/Screen Savers/Default Collections/Brand1/Brand1.extension1

Now set manually your wallpaper (for me center + right color for background) and screen saver settings (I choose Brand1 as source and Shifting Tiles as Style) for Brand1 and export ~/Library/Application Support/ and rename it to "Index Brand1.plist"


Make a package in composer containing :


/Library/Pictures/Index/Index Brand1.plist


Create a script



# Identify connected user
user=`ls -la /dev/console | cut -d " " -f 4`

# Modify Screen saver for 14.x
cp "/Library/Pictures/Brand1.Extension1" "/Library/Screen Savers/Default Collections/Brand1/Brand1.Extension1"

sudo -u $user defaults -currentHost write moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex" type -int 0
sudo -u $user defaults -currentHost write idleTime -int 300
sudo -u $user defaults -currentHost write tokenRemovalAction -int 0
sudo -u $user defaults -currentHost write LastViewedPhotoPath -string ""
sudo -u $user defaults -currentHost write SelectedFolderPath -string "/Library/Screen Savers/Default Collections/${Picture2}"
sudo -u $user defaults -currentHost write SelectedSource -int 3
sudo -u $user defaults -currentHost write styleKey -string "ShiftingTiles"

# Set Wallpaper and Screen saver for 14.x
cp "/Library/Pictures/Index/Index Brand1.plist" "/Users/$user/Library/Application Support/"

killall WallpaperAgent

exit 0



And finally create a policy with the package and the script above.

Not sure it is very clear but hope it helps.

New Contributor III

Just so that I am clear,  Did you create this package and script and still have to manually select your wallpaper and screensaver on the machines in System Settings?

New Contributor II

No you begin to set them manually on a test mac in order to retrieve the Index.plist containing all settings regarding the wallpaper and the screen saver.

Once done, you can use the policy (with the script and the package) to deploy the same wallpaper and screen saver  (with the same settings) on all your macs.


Just saw an "error" in the script :

Replace :

sudo -u $user defaults -currentHost write SelectedFolderPath -string "/Library/Screen Savers/Default Collections/${Picture2}"


With :

sudo -u $user defaults -currentHost write SelectedFolderPath -string "/Library/Screen Savers/Default Collections/Brand1"


New Contributor II
New Contributor II

Hey All,


I have found the following scripts on the MacAdmin slack channel that seem to work.

Basically, there are two steps that need to be completed.


Step 1: Set the Screensaver on a test device manually and run the following script to pull the Base64 code of the settings:



loggedInUser=$(/usr/bin/stat -f%Su /dev/console)
wallpaper_store_path="/Users/${loggedInUser}/Library/Application Support/"

getWallpaperBase64=$(plutil -extract AllSpacesAndDisplays xml1 -o - "${wallpaper_store_path}" | awk '/<data>/,/<\/data>/' | xargs | tr -d " " | tr "<" "\n" | head -2 | tail -1 | cut -c6-)
echo "wallpaperBase64: ${getWallpaperBase64}"

getWallpaperLocation=$(plutil -extract AllSpacesAndDisplays xml1 -o - "${wallpaper_store_path}" | grep -A 2 "relative" | head -2 | tail -1 | xargs | cut -c9- | rev | cut -c10- | rev)
echo "wallpaperLocation: ${getWallpaperLocation}"

getScreensaverBase64=$(plutil -extract AllSpacesAndDisplays xml1 -o - "${wallpaper_store_path}" | awk '/<data>/,/<\/data>/' | xargs | tr -d " " | tr "<" "\n" | tail -2 | head -1 | cut -c6-)
echo "screensaverBase64: ${getScreensaverBase64}"



Step 2: From there, update lines 9 & 10 with the Base64 code that we just got, and then push out the following script in a policy:



# Do not edit these variables.
loggedInUser=$(/usr/bin/stat -f%Su /dev/console)
wallpaper_store_path="/Users/${loggedInUser}/Library/Application Support/"
current_RFC3339_UTC_date="$(date -u '+%FT%TZ')"

# Input the data from the 'Get Screen Saver and Wallpaper Settings' script to the variables below.

# Index.plist contents.
aerial_desktop_and_screensaver_settings_plist="$(plutil -create xml1 - |
	plutil -insert 'Desktop' -dictionary -o - - |
	plutil -insert 'Desktop.Content' -dictionary -o - - |
	plutil -insert 'Desktop.Content.Choices' -array -o - - |
	plutil -insert 'Desktop.Content.Choices' -dictionary -append -o - - |
	plutil -insert 'Desktop.Content.Choices.0.Configuration' -data "${wallpaperBase64}" -o - - |
	plutil -insert 'Desktop.Content.Choices.0.Files' -array -o - - |
	plutil -insert 'Desktop.Content.Choices.0.Provider' -string '' -o - - |
	plutil -insert 'Desktop.Content.Shuffle' -string '$null' -o - - |
	plutil -insert 'Desktop.LastSet' -date "${current_RFC3339_UTC_date}" -o - - |
	plutil -insert 'Desktop.LastUse' -date "${current_RFC3339_UTC_date}" -o - - |
	plutil -insert 'Idle' -dictionary -o - - |
	plutil -insert 'Idle.Content' -dictionary -o - - |
	plutil -insert 'Idle.Content.Choices' -array -o - - |
	plutil -insert 'Idle.Content.Choices' -dictionary -append -o - - |
	plutil -insert 'Idle.Content.Choices.0.Configuration' -data "${screensaverBase64}" -o - - |
	plutil -insert 'Idle.Content.Choices.0.Files' -array -o - - |
	plutil -insert 'Idle.Content.Choices.0.Provider' -string '' -o - - |
	plutil -insert 'Idle.Content.Shuffle' -string '$null' -o - - |
	plutil -insert 'Idle.LastSet' -date "${current_RFC3339_UTC_date}" -o - - |
	plutil -insert 'Idle.LastUse' -date "${current_RFC3339_UTC_date}" -o - - |
	plutil -insert 'Type' -string 'individual' -o - -)"

# Create the path to the screen saver/wallpaper Index.plist.
mkdir -p "${wallpaper_store_path}"

# Create the Index.plist
plutil -create binary1 - |
	plutil -insert 'AllSpacesAndDisplays' -xml "${aerial_desktop_and_screensaver_settings_plist}" -o - - |
	plutil -insert 'Displays' -dictionary -o - - |
	plutil -insert 'Spaces' -dictionary -o - - |
	plutil -insert 'SystemDefault' -xml "${aerial_desktop_and_screensaver_settings_plist}" -o "${wallpaper_store_path}/Index.plist" -

# Kill the wallpaperAgent to refresh and apply the screen saver/wallpaper settings.
killall WallpaperAgent



Make sure to also package up the images to the location that was set on the test device as well

Valued Contributor II

Doesnt work at all, its is ignoring my base64 settings for the wallpaper and screensaver and setting Sonoma for both.

Hey @tkimpton,

This has worked for me in testing. This script will only set the screensaver. There is a different script in the MacAdmins chat to set the wallpaper as well.

Valued Contributor II

@mattcherson ive tested this in my test environment a ridiculous amount of times and it doesnt work for me. iscreensaver does work and i can verify on that.

Thanks for posting this! I followed the steps as provided in the Mac Admins Slack post and the settings were changed as expected on my test Mac and on my production Mac.

Worked for me....setup a base device how I wanted it and ran the Pull Base64 the info from the logs in Jamf and pasted it into the two fields for the code in step two and ran as tested successfully on both Apple and Intel silicon as well.

For some of my test users (myself included), instead of seeing the images we placed in the screen saver assets folder, they see the colors pngs located at /System/Library/Screen Savers/Default Collections/4 - Colors. The slack thread talking about this solution mentioned it too. This doesn't happen a lot but it happens often enough to make me want to find a way to fix it. That's what I will be working on today. Out of all of the possibilities for solution for macOS Sonoma that I have explored, I think this one has the best potential to be the solution. If companies would lose their obsession with putting screen savers on everyone's computer that they won't actually sit and look at that would be the best fix!

Contributor II

So far in our hope for a resolution, we have tried the following, after speaking with Jamf:

Jamf confirmed that the two PI's (PI109698 - PI-010337 and PI100636 - PI-006185) are still unresolved. Both affect the ability for Jamf to set the screen saver .saver location.

Jamf provided us with two .plist files to be used as a custom Config. Profile with the .saver path required.

We had an in-house iOS Dev create a .saver file for us via Xcode, this .saver file says to look to /Users/Shared/Screensavers folder location for the image files.

We then placed some random .png files to that location.

We then dropped the CustomCompany.saver to: Library/Screen Savers via a Composer created .pkg.

Sonoma sees the custom.saver, sets it with the two provided .plist files from Jamf and shows it in the GUI as the default.

It also locks the Screen Saver System Settings Pane marking it as "this setting has been configured by a profile".
However, we message below when it tries to run/start:


Best guess is the .saver file needs to be Notarized but this is not a normal workflow for the iOS Dev so they are looking into it.


New Contributor II

Several thoughts:

  1. As described Here the base64-encoded binary plist stores the absolute path name to the screensaver file; this means that if the .saver file is stored in /Users/[username]/Library/Screen Savers/ you would have to recreate the plist file for every individual user. To avoid that, you would want to install it to /Library/Screen Savers/ instead.
  2. If the .saver file is not code-signed and notarized, it may have file attributes inside it which put it in quarantine.  You can try xattr -rc /path/to/screensaver   to clear the quarantine flags.
  3. If you just need to get something working today, you can do a test using iScreensaver  (Download link:  )  which offers an unlimited free demonstration trial,  30 day money back guarantee upon purchasing.    iScreensaver 6.8.6 and higher automatically solve all these issues for macOS Sonoma.

Valued Contributor II

@iScreensaver thanks very much :)

Hey @iScreensaver ,

Thank you for this!

In my testing I did have the .saver file saving to /Library/Screen Savers/

So that might be why it was working in my instance

There's also some evidence that not only do you need to set the new Sonoma plist located at   ~/Library/Application Support/ 

You must also set up the old (pre-Sonoma) plist like this

defaults -currentHost write moduleDict -dict moduleName "MyScreensaver" path "/Library/Screen Savers/MyScreensaver.saver" type 0


Note that both of these would need to be set for each user account.

New Contributor II

Hi all,

What if I just want to put the classic Sonoma wallpaper to the desktop and login? How would I script that?



thanks :)



New Contributor

If anyone is still looking to configure/deploy screensavers on Sonoma, the solution put forth by Marc Bevin is working as of Sonoma 14.3.

I will have to test that out. thanks.

What kind of solution he offered. Where can I see it?

New Contributor III

Review the entire topic and look for the entries from Marc Bevin.  If you test it before me, let me know how it goes.