Setting Custom Screensaver

dennisnardi
Contributor

I'd like to set a photo that's in a specific folder on each computer in my environment to be the screensaver, with the "classic" style. I'd also like to set it once, and then allow users to change it if they wish.

I thought this would be a simple endeavor, but have not had any luck figuring out a successful method. Has anyone done something similar in their environment?

1 ACCEPTED SOLUTION

dennisnardi
Contributor

I found a script somewhere on Jamfnation that ended up working for me. I was able to specify a folder so that the picture(s) that were inside the folder was set to be the screensaver, and the style of screensaver (wall photo, flip book, classic, etc) could be defined.

#!/bin/sh

#  
# Get user logged into console and put into variable "user"
user=`ls -l /dev/console | cut -d " " -f 4`
osMajor=$(sw_vers -productVersion | awk -F"." '{print $2}')
osMinor=$(sw_vers -productVersion | awk -F"." '{print $3}')


sudo -u $user defaults -currentHost write com.apple.screensaver CleanExit -string "YES"
sudo -u $user defaults -currentHost write com.apple.screensaver PrefsVersion -int 100
sudo -u $user defaults -currentHost write com.apple.screensaver showClock -string "NO"
sudo -u $user defaults -currentHost write com.apple.screensaver idleTime -int 600


if [[ $osMajor -eq 14 ]] && [[ $osMinor -ge 2 ]]; then

sudo -u $user defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex" type -int 0

else

sudo -u $user defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0
fi


sudo -u $user defaults -currentHost write com.apple.screensaver tokenRemovalAction -int 0

sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser LastViewedPhotoPath -string ""
sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath -string "/Library/Application Support/JAMF/bin/screensaver"
sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 3

sudo -u $user defaults -currentHost write com.apple.ScreenSaver.iLifeSlideShows styleKey -string "Classic"

sudo killall -hup cfprefsd

View solution in original post

22 REPLIES 22

Captainamerica
Contributor II

Hi,
If running Mojave it will give problems with SIP. So you cannot just go in and edit the screensaver preferences as before in earlier mac version in the default screensavers files for mac OS as SIP will not let you. Of course you can then disable SIP, but probably not something infosec department is interested in your company :)

mconners
Valued Contributor

Hello @dennisnardi not sure the reference to "classic" but we have done is load up the /Library/Desktop Pictures/ folder with our preferred desktop pictures. Then in a configuration profile under restrictions, we lock down the desktop picture to the preferred picture for the given deployment. This has been working well for us on both High Sierra and Mojave.

dennisnardi
Contributor

I found a script somewhere on Jamfnation that ended up working for me. I was able to specify a folder so that the picture(s) that were inside the folder was set to be the screensaver, and the style of screensaver (wall photo, flip book, classic, etc) could be defined.

#!/bin/sh

#  
# Get user logged into console and put into variable "user"
user=`ls -l /dev/console | cut -d " " -f 4`
osMajor=$(sw_vers -productVersion | awk -F"." '{print $2}')
osMinor=$(sw_vers -productVersion | awk -F"." '{print $3}')


sudo -u $user defaults -currentHost write com.apple.screensaver CleanExit -string "YES"
sudo -u $user defaults -currentHost write com.apple.screensaver PrefsVersion -int 100
sudo -u $user defaults -currentHost write com.apple.screensaver showClock -string "NO"
sudo -u $user defaults -currentHost write com.apple.screensaver idleTime -int 600


if [[ $osMajor -eq 14 ]] && [[ $osMinor -ge 2 ]]; then

sudo -u $user defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex" type -int 0

else

sudo -u $user defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0
fi


sudo -u $user defaults -currentHost write com.apple.screensaver tokenRemovalAction -int 0

sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser LastViewedPhotoPath -string ""
sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath -string "/Library/Application Support/JAMF/bin/screensaver"
sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 3

sudo -u $user defaults -currentHost write com.apple.ScreenSaver.iLifeSlideShows styleKey -string "Classic"

sudo killall -hup cfprefsd

mm2270
Legendary Contributor III

It's possible there's some esoteric way to set this with a Config Profile, but then, it would likely be enforced if it was set that way since that's just what profiles tend to do.
These settings live in a couple of ByHost preference files, inside the user directory, so the only way I can think of to set these is with a script, but it has to run some commands as the user for it to really work effectively.

