Want to highlight a helpful answer? Upvote!

Did someone help you, or did an answer or User Tip resolve your issue? Upvote by selecting the upvote arrow. Your feedback helps others! Learn more about when to upvote >

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Customize Dock with Script

I am trying to make an AppleScript that will place a .app in my users dock based on the org group that they are a part of in Active Directory. For example, a teacher will get a different .app in their dock then a student, because they are part of a different group in Active Directory. Can anyone help me with this? Thanks!

Posted on Apr 20, 2016 12:32 PM

Reply
10 replies

Apr 20, 2016 3:23 PM in response to morelockc

I don't use Active Directory, so I cannot test your org group decision tree within AppleScript. But, here is how you specify that an application launch, minimalize itself to a Dock icon, and keeps itself in the Dock after it quits running. Uses GUI scripting. Tested with OS X 10.11.4.


The following code is an adaptation from MacScripter.


-- AppleScript that launches, minimalizes itself, and remains in the Dock after it is quit.

set appName to "Notes"


tell application (my appName) to launch


tell application "System Events" to tell UI element appName of list 1 of process "Dock"

perform action "AXShowMenu"

click menu item "Options" of menu 1

click menu item "Keep in Dock" of menu 1 of menu item "Options" of menu 1

perform action "AXShowMenu"


clickmenu item "Hide" of menu 1

perform action "AXShowMenu"


clickmenu item "Quit" of menu 1

end tell

Apr 20, 2016 9:58 PM in response to morelockc

Hello


You might try the following AppleScript to add specified applications as persistent applications to Dock of current user.



--APPLESCRIPT set apps to {"/Applications/Preview.app", "/Applications/iWork '09/Pages.app"} add_persistent_apps_to_dock(apps) on add_persistent_apps_to_dock(argv) (* list argv : list of POSIX path of application bundles *) set args to "" repeat with a in argv set args to args & a's quoted form & space end repeat do shell script "/bin/bash -s <<'EOF' - " & args & " # # file: # add_persistent_apps_to_dock.sh # # usage: # ./add_persistent_apps_to_dock.sh file [file ...] # # file : absolute posix path of application bundle # shopt -s extglob for f in \"$@\" do f=${f/%+(\\/)}/ # normalise bundle path so that it ends with / fq=$(sed 's/[^[:alnum:]]/\\\\&/g' <<< \"$f\") # quote meta characters for regex [[ -n $(defaults read com.apple.dock persistent-apps | sed -En \"s/\\\"_CFURLString\\\" = \\\"?($fq)\\\"?;/\\1/p\" ) ]] && continue # already exists defaults write com.apple.dock persistent-apps -array-add \" <dict> <key>tile-data</key> <dict> <key>file-data</key> <dict> <key>_CFURLString</key> <string>${f}</string> <key>_CFURLStringType</key> <integer>0</integer> </dict> </dict> </dict> \" done killall Dock EOF" end add_persistent_apps_to_dock --END OF APPLESCRIPT




And here's the original shell script in case you prefer to use it in shell.



#!/bin/bash # # file: # add_persistent_apps_to_dock.sh # # function: # add specified application bundle(s) to Dock as persistent application(s) # # usage: # ./add_persistent_apps_to_dock.sh file [file ...] # # file : absolute posix path of application bundle # # version: # 0.10 # shopt -s extglob for f in "$@" do f=${f/%+(\/)}/ # normalise bundle path so that it ends with / fq=$(sed 's/[^[:alnum:]]/\\&/g' <<< "$f") # quote meta characters for regex [[ -n $(defaults read com.apple.dock persistent-apps | sed -En "s/\"_CFURLString\" = \"?($fq)\"?;/\1/p" ) ]] && continue # already exists defaults write com.apple.dock persistent-apps -array-add " <dict> <key>tile-data</key> <dict> <key>file-data</key> <dict> <key>_CFURLString</key> <string>${f}</string> <key>_CFURLStringType</key> <integer>0</integer> </dict> </dict> </dict> " done killall Dock




Scripts are briefly tested under OS X 10.6.8.


Good luck,

H

Apr 22, 2016 8:14 PM in response to morelockc

Hello


Sorry for late reply. Since I know little about Active Directory, I cannot be of much help here. You'd need to identify the group which the user is a member of and branch the code based upon it.


Does the following command (in Terminal) print any clue to identify the group of the current user in Active Directory?



id -Gn




If it does, solution would be simple. If not, you might try dscl, dsmemberutil etc. E.g.,



dsmemberutil checkmembership -U user_name -G group_name




which would print one of the following:



user is a member of the group user is not a member of the group




------

By the way, I revised the scripts so as to treat more general file name, which includes & < " and U+0080 and upper characters, properly. Main code is rewritten in Perl.


