Help with a screensaver extension attribute

ddasilva
New Contributor

Hey guys,

I'm still new to the extension attributes game and was wondering if someone in the community could help be come up with a EA that will return the current set screensaver.

I found this attribute that is supposed to provide the current screensaver set time LINK and attempting to modify it has not been very successfull.

Any help would be appreciated. If anyone has suggestions on where i can get more info on writing my own that would be great too.

Thanks!

1 ACCEPTED SOLUTION

iJake
Valued Contributor

You can modify it to only show the name or the file or whatever format you want but this should do what you want. Just threw it together so not fully tested but it works on my 10.11 machine

#!/bin/bash

plistBuddyPath="/usr/libexec/PlistBuddy"

grabConsoleUserAndHome(){
  currentUser=$(stat -f %Su "/dev/console")
  homeFolder=$(dscl . read "/Users/$currentUser" NFSHomeDirectory | cut -d: -f 2 | sed 's/^ *//'| tr -d '
')
  case "$homeFolder" in  
     * * )
           homeFolder=$(printf %q "$homeFolder")
          ;;
       *)
           ;;
esac
}

grabConsoleUserAndHome

if [[ "$currentUser" == "root" ]]
    then
        exit
fi

screensaverPlist=$(find $homeFolder/Library/Preferences/ByHost -name com.apple.screensaver.*  -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" ")

if [[ ! -z $screensaverPlist ]]
    then
        screensaverName=$($plistBuddyPath -c "print :moduleDict:moduleName" $screensaverPlist)
        screensaverFile=$($plistBuddyPath -c "print :moduleDict:path" $screensaverPlist)
fi

echo "<result>$screensaverName,$screensaverFile</result>"

View solution in original post

4 REPLIES 4

iJake
Valued Contributor

You can modify it to only show the name or the file or whatever format you want but this should do what you want. Just threw it together so not fully tested but it works on my 10.11 machine

#!/bin/bash

plistBuddyPath="/usr/libexec/PlistBuddy"

grabConsoleUserAndHome(){
  currentUser=$(stat -f %Su "/dev/console")
  homeFolder=$(dscl . read "/Users/$currentUser" NFSHomeDirectory | cut -d: -f 2 | sed 's/^ *//'| tr -d '
')
  case "$homeFolder" in  
     * * )
           homeFolder=$(printf %q "$homeFolder")
          ;;
       *)
           ;;
esac
}

grabConsoleUserAndHome

if [[ "$currentUser" == "root" ]]
    then
        exit
fi

screensaverPlist=$(find $homeFolder/Library/Preferences/ByHost -name com.apple.screensaver.*  -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" ")

if [[ ! -z $screensaverPlist ]]
    then
        screensaverName=$($plistBuddyPath -c "print :moduleDict:moduleName" $screensaverPlist)
        screensaverFile=$($plistBuddyPath -c "print :moduleDict:path" $screensaverPlist)
fi

echo "<result>$screensaverName,$screensaverFile</result>"

stevewood
Honored Contributor II
Honored Contributor II

@ddasilva I used defaults read to read the screen saver plist in the ByHost folder of my user (/Users/<user>/Library/Preferences/ByHost/com.apple.screensaver.<UUID>.plist) to figure out the structure of the file. This is what I got back:

{
    CleanExit = YES;
    PrefsVersion = 100;
    idleTime = 600;
    moduleDict =     {
        moduleName = "Computer Name";
        path = "/System/Library/Frameworks/ScreenSaver.framework/Resources/Computer Name.saver";
        type = 0;
    };
    showClock = 1;
    tokenRemovalAction = 0;
}

I can see from this that what you want, the screen saver name, is in the moduleDict dictionary of the plist. So, to grab the moduleName (and path if I wanted) I used PlistBuddy to read into the dictionary (defaults cannot do this that I know of):

/usr/libexec/PlistBuddy -c "print :moduleDict:moduleName" /Users/swood/Library/Preferences/ByHost/com.apple.screensaver.AC5AE6BE-30EA-5F85-BCF6-E16FA1C546AF.plist

This provided me with the following output:

Computer Name

Putting that together in an EA would look like this:

#!/bin/bash
currentUser = `python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`

fileLoc=`find /Users/$currentUser/Library/Preferences/ByHost/ -name com.apple.screensaver.*`
screenSaver=`/usr/libexec/PlistBuddy -c "print :moduleDict:moduleName" ${fileLoc}`

echo "<result>${screenSaver}</result>"

That should give you an EA that contains the module name for the screen saver.

Hope that helps, and as always, test, test, TEST.

mm2270
Legendary Contributor III

Actually, this may depend on what you mean by "set screensaver" There are actually two (or more). One that applies when the Mac is sitting at a login window, i.e, no user logged in. And then there is the user specific screensaver module setting, which will likely be different for each account if there are more than one on a system. Which one(s) are you looking to pull into the EA?
Technically its possible to pull a list of all of them, meaning, the one set for the system, and the one set for every valid user account on the Mac.

The examples posted above will get you the current user's screensaver setting. Here's another version I literally just whipped together. Same principle as what was posted above.

#!/bin/bash

loggedInUser=$(stat -f%Su /dev/console)
MacUUID=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}')

setScreenSaver=$(/usr/libexec/PlistBuddy -c "Print :moduleDict:moduleName" /Users/${loggedInUser}/Library/Preferences/ByHost/com.apple.screensaver.${MacUUID}.plist)

echo "<result>$setScreenSaver</result>"

Again, the same process could be used to loop over all local home directories and build an array of the username and values, then print the final array later as its result for the EA. That would give you a list of names and the set ScreenSaver modules for each one.

ddasilva
New Contributor

Thanks everyone... @iJake 's option seems to be working for me.