Skip to main content

So, here's my issue. If I run a script via Policy to set the screensaver, it doesn't work.



<snippet>



!/bin/sh



Set Screensaver to Shell Screensaver



/usr/bin/defaults -currentHost write com.apple.screensaver 'idleTime' -int "900"
</snippet>



Run that script as a policy via JSS and it doesn't set the value. Run that as a bash script from a terminal windows under the current user and it works fine. Run that same script again in Terminal with sudo and it doesn't set the value. "defaults read com.apple.screensaver idleTime" returns the current value, not the one I just tried to set.



In other words, no combination of script, Casper, bash running as root/sudo lets that script above run properly. It returns 0 to the JSS but doesn't actually do anything. It only sets the correct value under user context.



Oddly, if I take a completely different approach (thanks Macmule!) and run this code instead, it runs like a champ under all conditions.



<snippet>
startTime="900"
if [[ -n $startTime ]]; then
/usr/libexec/PlistBuddy -c "Add :idleTime integer $startTime" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist
fi
</snippet>



So my question is two-fold. Why is running the first script effectively blocked when running as root. Am I hitting the issue where this thing is setting a screensaver only for root and therefore not available to the current user? If so, I would have thought that using the '-currentHost' switch would have set that parameter globally? Secondly, what is sufficiently different about the two script models that lets the second piece of code run properly?



This may be rudimentary, but I am a Windows person and so some of the subtlety here is escaping me.

@johnmccrae I've a script I used to use for this years ago, posted here. Might be of some help.


@bentoms Thanks! Yours was the script I finally used to get it working. It's brilliant. Do you accept pull requests? I made a couple of tweaks to it.


@johnmccrae Awesome.



I could, but I don't really use that anymore.



However, if you have a fork posted I'll mention that & will link to it.


Marking this as Solved. Thanks @bentoms . I don't have a git repo I use regularly either so I am posting the full code here. I made 2 small changes to the original code posted here. I added/changed the command for the askForPassword parameter and I added a KillAll command to the end to kill preferences so the OS loads this one instantly.



!/bin/sh



########################################################################################


# More information: http://macmule.com/2010/11/18/how-to-set-osxs-screen-saver-via-script/



GitRepo: https://github.com/macmule/setscreensaver



License: http://macmule.com/license/



########################################################################################


#####


# HARDCODED VALUES ARE SET HERE



#####


startTime="900" # Integer - Seconds
justMain="0" # Boolean
screenSaverName="Shell" # String
screenSaverPath="/System/Library/Screen Savers/Shell.saver" # String
requirePassword="1" # Integer (1 = true, 0 = false)
timeBeforeRequiringPassword="5" # Integer - Seconds
askforpassword="1" # Integer (1 = true, 0 = false)



# IF RUN AS A SCRIPT IN CASPER, CHECK TO SEE IF A VALUE WAS PASSED IN PARAMETER AND, IF SO, ASSIGN



if [ "$4" != "" ] && [ "$startTime" == "" ]; then
startTime=$4
fi



if [ "$5" != "" ] && [ "$justMain" == "" ]; then
justMain=$5
fi



if [ "$6" != "" ] && [ "$screenSaverName" == "" ]; then
screenSaverName=$6
fi



if [ "$7" != "" ] && [ "$screenSaverPath" == "" ]; then
screenSaverPath=$7
fi



if [ "$8" != "" ] && [ "$requirePassword" == "" ]; then
requirePassword=$8
fi



if [ "$9" != "" ] && [ "$timeBeforeRequiringPassword" == "" ]; then
timeBeforeRequiringPassword=$9
fi



#####


# Get the Universally Unique Identifier (UUID) for the correct platform



ioreg commands found in a comment at http://www.afp548.com/article.php?story=leopard_byhost_changes



#####


# Check if hardware is PPC or early Intel
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 -c51-62 | awk {'print tolower()'}
# Check if hardware is new Intel
elif [[ 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



#####


Get the Username of the currently logged user



loggedInUser=/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'



Query dscl to get the currently logged in users home folder



loggedInUserHome=dscl . -read /Users/$loggedInUser | grep NFSHomeDirectory: | /usr/bin/awk '{print $2}'



#####


# For each variable check to see if it has a value. If it does then write the variables value to the applicable plist in the applicable manner



#####


Variables for the ~/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist



Set bash to become case-insensitive



shopt -s nocaseglob



Remove the all the com.apple.screensaver* plists, with the Case insensitivity this will also remove the Case insenstivity was updated to remove:



com.apple.ScreenSaver.iLifeSlideShows.XX.plist & com.apple.ScreenSaverPhotoChooser.XX.plist saver plists



rm -rf "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver*



Set bash to become case-sensitive



shopt -u nocaseglob



if [[ -n $startTime ]]; then
/usr/libexec/PlistBuddy -c "Add :idleTime integer $startTime" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist
fi



if [[ -n $justMain ]]; then
/usr/libexec/PlistBuddy -c "Add :mainScreenOnly bool $justMain" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist
fi



Make sure the moduleDict dictionary exists



/usr/libexec/PlistBuddy -c "Add :moduleDict dict" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist



if [[ -n $screenSaverName ]]; then
/usr/libexec/PlistBuddy -c "Add :moduleDict:moduleName string $screenSaverName" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist
/usr/libexec/PlistBuddy -c "Add :moduleName string $screenSaverName" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist
fi



if [[ -n $screenSaverPath ]]; then
/usr/libexec/PlistBuddy -c "Add :moduleDict:path string $screenSaverPath" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist
/usr/libexec/PlistBuddy -c "Add :modulePath string $screenSaverPath" "$loggedInUserHome"/Library/Preferences/ByHost/com.apple.screensaver."$macUUID".plist
fi



Variables for the ~/Library/Preferences/com.apple.screensaver.plist



Remove the com.apple.screensaver.plist, comment out if you do not wish to remove this file



rm -rf "$loggedInUserHome"/Library/Preferences/com.apple.screensaver.plist



if [[ -n $requirePassword ]]; then
/usr/libexec/PlistBuddy -c "Add :askForPassword integer $askforpassword" "$loggedInUserHome"/Library/Preferences/com.apple.screensaver.plist
fi



if [[ -n $timeBeforeRequiringPassword ]]; then
/usr/libexec/PlistBuddy -c "Add :askForPasswordDelay integer $timeBeforeRequiringPassword" "$loggedInUserHome"/Library/Preferences/com.apple.screensaver.plist
fi



Echo out on completion..



echo "Set Screen Saver for user: "$loggedInUser"..."



killall cfprefsd



rm -f ~/Library/LaunchAgents/set-screensaver.plist