Policies not running properly unless manually triggered

tommrkr
New Contributor II

I have a bit of a head scratcher that I'm hoping people may be able to assist with.

Attempting to set a default desktop background in my lab. Created a policy that deploys a package with desired image and a python script. It is set to run once on recurring check-in. All machines report that the policy has run w/o problem. However, none of the machines have taken the new background. The package has been unpacked, as the images are in /User/Shared as I requested.

If I flush the machine from the list, go to the physical machine and run 'sudo jamf policy' from the terminal, the script runs just fine, I get a new background, and everything is happy. Except me, because I don't want to walk around and touch every machine.

If anyone has any thoughts, I'd love to hear them. Happy to provide any further information if it is helpful.

2 ACCEPTED SOLUTIONS

bentoms
Release Candidate Programs Tester

@tommrkr we use a version of Graham's script. But tigger it via a LaunchAgent at login.

I think the issue is whom is logged into the Macs at the time of execution.

View solution in original post

tommrkr
New Contributor II

Update:

Moving it to the login hook, I got an error:

_RegisterApplication(), FAILED TO establish the default connection to the WindowServer, _CGSDefaultConnection() is NULL. mac

Added sudo -u username to the command calling the script and all was right with the world. I guess the script couldn't touch the environment as root. Right now, I'm really only concerned with one account getting the push, but I decided to pull the user from the system and passing as a variable instead of just using the username

#!/bin/sh

loggedinuser=$(ls -ltr /dev/console | awk '{print $3}')
sudo -u "$loggedinuser" python /Users/Shared/set_desktops.py --path /Users/Shared/DefaultDesktop03.jpg

Thanks to everyone for helping me get the wheels spinning again!

View solution in original post

7 REPLIES 7

mm2270
Legendary Contributor III

I don't know python, but others do. Can you post the script or the relevant parts of it at least? I'm wondering if you're just running up against the aggressive preference caching.

tommrkr
New Contributor II

Sure, it's a script that's been mentioned here and available at (https://github.com/grahamgilbert/macscripts/tree/master/set_desktops)

#!/bin/sh

#!/usr/bin/python

'''Uses Cocoa classes via PyObjC to set a desktop picture on all screens.
Tested on Mountain Lion and Mavericks. Inspired by Greg Neagle's work: https://gist.github.com/gregneagle/6957826

See:
https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSWorkspace_Class/Reference/Reference.html

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/Reference/Reference.html

https://developer.apple.com/library/mac/documentation/cocoa/reference/applicationkit/classes/NSScreen_Class/Reference/Reference.html
'''

from AppKit import NSWorkspace, NSScreen
from Foundation import NSURL
import argparse
import sys

parser = argparse.ArgumentParser(description='Sets the desktop picture on all screens')
parser.add_argument('--path', help='The path of the image')
args = vars(parser.parse_args())

if args['path']:
    picture_path = args['path']
else:
    print >> sys.stderr, 'You must supply a path for the desktop picture'
    exit(-1)

# generate a fileURL for the desktop picture
file_url = NSURL.fileURLWithPath_(picture_path)

# make image options dictionary
# we just make an empty one because the defaults are fine
options = {}

# get shared workspace
ws = NSWorkspace.sharedWorkspace()

# iterate over all screens
for screen in NSScreen.screens():
    # tell the workspace to set the desktop picture
    (result, error) = ws.setDesktopImageURL_forScreen_options_error_(
                file_url, screen, options, None)
    if error:
        print error
        exit(-1)

bentoms
Release Candidate Programs Tester

@tommrkr we use a version of Graham's script. But tigger it via a LaunchAgent at login.

I think the issue is whom is logged into the Macs at the time of execution.

Look
Valued Contributor III

Maybe it needs a user logged in for something it's referencing to exist?
What does it do on a machine with a user logged in but still running from the JSS normally on the recurring trigger?
Sorry I also don't do Python, just guessing as to the machine differences when it's being run.

Chris_Hafner
Valued Contributor II

Yea, I'm a bit out of my depth with python. Just remember that a machine will 'check-in' if it's logged out. Since the policy will only run once, this could point directly to what folks are already point to. There should be policy logs you can check. Regardless, you also should be able to change the event trigger from "recurring check-in" to "login" and see if that helps with the policy as you have it. You will have to clear your policy logs thouhg as the JSS will remember that it's already run the policy on a given unit.

P.S> I'm getting the sense that I really should learn python.

tommrkr
New Contributor II

Thanks everyone for your input. I did make sure that the account in question was logged in to all of the machines and ran the script on check-in to no avail. I also tried killing cfprefsd and dock to rule out caching issues. Still no luck.

I've also tried calling the sqlite db, trying to change via osascript, but never had any luck via policy. Was hoping the python script would be the way to go, but I think I'm missing a piece to the puzzle.

I will try it as a login hook and see if that makes a difference.

tommrkr
New Contributor II

Update:

Moving it to the login hook, I got an error:

_RegisterApplication(), FAILED TO establish the default connection to the WindowServer, _CGSDefaultConnection() is NULL. mac

Added sudo -u username to the command calling the script and all was right with the world. I guess the script couldn't touch the environment as root. Right now, I'm really only concerned with one account getting the push, but I decided to pull the user from the system and passing as a variable instead of just using the username

#!/bin/sh

loggedinuser=$(ls -ltr /dev/console | awk '{print $3}')
sudo -u "$loggedinuser" python /Users/Shared/set_desktops.py --path /Users/Shared/DefaultDesktop03.jpg

Thanks to everyone for helping me get the wheels spinning again!