More ScreenSaver fun! Setting a ScreenSaver under Script/Casper Doesn't run?

johnmccrae
New Contributor II

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.

1 ACCEPTED SOLUTION

johnmccrae
New Contributor II

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

View solution in original post

4 REPLIES 4

bentoms
Release Candidate Programs Tester

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

johnmccrae
New Contributor II

@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.

bentoms
Release Candidate Programs Tester

@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.

johnmccrae
New Contributor II

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