(Some technicalities. HFS Plus name is basically in NDF (Normalization Form D) but not decomposed in certain exceptional Unicode code points. The following scripts do NOT distinguish compatibility equivalence in those exceptions in name comparison and may fail to register an application whose name has a character in those exceptions if another application whose name is only distinguishable by the compatibility equivalent character of the character has been already registered.)


Here's revised AppleScript.



--APPLESCRIPT set apps to {"/Applications/Preview.app", "/Applications/iWork '09/Pages.app"} add_persistent_apps_to_dock(apps) on add_persistent_apps_to_dock(argv) (* list argv : list of POSIX path of application bundles *) set args to "" repeat with a in argv set args to args & a's quoted form & space end repeat do shell script "/usr/bin/perl -CSDA <<'EOF' - " & args & " 2>&1 # # @ARGV : array of absolute path of application bundles # use strict; use Unicode::Normalize; # get exisiting paths from persistent-apps in dock plist my @paths = (); my $t = qx[defaults read com.apple.dock persistent-apps]; while ($t =~ /\"_CFURLString\" = \"(.*)\";/og) { $_ = $1; s/\\x5c{2}U([0-9a-f]+)/pack('U*', hex($1))/ogie; s/\\x5c{2}\"/\"/og; push @paths, NFD($_); # normalise to NFD } # add given paths to persistent-apps in dock plist map { s%/*\\z%/%o } @ARGV; # normalise bundle path so that it ends with single / for (@ARGV) { my $p = NFD($_); # normalise to NFD my $re = qr/^\\Q$p\\E\\z/i; unless (grep /$re/, @paths) { # only if not in persistent-apps s/&/&amp;/og; # XML escape: & => &amp; s/</&lt;/og; # XML escape: < => &lt; s/'/'\\\\''/og; # shell escape: ' => '\\'' qx[ defaults write com.apple.dock persistent-apps -array-add ' <dict> <key>tile-data</key> <dict> <key>file-data</key> <dict> <key>_CFURLString</key> <string>$_</string> <key>_CFURLStringType</key> <integer>0</integer> </dict> </dict> </dict>' ]; } } # restart Dock qx[killall Dock]; EOF" end add_persistent_apps_to_dock --END OF APPLESCRIPT




And here's the revised shell script.



#!/bin/bash # # file: # add_persistent_apps_to_dock.sh # # function: # add specified application bundle(s) to Dock as persistent application(s) # # usage: # ./add_persistent_apps_to_dock.sh file [file ...] # # file : absolute posix path of application bundle # # version: # 0.20 # /usr/bin/perl -CSDA -w <<'EOF' - "$@" # # @ARGV : array of absolute path of application bundles # use strict; use Unicode::Normalize; # get exisiting paths from persistent-apps in dock plist my @paths = (); my $t = qx[defaults read com.apple.dock persistent-apps]; while ($t =~ /"_CFURLString" = "(.*)";/og) { $_ = $1; s/\x5c{2}U([0-9a-f]+)/pack('U*', hex($1))/ogie; s/\x5c{2}"/"/og; push @paths, NFD($_); # normalise to NFD } # add given paths to persistent-apps in dock plist map { s%/*\z%/%o } @ARGV; # normalise bundle path so that it ends with single / for (@ARGV) { my $p = NFD($_); # normalise to NFD my $re = qr/^\Q$p\E\z/i; unless (grep /$re/, @paths) { # only if not in persistent-apps s/&/&amp;/og; # XML escape: & => &amp; s/</&lt;/og; # XML escape: < => &lt; s/'/'\\''/og; # shell escape: ' => '\'' qx[ defaults write com.apple.dock persistent-apps -array-add ' <dict> <key>tile-data</key> <dict> <key>file-data</key> <dict> <key>_CFURLString</key> <string>$_</string> <key>_CFURLStringType</key> <integer>0</integer> </dict> </dict> </dict>' ]; } } # restart Dock qx[killall Dock]; EOF




Scripts are briefly tested under OS X 10.6.8.


Good luck,

H

Apr 28, 2016 1:24 PM in response to Hiroto

Hiroto, thank you so much for this script. I almost have it integrated with my active directoy but I am running into a small problem. If I just enter one app into the script it will place it in the dock. If I enter multiple, it will not do all of them and it is not very consistant. Can you recommend a fix? Here is my modified version:

This is what I am using to pull active directory credentials and then call the script if they are in the correct user group:


-- Get the logged in users username

set loggedInUser to do shell script "whoami"


-- Get the Users account UniqueID

set accountType to do shell script "dscl . -read /Users/" & loggedInUser & " | grep UniqueID | cut -c 11-"


-- Get the nodeName from the Users account

set nodeName to do shell script "dscl . -read /Users/" & loggedInUser & " | awk '/^OriginalNodeName:/,/^Password:/' | head -2 | tail -1 | cut -c 2-"