Here's one I whipped together. Not extensively tested, but I did execute the script as root as it would via a Jamf Pro policy and it worked for me. Be sure to change the path at the top for FOLDER_PATH to the actual path of the directory with your images in them.

#!/bin/bash

FOLDER_PATH="/Users/Shared/SSImages" ## Customize this path to the folder with images
FOLDER_NAME="${FOLDER_PATH##*/}"

LOGGED_IN_USER=$(stat -f%Su /dev/console)
LOGGED_IN_UID=$(id -u "$LOGGED_IN_USER")

UUID=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F" '/IOPlatformUUID/{print $4}')

/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" /bin/rm ~/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.${UUID}.plist
/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" defaults -currentHost write com.apple.ScreenSaver.iLifeSlideShows styleKey Classic
/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" defaults -currentHost write com.apple.ScreenSaverPhotoChooser CustomFolderDict -dict identifier "$FOLDER_PATH" name "$FOLDER_NAME"
/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath "$FOLDER_PATH"

Because this has multiple commands all being run as the logged in user, it might be better to set this in a one time login policy or even create a LaunchAgent that runs one time, maybe touches a file to indicate it already ran for that user account and so won't run again on next login or something.

Edit: Heh. Looks like you found a similar script already while I was typing up my response that does the trick. Glad you found a solution.

Captainamerica
Contributor II

Does it work for mojave with sip enabled?

mm2270
Legendary Contributor III

@Captainamerica Yes. These settings are all in the user space, so SIP doesn't come into play here.

Captainamerica
Contributor II

I just tried the script from @dennisnardi and works fine
How it is possible to change the pictures only slide after 5 minutes or similar. Right now they change every 2 seconds or there about

mm2270
Legendary Contributor III

@Captainamerica I don't know if it's possible to adjust those screensavers. The basic ones like "Classic" don't have a control over how fast the transitions happen. If you look at them in the GUI, they only let you choose which folder of images to use. Contrast this by ones like iTunes Artwork, Flurry and couple of others, which have an options control to adjust their behavior. Since it's not available in the GUI, I doubt there's anything you can do to affect them with a script either.

cbruce
New Contributor III

Hello !
Thanks all for the great information. Has anyone worked with SaveHollywood? I am tasked to roll out a custom .mp4 screensaver that has been created using SaveHollywood.
Semi newbee to coding.
Thanks!

jameson
Contributor II

I have used the below for Mojave and worked great. However, not on catalina I have some clients where same script does not work anymore - but some clients work even on Catalina
Anyone seeing the same issue ?

It seems the "classic" is not picked , as if manually choosing classic the my pictures are there

#!/bin/sh

#  
# Get user logged into console and put into variable "user"
user=`ls -l /dev/console | cut -d " " -f 4`
osMajor=$(sw_vers -productVersion | awk -F"." '{print $2}')
osMinor=$(sw_vers -productVersion | awk -F"." '{print $3}')


sudo -u $user defaults -currentHost write com.apple.screensaver CleanExit -string "YES"
sudo -u $user defaults -currentHost write com.apple.screensaver PrefsVersion -int 100
sudo -u $user defaults -currentHost write com.apple.screensaver showClock -string "NO"
sudo -u $user defaults -currentHost write com.apple.screensaver idleTime -int 600


if [[ $osMajor -eq 15 ]] && [[ $osMinor -ge 2 ]]; then

sudo -u $user defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex" type -int 0

else

sudo -u $user defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0
fi


sudo -u $user defaults -currentHost write com.apple.screensaver tokenRemovalAction -int 0

sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser LastViewedPhotoPath -string ""
sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath -string "/Library/Application Support/JAMF/bin/screensaver"
sudo -u $user defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 3

sudo -u $user defaults -currentHost write com.apple.ScreenSaver.iLifeSlideShows styleKey -string "Classic"

sudo killall -hup cfprefsd

JCMBowman
New Contributor III

HappyMarcus
New Contributor II

@jameson: Is the Catalina clients where it doesn't work perhaps on 10.15.1? Your script is currently checking if the minor version is on .2, so the ones on 10.15.1 will not get the screen saver. If I understand the script correctly.

