Posted on 08-30-2012 12:07 PM
Hi all,
I know that some of you seem to use the dockutil software. I use it and it works great, but I'm looking to do a few things in the script with groups, but don't script much at all.
Say I've got a basic script, like this one here:
#!/bin/bash
# Enable and configure Dock for Students
LoggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`
LoggedInUserHome=`dscl /LDAPv3/127.0.0.1 -read /Users/$LoggedInUser | grep NFSHomeDirectory: | cut -c 19- | head -n 1`
plist=$LoggedInUserHome/Library/Preferences/com.apple.dock.plist
sudo -u $LoggedInUser dockutil --remove all "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/Google Chrome.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/Safari.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/Firefox.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/Self Service.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/Microsoft Office 2008/Microsoft Word.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/Microsoft Office 2008/Microsoft Excel.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/Microsoft Office 2008/Microsoft PowerPoint.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/iWork '09/Pages.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/iWork '09/Numbers.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/iWork '09/Keynote.app/ "${plist}"
sudo -u $LoggedInUser dockutil --add /Applications/ "${plist}" --section others
sudo -u $LoggedInUser dockutil --add '~/Documents' "${LoggedInUserHome}"
It works out great for students, no problem.
If I wanted to do something like, make a statement that says, I'll give you 2 more application icons if you are a member of GroupX, is there a simple way to do that?
I thought it might be easy to just create 2 scripts: 1 for staff and 1 for students.
Then, I can do, if | else statements, based on what groups they are in. Once it finds their group, it gives them that dock.
The issue is I don't know how to put that together and I'm not sure what happens when they are a member of 2 groups, unless there's some hierarchal way of doing it where I would put groups that would have more icons at the top of the script and it stops processing once it hits that group. That's not a perfect design, but it would work for probably everyone right now.
Any thoughts? Thanks much!
Brian
Posted on 08-30-2012 12:48 PM
You can use an if/then statement to distinguish between teachers and students: "If user is part of teachers group then add these dock icons. Otherwise, add these other dock icons (students)." Something like:
#!/bin/sh
ROLE=$( some code here where the result is "student" or "teacher" )
if [ "$ROLE" = "teacher" ] ; then
your code to add teacher dock icons here
else
your code to add student dock icons here
fi
What you need to do is determine how you'll identify a student vs. a teacher. Is that information stored in your LDAP directory too?
Posted on 08-30-2012 01:43 PM
why not use mcx for this?
Posted on 08-30-2012 04:04 PM
MCX would be the ideal solution, however, the option to apply these just once is broken in a few iterations of Casper. I don't encourage forcing preferences like Dock items on the user.
Posted on 08-30-2012 05:27 PM
Thanks for the responses. I ideally wanted to use Casper but like talkingmoose said, it doesn't work that well. I've tried Casper for dock stuff and it is really inconsistent. Using self service and dockutil is really simple and I have yet to see it fail. Plus teachers can do what they wish with their docks and reset it to a clean dock anytime they wish and have it work all the time.
I guess the role thing sounds interesting. I was just hoping I could do it via a group but that's not ideal I would suppose. I'd have to see if I could have it read an attribute in their OD record maybe? Like if in a section they had a code like tt5 or something it would see that and then add a change to the dock? That wouldn't actually be bad at all since I could likely add that code to group members in mass via WGM.
I'm not sure how to get it to read something I put in OD records though. Have you ever done such a thing? Typing this on my iPhone so hopefully I didn't make too many errors in this post.
Posted on 08-31-2012 04:53 AM
OP-
You *should* be able to do some sort of dscl query to see what groups they belong to. If it were me, I'd use a Case statement to match and then set $Role. I've done something very similar with AD.
Posted on 08-31-2012 08:22 AM
Jared's thinking what I'm thinking.
The original script already has a dscl query in it to determine the path of the user's home folder (NFSHomeDirectory). You should be able to modify that line to pull a list of groups, a title or something from LDAP that identifies the role of the user (assuming your LDAP directory contains that information).
Posted on 08-31-2012 08:44 AM
Hey Everyone,
If you have live LDAP lookups enabled in the JSS, and assign a LDAP user you can scope by LDAP group. If this doesn't work, because your LDAP configuration is large and complicated (I've seen some crazy ones personally), then you can try the scripting method. You can also force LDAP logins to Self Service and scope it from there as well.
You can query your LDAP servers via dscl command line once a Mac is bound to a LDAP server. An example might be:
dscl /Search read /Users/username
This will pull all the information down, from there you would have to read specific LDAP attributes, or start awk/grep-ing the info you need.
Hope this helps,
Tom
Posted on 08-31-2012 08:47 AM
The following is my method of what Tom describes above: http://macmule.com/2012/05/16/submit-user-information-from-ad-into-the-jss-at-login///
Posted on 08-31-2012 08:53 AM
Hi Ben,
It looks like you are popular on the Internet. I had a customer recently that was using several of your scripts from your website. Keep up the good work. :-)
Thanks,
Tom
Posted on 08-31-2012 09:17 AM
Coolio :)
It's kinda your fault anyways for being so helpful to me (as well as others), when this was a list.
Just giving something back.
Posted on 08-31-2012 10:31 AM
Oh man, great information everyone. Bentoms, I was perusing your stuff already so I'll be checking out that link shortly. I'm going to do a bit of fiddling around with things here in a test setup and see how it works when I apply a couple of script modifications.
I'll post back with my findings as soon as I test them out. Thanks again everyone - much appreciated!
I wish I could get a notification of RSS feed to work on this site. Can't get anything to come up using a few different apps. I'll have to look that over as well.
Thanks again!
Posted on 09-07-2012 10:21 PM
Sweet! Thanks Ben that is an awesome script :)
Posted on 09-10-2012 06:17 PM
Is there a way to run this script in a policy at "login"?
It will get "root" as the user when you run it as a login script.
Posted on 09-11-2012 02:38 PM
which script?
Posted on 09-11-2012 04:19 PM
The dockutil script to configure user dock at login.
Posted on 09-12-2012 12:16 AM
Ah. See the 1st 4 lines or so of the script?
That's basically getting the logged in Users details & telling Dockutil to use them.
So even though it's being run as root, it will run a command like:
/Users/<loggedInUser>/Library/Preferences/
With Casper if you use $3 in a script @ login, $3 will be the username of the user logging in.
Posted on 09-13-2012 07:08 AM
@Kumarasinghe - If you run it as the user as the user via launchd then it will run as the user and there is no need to populate variables or even specify the plist as dockutil's ddefault behavior assumes current user.
There used to be an awesome intro to launchd article on AFP548 that would give you the basics you need to accomplish this but it looks like it did not make the migration.
Also, for assigning the variable ```
LoggedInUserHome
``` you definitely don't need the first grep and I'm sure the cut | head portion can be cleaned up as well... but you can just ask dscl to give you the info you want like so:
LoggedInUserHome=$(dscl /LDAPv3/127.0.0.1 -read /Users/$LoggedInUser NFSHomeDirectory | cut -c 19- | head -n 1)
P.S. also dockutil doesn't screw up permissions so if you are already telling it to work on a specific plist you don't need to tell it to run as a specific user
EDIT: P.P.S. it is also smart enough now to just take a home directory as an argument instead of the full path to the plist, which would clean up the script as well.
Posted on 09-13-2012 06:07 PM
Thanks Ben and Ryan.
@rmanly
I think you are referring to this article.
http://web.archive.org/web/20110527183309/http://www.afp548.com/article.php?story=20050620071558293
Posted on 09-13-2012 11:56 PM
@bentoms
1st 4 lines would get the logging in user ONLY if you have "Perform login actions in background" selected in Computer Management Framework Settings > Login/Logout Hook of JSS. If its is unticked, logged in user will be root.
$3 method works with "Perform login actions in background" unticked but not when ticked.
I think plist files creation times may be different when you use "Perform login actions in background" as policies will apply in the same time when the OS is creating those default plist files.
Posted on 02-13-2013 03:21 PM
Anyone else care to share their dockutil scripts? I've got my login script for staff working well on 10.6 and 10.7. With 10.8, however, the dock restart process isn't working correctly. When the dock does restart, it only adds 1 of the items in my script. If I look in the dock plist I can see the other items I've added but they don't show up until I bounce the Dock process one more time. I'm working around it by waiting a few seconds after my dockutil commands run and then killing the dock again, but it's not real elegant.
Posted on 10-29-2014 10:15 PM
I am interested in using Docutil, and map to LDAP user groups. I have read this thread completely, but I am a bit confused as to the workflow. Can anyone make a recommendation / procedure? I want to modify the docutil by LDAP user groups, ie Student, Teacher, Workgroup, etc.
Posted on 12-04-2014 01:33 AM
I'm having an issue with dockutil and a user launch agent at login to add an item to the dock. the launch agent executes a script.
running the script manually and it adds the dock item perfectly. however, when executed by a launch agent it does not add the dock item. I can see it is trying as the dock is killed and refreshed.
anyone experienced any similar issues with dockutil + launch agents?
Posted on 12-04-2014 02:03 AM
When you run the script manually, you probably run it as the user or? I experienced similar issues like this, because I did not authenticate as the specific user I would like to change the .plist for? May you wanna post your agent and script as well?
Cheers!
Posted on 12-04-2014 02:33 AM
Hi @fabsen83
The weird thing is i can get it to work by adding a dummy line after trying to add my dock item that i want.
If i just have the one line to add an item it fails - If i have a line to add my item, then another entry to add another dock item it adds the first item but not the second item.
Having a sole item by itself fails everytime! really strange.
anyway heres my script:
#!/bin/bash
#Script to check if we have a network connection and then mount users home drive
#This will be delivered by launch agent
#Author: James Durler
#Date: 3/12/2014
logFile="/Users/$USER/Library/logs/homedrive.log"
touch $logFile
function mountDrive {
#Using $USER to determine the user running this command to be used in the dscl command to find users SMB Home Path
smbhome=dscl '/Active Directory/ARTSLOCAL/All Domains' -read /Users/$USER SMBHome | awk '{print $2}' | sed -e 's/\\/smb:///g' | sed 's:\:/:g'
echo "Untrimmed SMB Home Path is $smbhome" >> $logFile
#trim the variable smbhome, so we can test if the file share we are trying to mount to is available
#first we are removing the smb:// - this should always be the start of the users smbhome path
newsmbhome=$(echo $smbhome | cut -c 7-)
echo "Removed the smb:// variable is now $newsmbhome" >> $logFile
#now remove everything after the first /, so delimitting by the / after INF-FS06
newersmbhome=$(echo $newsmbhome | cut -f1 -d"/")
echo "Removed everything after the first slash, we now have the file share to ping for availability $newersmbhome" >> $logFile
#now pinging the file share to see if it is available
if ping -c 1 $newersmbhome &> /dev/null;then
#file share is available
echo "Mounting Home Drive" >> $logFile
mkdir /Volumes/Home Drive
mount -t smbfs $smbhome /Volumes/Home Drive/
echo "adding dock item" >> $logFile
/Users/Shared/dockutil --add /Volumes/Home Drive/
/Users/Shared/dockutil
/Users/Shared/dockutil
else
#file share is unavailable
echo "File share is not responding"
fi
}
#Check if the home drive is already mounted before doing anything else
if [ -d /Volumes/Home Drive ]
then
echo "Home Drive already Mounted, exiting Script"
exit 0
fi
if ping -c 1 inf-dc01 &> /dev/null;then
#inf-dc01 is responsive, get users SMB home path
echo "inf-dc01 is responsive, getting users SMB home path"
mountDrive
elif ping -c 1 inf-dc02 &> /dev/null;then #inf-dc02 is responsive, get users SMB home path echo "inf-dc02 is responsive, getting users SMB home path" mountDrive
elif ping -c 1 inf-dc03 &> /dev/null;then #inf-dc03 is responsive, get users SMB home path echo "inf-dc03 is responsive, getting users SMB home path" mountDrive
elif ping -c 1 inf-dc04 &> /dev/null;then #inf-dc04 is responsive, get users SMB home path echo "inf-dc04 is responsive, getting users SMB home path" mountDrive
else echo "No Domain Controller is responding, do nothing" fi
Heres my launch agent created with lingon:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<false/>
<key>Label</key>
<string>com.UAL.HomeDrive</string>
<key>ProgramArguments</key>
<array>
<string>/Users/Shared/rwar.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>30</integer>
</dict>
</plist>
Posted on 12-04-2014 02:55 AM
I see - think your script is fine, but for me a little bit complex and loads of pinging to make sure everything is available. For me it's a long time ago and I don't know the latest version of dockutil - you might need to kill cfprefsd before killing the Dock itself. This issue is really weird, sorry, but if it works with the dummy line why not just keeping it and reporting this issue to the developer of dockutil!? I will check the latest version of dockutil - maybe I can figure out something new.