-- Get the Users group membership from AD

set ADGroups to do shell script "dscl " & quoted form of nodeName & " -read /Users/" & loggedInUser & " | awk '/^dsAttrTypeNative:memberOf:/,/^dsAttrTypeNative:msExchHomeServerName:/'"


-- Get the Users AD Home Folder

set ADHome to do shell script "dscl " & quoted form of nodeName & " -read /Users/" & loggedInUser & "| grep SMBHome: | cut -c 10- | sed 's/\\\\/\\//g' "


-- Checks to see if account is an AD Account, if its not exit

if accountType is less than 1000 then

tell me to quit

end if


if ADGroups contains "Technology_Dept" then


run scriptfile "Macintosh HD:Users:Shared:Staff_Drives.scpt"


end if



Then I am am calling this to place the apps in the dock:


--APPLESCRIPT

set apps to {"/Users/Shared/Apps_Drive.app", "/Users/Shared/Apps_Drive.app"}

set apps to {"/Users/Shared/Public_Drive.app", "/Users/Shared/Public_Drive.app"}

set apps to {"/Users/Shared/Stu_Public.app", "/Users/Shared/Stu_Public.app"}

set apps to {"/Users/Shared/H_Drive.app", "/Users/Shared/H_Drive.app"}

set apps to {"/Users/Shared/Lock_Desktop.app", "/Users/Shared/Lock_Desktop.app"}


add_persistent_apps_to_dock(apps)


on add_persistent_apps_to_dock(argv)

(*

list argv : list of POSIX path of application bundles

*)

set args to ""

repeat with a in argv

set args to args & a'squoted form & space

end repeat

do shell script "/usr/bin/perl -CSDA <<'EOF' - " & args & " 2>&1

#

# @ARGV : array of absolute path of application bundles

#

use strict;

use Unicode::Normalize;


# get exisiting paths from persistent-apps in dock plist

my @paths = ();

my $t = qx[defaults read com.apple.dock persistent-apps];

while ($t =~ /\"_CFURLString\" = \"(.*)\";/og) {

$_ = $1;

s/\\x5c{2}U([0-9a-f]+)/pack('U*', hex($1))/ogie;

s/\\x5c{2}\"/\"/og;

push @paths, NFD($_); # normalise to NFD

}


# add given paths to persistent-apps in dock plist

map { s%/*\\z%/%o } @ARGV; # normalise bundle path so that it ends with single /

for (@ARGV) {

my $p = NFD($_); # normalise to NFD

my $re = qr/^\\Q$p\\E\\z/i;

unless (grep /$re/, @paths) { # only if not in persistent-apps

s/&/&amp;/og; # XML escape: & => &amp;

s/</&lt;/og; # XML escape: < => &lt;

s/'/'\\\\''/og; # shell escape: ' => '\\''

qx[

defaults write com.apple.dock persistent-apps -array-add '

<dict>

<key>tile-data</key>

<dict>

<key>file-data</key>

<dict>

<key>_CFURLString</key>

<string>$_</string>

<key>_CFURLStringType</key>

<integer>0</integer>

</dict>

</dict>

</dict>'

];

}

}


# restart Dock

qx[killall Dock];

EOF"

end add_persistent_apps_to_dock

--END OF APPLESCRIPT

I am not an expert when it comes to this so if I am doing it wrong, please let me know! Thank you so so so much!

Apr 28, 2016 7:21 PM in response to morelockc

Hello


If you're adding the five applications, you may simply set the variable apps to a list of them. Something like this:



set apps to {"/Users/Shared/Apps_Drive.app", "/Users/Shared/Public_Drive.app", "/Users/Shared/Stu_Public.app", "/Users/Shared/H_Drive.app", "/Users/Shared/Lock_Desktop.app"}




For better legibility, you can also write as follows:



set apps to {¬ "/Users/Shared/Apps_Drive.app", ¬ "/Users/Shared/Public_Drive.app", ¬ "/Users/Shared/Stu_Public.app", ¬ "/Users/Shared/H_Drive.app", ¬ "/Users/Shared/Lock_Desktop.app"}




or even like this (provided that each path does not contain newline character):



set apps to paragraphs of "/Users/Shared/Apps_Drive.app /Users/Shared/Public_Drive.app /Users/Shared/Stu_Public.app /Users/Shared/H_Drive.app /Users/Shared/Lock_Desktop.app"




Good luck,

H

May 2, 2016 5:40 AM in response to Hiroto

I have one last question for you since you seem to be so knowledgeable. Now that I have a working script, how can I make it run at login for all users and new users. The computers are bound to Active Directory and I need this script to run at login for all users and when new users login to the computer for the first time. If I add it to all users it will not solve the problem for new users? Thank in advance!

Customize Dock with Script

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.