Which also would explain why you can manually choose the classic one and see the pictures. The pictures (I assume) is deployed to all scoped clients via a package, so they should be installed regardless if you're running 10.14.X, 10.15.1 or 10.15.2.

I edited my script and simply removed the check for minor version, works great (for now)! :)

if [[ $osMajor -eq 14 || 15 ]]; then

sfaeder
New Contributor III

This does not appear to be working at all for me on any MacOS. Has anyone been able to resolve this lately?

inflicted
New Contributor II

I used the script for @dennisnardi and it worked. How do i revert the changes and have it show its default screensaver?

Edit: i thought it worked but all it did was install the png file into the /Library/Screen Savers/ folder. but it did not choose the classic one. When i click on the Classic in screen saver system preferences, it shows up there

user-CrLmEPZVbD
New Contributor

I'm not able to get this working on Mojave 10.14.4. The inputs I tried were:

#!/bin/sh
/usr/bin/defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex" type -int 0
/usr/bin/defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0
/usr/bin/defaults -currentHost write com.apple.ScreenSaverPhotoChooser LastViewedPhotoPath -string ""
/usr/bin/defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath -string "/users/kylefoley/pictures/art/art 2/impressionism/claude monet/"
/usr/bin/defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 3
sudo killall -hup cfprefsd

I did not get an error message but it did not do what I wanted. Also when I input /usr/bin/defaults -currentHost read com.apple.ScreenSaverPhotoChooser

I get

{
    CustomFolderDict =     {
        identifier = "/Users/kylefoley/Pictures/art/complete art 2";
        name = "complete art 2";
    };
    LastViewedPhotoPath = "";
    SelectedFolderPath = "/users/kylefoley/pictures/art/art 2/impressionism/claude monet/";
    SelectedSource = 3;
    ShufflesPhotos = 1;
}

I think the path for the CustomFolderDict is wrong. Does anyone know how I change that?

etarasula
New Contributor II

Tried and got this error:

Script exit code: 2
Script result: 2021-04-16 14:15:48.026 defaults[1074:9601] Unexpected argument sudo; leaving defaults unchanged.
/Library/Application Support/JAMF/tmp/Corp Screensaver: line 31: syntax error: unexpected end of file
Error running script: return code was 2.

jsp_raja
New Contributor

anyone tried it for monterey OS screensaver change not happening as per previous scripts 

 

howie_isaacks
Valued Contributor II

I just discovered that my own process for setting screensavers has all of a suddent stopped working. The script we're using is almost exactly like the one above. It uses these commands:

osMajor=$(sw_vers -productVersion | awk -F"." '{print $2}')
osMinor=$(sw_vers -productVersion | awk -F"." '{print $3}')

 I'm running macOS Sonoma on my personal MacBook Pro. When I run the command for "osMajor", the output is "0". The command for "osMinor" results in nothing. There is no output. I ran the same commands on a Mac runing 13.5.2. I got similar results.

mm2270
Legendary Contributor III

@howie_isaacks It makes sense the output from

osMajor=$(sw_vers -productVersion | awk -F"." '{print $2}')

would be a 0 if the Mac it's running on is on macOS Sonoma. Sonoma is, I believe, version 14.0.0 or just 14.0. (Since you said the second variable outputs nothing, that would indicate it shows as version 14.0). The first command is grabbing the digit after the first period, which would be "0".

To help fix it, you might need to post the full script so we can see what adjustments would be needed.

howie_isaacks
Valued Contributor II

At the moment it's not a huge priority but what I was going to do is go through the entire script and manually run the commands to check what is actually working as I go along and initially ignore the outputs from those commands. The script I'm using is the same as the one posted above. I suspect that the person who had my job before me got it from here. The script works with Ventura, which will be the most installed macOS in my fleet for at least the next few month. I was really wanting to use a profile to set all of these settings and then only change the content in the directory where we place all of the graphical assets for the screensavers. That would be so much easier every time there's a change, and we do a lot of them.

The script is not working for Sonoma anymore. com.apple.screensaver doesn't exist anymore. So far I was not able to find a solution.

iScreensaver
New Contributor II

for macOS Sonoma screensavers, see the discussion here:   https://community.jamf.com/t5/jamf-pro/custom-screensavers-in-sonoma/m-p/300884