Set screensaver using script.

bvandepol
New Contributor III

I'm about to pull my hair out! I think what I want is pretty simple;

Screensaver -> Shifting Tiles -> Custom Source (/Library/Screen Savers/CORP) -> Shuffle -> Start after 10 mins

Using a package i've dropped all the pictures (and a copy of the script) to my clients. The next step would be to activate the screensaver and (re)set it at every login. I've tried running my script under my account and everything works just fine.

Now, when I run the script using Casper, or call the local script using sh /Library/Screen Savers/CORP/set_screensaver.sh nothing happens. Although, it looks like it. All settings are correct, except the right screen saver is never selected. I can't get the right screen saver picked using Casper. When i perform it on the client using terminal everything works fine.

I think i'm pretty close, but I need some help on the last part. Thanks!

#!/bin/sh
if [[ `ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-50` != "00000000-0000-1000-8000-" ]]; then
    macUUID=`ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-62`
fi

defaults write ~/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist CleanExit "YES"
defaults write ~/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist idleTime 600
defaults write ~/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist moduleDict -dict moduleName "iLifeSlideshows" path "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0
defaults write ~/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist identifier "/Library/Screen Savers/CORP"
defaults write ~/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist LastViewedPhotoPath ""
defaults write ~/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist SelectedFolderPath "/Library/Screen Savers/CORP"
defaults write ~/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist SelectedSource -int 4
defaults write ~/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist ShufflesPhotos -int 1
defaults write ~/Library/Preferences/ByHost/com.apple.ScreenSaver.iLifeSlideShows.$macUUID.plist styleKey "ShiftingTiles"
1 ACCEPTED SOLUTION

mm2270
Legendary Contributor III

Are you testing this against Mavericks? If so, although it technically shouldn't happen when using the defaults command as you are, you may need to kill CoreFoundationPreferencesDaemon, or cfprefsd as it shows up in the process list.
Add this at the end of your script

killall cfprefsd

Explanation- Mavericks upped how aggressive it is in holding onto cached preferences. In an effort to conserve as much battery life as possible, Apple designed 10.9 to pull from cache whenever possible. Unless you kill the daemon that controls that (it respawns right away) it may not be using the new settings from disk. It will upon logout and login, but I'm guessing you want these new settings to apply right away.
Again, in theory 'defaults' isn't subject to this, but I've seen odd cases where I needed to add the killall to scripts to get the OS to really recognize the changes.

Also, your "curUser" line is pulling the logged in user, not root. Its more or less the same command most of us here use when needing to get the logged in user name, so that should definitely be working correctly.
I have not looked over the rest of your script carefully, so there may still be something off, but probably not if its working when you run it manually.

View solution in original post

11 REPLIES 11

mm2270
Legendary Contributor III

The tilde (~) expansion will apply against the user running the script. When you run your script locally in Terminal its applying against your account, since you're running it. When it runs from Casper. its using the service account or root (typically the latter) As such, since all your paths start with ~/, you're telling your script to apply the settings to "root" and not who is logged in.
You need to get the logged in user account in your script up front, and then use that account as the path to the plist files to affect.

That said, I think you should be able to accomplish what you want with either Configuration Profiles or MCX and not have to use a recurring script at all. That's what they are designed for, so I would look into those first before attempting to script it.

bvandepol
New Contributor III

Update:
I simply can't get it to work using Casper. I've been trying to use Managed Preferences as well.
The script below works while running it from the terminal as the current user.

Any input or directions are more than welcome.

#!/bin/sh
# grab current user
curUser=`ls -l /dev/console | cut -d " " -f 4`

# grab the system's uuid
if [[ `ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-50` != "00000000-0000-1000-8000-" ]]; then
    macUUID=`ioreg -rd1 -c IOPlatformExpertDevice | grep -i "UUID" | cut -c27-62`
fi

#jamf displayMessage -message $curUser

defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist CleanExit "YES"
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist PrefsVersion -int 100
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist idleTime -int 600
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.screensaver.$macUUID.plist moduleDict -dict moduleName "iLifeSlideshows" path "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist identifier "/Library/Screen Savers/CORP"
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist LastViewedPhotoPath "/Library/Screen Savers/CORP"
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist SelectedFolderPath "/Library/Screen Savers/CORP"
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist SelectedSource -int 4
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.ScreenSaverPhotoChooser.$macUUID.plist ShufflesPhotos -int 1
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.ScreenSaver.iLifeSlideShows.$macUUID styleKey "ShiftingTiles"
defaults write /Users/$curUser/Library/Preferences/ByHost/com.apple.ScreenSaver.iLifeSlideShows styleKey "ShiftingTiles"
#sudo chown -R "$curUser:DOMAINDomain Users" ~/Library/Preferences/ByHost/

ahambidge
New Contributor II

@bvandepol, as @mm2270 suggested, since the script is running as 'root' I'm pretty sure your line to grab the current user is returning 'root' instead of the user actually using/logging into the system. I second @mm2270's suggestion of utilizing a configuration profile instead of a script for this.

However, if a script is the best way to go for your environment, I would suggest that you modify your package to deploy a LaunchAgent plist that executes your script instead of trying to do it via Casper Policy. As LaunchAgents are run as the logging-in user, you know it will execute in that context.

bvandepol
New Contributor III

Thanks @ahambidge for your response. The funny thing is that ```
jamf displayMessage -message $curUser
``` does actually show the correct username.

I'm pretty new to all of this so forgive my ignorance.

I've been looking at Managed Preferences -> Screen Saver (ByHost/Loginwindow) but I can't get it to work there either.

I'm missing the com.apple.ScreenSaver.iLifeSlideShows and com.apple.ScreenSaverPhotoChooser preferences there which I need for our config. The manual settings that I can add are applied/applicable to com.apple.screensaver.ByHost am I right?

Coming from a position as a Windows Sysadmin i find this very frustrating and complex.

ahambidge
New Contributor II

@bvandepol][/url, not a problem. I'm currently the workstation Windows & Mac admin at my workplace, so I somewhat understand your frustration. :)

I wouldn't bother with Managed Preferences. While some may continue to get them to work, Apple keeps threatening that they 'may not work in the next release' and I've seen spotty (at best) execution of them myself. Apple released Configuration Profiles as a replacement for Managed Preferences, so I would focus my efforts on that rather than MCX/Managed Preferences, but I'm sure someone smarter than me will chime in to the contrary shortly. :)

In regards to your script snippet utilizing the jamf displayMessage verb; whom are you running that as? Your account via SUDO, or via a Casper policy and capturing the output? I still think the policy is running as root and that's why it's not working. :)

I've never messed with the screensaver, save for it's timeout feature, and I utilized defaults & the default user template to manage it post-image:

#!/bin/sh 
#Sets Screensaver lock settings
defaults write /System/Library/User Template/English.lproj/Library/Preferences/com.apple.screensaver askForPasswordDelay -string 1800
defaults write /System/Library/User Template/English.lproj/Library/Preferences/com.apple.screensaver askForPassword -int 1
echo "Screensaver Settings complete."

AFAIK, these settings still work. It would be pretty simple for you to modify your current script to and remove the "$currUser" variable & path to hardcode in the default user template.

nessts
Valued Contributor II

Here is setting the default picture screen saver in perl. which you should be able to convert to shell if you so choose:

unless(-e $ss) {
    syslog('notice', "Setting default ScreenSaver");
    system("defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName "iLifeSlideshow" path "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type 0");
    system("defaults -currentHost write com.apple.ScreenSaverPhotoChooser LastViewedPhotoPath """);
    system("defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath "/Library/Screen Savers/Default Collections/GreenSaver"  ");
    system("defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 3");
    system("defaults -currentHost write com.apple.ScreenSaverPhotoChooser ShufflesPhotos -bool false");
    system("touch "$ss"");
}

mm2270
Legendary Contributor III

Are you testing this against Mavericks? If so, although it technically shouldn't happen when using the defaults command as you are, you may need to kill CoreFoundationPreferencesDaemon, or cfprefsd as it shows up in the process list.
Add this at the end of your script

killall cfprefsd

Explanation- Mavericks upped how aggressive it is in holding onto cached preferences. In an effort to conserve as much battery life as possible, Apple designed 10.9 to pull from cache whenever possible. Unless you kill the daemon that controls that (it respawns right away) it may not be using the new settings from disk. It will upon logout and login, but I'm guessing you want these new settings to apply right away.
Again, in theory 'defaults' isn't subject to this, but I've seen odd cases where I needed to add the killall to scripts to get the OS to really recognize the changes.

Also, your "curUser" line is pulling the logged in user, not root. Its more or less the same command most of us here use when needing to get the logged in user name, so that should definitely be working correctly.
I have not looked over the rest of your script carefully, so there may still be something off, but probably not if its working when you run it manually.

bvandepol
New Contributor III

That was the magic trick!

sudo killall cfprefsd

Thanks all for thinking with me!

mssaffan
New Contributor II

Sorry to reopen an old thread,

but is this still viable for 10.11 10.12 and/or 10.13?

EUC600
New Contributor III

This was working great for me until 10.13.4. As soon as any of our machines get updated to 10.13.4 it starts displaying the "Message" Screensaver only.

Did something change with the

defaults write /Users/$currentUser/Library/Preferences/ByHost/com.apple.ScreenSaver.iLifeSlideShows.$macUUID styleKey "Classic" command in 10.13.4?

gda
Contributor
#!/bin/bash
defaults write /Users/$currentUser/Library/Preferences/ByHost/com.apple.ScreenSaver.iLifeSlideShows.$macUUID styleKey "Classic"

First of all. Please. Switch away from writing into user preference files. This feels so wrong. And you need to kill cfprefsd. And you need to correct permissions. Use user preference domains instead. Run it with sudo in front of it:

#!/bin/bash
sudo $currentUser defaults -currentHost write com.apple.ScreenSaver.iLifeSlideShows styleKey "Classic"

This should solve the problem:

#!/bin/bash
sudo $currentUser defaults -currentHost write com.apple.ScreenSaver.Basic MESSAGE "Put your message here"