Posted on 06-13-2016 07:15 AM
So, el capitan has a new binary called sfltool. It has been discussed a few times, and I have incorporated it into my firstrun script to add items to the sidebar. I think many more uses for this will be discovered.
Here is my script as an example.
#!/bin/bash
# Get the Username of the currently logged user
loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`
if [ -e /usr/local/bin/mysides ]
then
su - "$loggedInUser" -c "/usr/local/bin/mysides remove All My Files file:///System/Library/CoreServices/Finder.app/Contents/Resources/MyLibraries/myDocuments.cannedSearch/" && sleep 2
su - "$loggedInUser" -c "/usr/local/bin/mysides remove iCloud x-apple-finder:icloud" && sleep 2
su - "$loggedInUser" -c "/usr/local/bin/mysides remove domain-AirDrop nwnode://domain-AirDrop" && sleep 2
/usr/bin/sfltool add-item com.apple.LSSharedFileList.FavoriteItems file:///Users/$loggedInUser && sleep 2
/usr/bin/sfltool add-item com.apple.LSSharedFileList.FavoriteItems file:///Users/$loggedInUser/Desktop && sleep 2
/usr/bin/sfltool add-item com.apple.LSSharedFileList.FavoriteItems file:///Users/$loggedInUser/Documents && sleep 2
/usr/bin/sfltool add-item com.apple.LSSharedFileList.FavoriteItems file:///Users/$loggedInUser/Downloads && sleep 2
/usr/bin/sfltool add-item com.apple.LSSharedFileList.FavoriteItems file:///Users/$loggedInUser/Movies && sleep 2
/usr/bin/sfltool add-item com.apple.LSSharedFileList.FavoriteItems file:///Users/$loggedInUser/Music && sleep 2
/usr/bin/sfltool add-item com.apple.LSSharedFileList.FavoriteItems file:///Users/$loggedInUser/Pictures && sleep 2
touch /Users/$loggedInUser/.sidebarshortcuts
fi
/usr/libexec/PlistBuddy -c "Add :networkbrowser:CustomListProperties:com.apple.NetworkBrowser.backToMyMacEnabled bool False" /Users/$loggedInUser/Library/Preferences/com.apple.sidebarlists.plist
/usr/libexec/PlistBuddy -c "Add :networkbrowser:CustomListProperties:com.apple.NetworkBrowser.bonjourEnabled bool False" /Users/$loggedInUser/Library/Preferences/com.apple.sidebarlists.plist
killall cfprefsd
Posted on 06-13-2016 07:25 AM
To add an item to the Command+K connect to server favorites:
/usr/bin/sfltool add-item -n "foobar" com.apple.LSSharedFileList.FavoriteServers "afp://foo.bar"
Posted on 08-09-2016 07:56 AM
I have to ask. What's ~/.sidebarshortcuts?
Posted on 09-20-2016 06:24 AM
Is there a way to delete all server favourites?
Posted on 08-30-2017 01:53 PM
Same as @jamiegalbreath, I have server favorites that I need to remove somehow (in my case, the Server URL has a .local suffix that I need to remove).
I can create the new entry in the favorites list by using the commands above, but I end up with 2 entries in the list (1 with the .local address, which doesn't work with Sierra for some reason.... and one with the updated URL).
Does anyone know how to remove an existing server from the list (or even just clear the list)?
EDIT: I've determined that running an "sfltool clear" will wipe all of the shared file lists on logout (it looks like it deletes the contents of the "com.apple.sharedfilelists" folder).
I haven't figured out how to target just one list (like "Favorite Servers" for example).
Also, because it seems to require a logout to take effect, I can't add the new server after running the clear command (the behaviour I'm seeing is that if I try, it retains the bad server entry).
I've tried "killall cfprefsd" (is this even a thing anymore?), but it doesn't help.
Posted on 08-30-2017 01:56 PM
sfltool
.....10.13..... :(
Posted on 10-30-2017 12:38 PM
which sfltool in 10.13 returns /usr/bin/sfltool @bpavlov
Posted on 10-30-2017 01:50 PM
@djdavetrouble I know the tool is still there. But it's been crippled. It doesn't have the same functionality that it previously had the last time I checked.
Posted on 11-16-2017 11:32 AM
Yep. It's been gutted.
10.12Usage: sfltool restore|add-item|save-lists|test|archive|enable-modern|dump-server-state|clear|disable-modern|dump-storage|list-info [options]
10.13Usage: sfltool archive|list-info|list [options]
Posted on 11-28-2017 07:40 AM
Posted on 12-08-2017 08:35 AM
Apple! bring back sfltool in 10.13 !!!!
Posted on 01-16-2018 06:20 AM
Apple...
Posted on 01-16-2018 11:09 AM
"Apologies, we do not plan to add back the feature. You will need to write a tool that does what’s needed." -Apple
Posted on 01-16-2018 11:25 AM
«sigh»
Posted on 02-13-2018 08:06 AM
Had an app that mapped network drives and wrote Favorites icons to finder using slftool. Worked great in 10.12, in 10.13 I noticed when I ran the app it would create a .sfl2 file. So I'd see:
com.apple.LSSharedFileList.FavoriteItems.sfl
com.apple.LSSharedFileList.FavoriteItems.sfl2
Unfortunate that it appears I can't use the app anymore. Did anyone come up with a workaround for this?
Posted on 02-13-2018 04:54 PM
I don't have a workaround, but a 'work with [Apple] for future state'...
Rather than asking for a binary solution, I would ask for an MDM payload solution. The settings in question are ultimately stored in plists. This makes them ripe for configuration profile management.
Posted on 02-14-2018 02:54 AM
For 10.13 I switched to using FinderSidebarEditor
This uses the "deprecated" but still working LSSharedFileList commands and seems to be the only way to do sidebar tasks on 10.13. I'd say a a configuration profile is less than ideal, two of the items we regularly add to the sidebar are programmatically defined not static (network home and network shared space), profiles also wouldn't help for linking to locations which could be changed by the user (a OneDrive or OwnCloud folder), really sfltool was ideal and needed an improvement to delete entries.
Posted on 02-14-2018 05:23 AM
@dsavageED thanks, I will look into that. I haven't worked with Python before (have been focused on AppleScript and Bash) so it'll probably be a down-the-road kind of thing.
Posted on 02-14-2018 05:37 AM
@el2493 I am by no means that familiar with python ( I can read and code it a bit), but to leverage that script all you really need is:
#!/bin/bash
# Assuming FinderSidebarEditor.py script is stored in /usr/local/python you can call the function inside a bash script
python - <<EOF
import sys
sys.path.append('/usr/local/python') # Custom location script is installed to
from FinderSidebarEditor import FinderSidebar # Import the module
sidebar = FinderSidebar() # Create a Finder sidebar instance to act on.
sidebar.add("$path") # Add '$path' favorite to sidebar
EOF
Posted on 02-14-2018 06:00 AM
Thanks, that's very helpful!
Posted on 02-15-2018 06:19 AM
@dsavageED I'm going to keep looking into this, but since you had the previous information I was wondering what the format of "$path" should be? I tried /volumes/[share name] (and the favorite showed as a "?" and wouldn't open) before looking at the python code and finding it was going to be a little more complicated than that.
Trying to make sense of:
def add(self, to_add, uri="file://localhost"):
"""
Append item to sidebar list items.
Args:
to_add (str): Path to item to append to sidebar list.
Keyword Args:
uri (str): URI of server where item resides if not on localhost.
"""
if uri.startswith("afp") or uri.startswith("smb"):
path = "%s%s" % (uri, to_add)
to_add = mount_share(path)
item = NSURL.alloc().initFileURLWithPath_(to_add)
LSSharedFileListInsertItemURL(self.sflRef, kLSSharedFileListItemBeforeFirst, None, None, item, None, None)
self.synchronize()
self.update()
So would the path need to be defined as "%s%s" % (file://localhost, /volumes/[share name])? Or does it need the actual path of the drive/folder and not the volumes information? I also tried different combinations of "%s%s" % ([the path]) and wasn't having any luck.
Posted on 02-15-2018 06:53 AM
Figured it out...the path of the volume was /Volumes/share_name$ and the "$" was messing things up. Changed to /Volumes/share_name$ and it worked.
Posted on 03-04-2018 11:44 AM
Using FinderSidebarEditor, I have two questions:
EDIT: Regarding the home folder:
Using:
#!/usr/bin/python
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 + "
");'`
from FinderSidebarEditor import FinderSidebar # Import the module
sidebar = FinderSidebar() # Create a Finder sidebar instance to act on.
sidebar.remove("All My Files") # Remove 'All My Files' favorite from sidebar
sidebar.remove("iCloud") # Remove 'iCloud' favorite from sidebar
sidebar.add("/Library") # Add '/Library' favorite to sidebar
sidebar.add("/Applications") # Add '/Library' favorite to sidebar
sidebar.add("/Users/$CurrentUser/Desktop") # Add '/Library' favorite to sidebar
sidebar.add("/Users/$CurrentUser/Downloads") # Add '/Library' favorite to sidebar
^
I get the following error (TextWrangler points to the last character in the variable line).
File "/usr/local/bin/Test2.py", line 3
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 + "
");'`
Posted on 03-05-2018 11:51 AM
@gskibum mysides seems to work a little easier than FinderSidebarEditor, despite it not being updated in a few years, but outside of that, I'm pretty sure your error is related to the fact that python variables from commands don't use the backtick syntax like in bash.
I don't really know python, but I made the following modification to the beginning of your script and it seems to at least get the correct logged in user's name. Not sure if the rest of it will work since I didn't really try it.
#!/usr/bin/python
from SystemConfiguration import SCDynamicStoreCopyConsoleUser
import sys
CurrentUser = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [CurrentUser,""][CurrentUser in [u"loginwindow", None, u""]]
The main issue is that you had the backtick syntax, plus, you're using a python one liner within a python script, but it was only ever a one liner because of needing to embed it into bash scripts. Since your entire script is python, I broke out the individual commands. Also, it's possible that to use a path to mysides that includes that CurrentUser variable, something else in the script needs to be changed. I don't think you just string them together like that in python.
Again, I really don't know python, so this might be a horrible way to do it. I just don't know what I don't know, so, there you go :-)
Posted on 03-05-2018 01:42 PM
Some Python pros over at Slack got me working with this:
from SystemConfiguration import SCDynamicStoreCopyConsoleUser
username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]
username = [username, ""][username in [u"loginwindow", None, u""]]
Then call it like this:
sidebar.add("/Users/%s/Pictures" % username)
Posted on 03-12-2018 06:52 PM
How are ya'll adding AirDrop back to the Finder Sidebar?
I'm trying this command with mysides but getting nowhere:
$mysides add domain-AirDrop "nwnode://domain-AirDrop"
killall cfprefsd
Posted on 04-23-2018 01:35 PM
With slftool
not able to add favorites in High Sierra, I set out on a journey to find an alternative. The sfl2 format is just a Foundation.NSKeyedArchiver
dump, so I wrote the following python script to generate the Server Favorites file:
Edit: See my post below for a script that applies to all users.
Edit 2: The latest version of these scripts are available here.
# some inspiration from: https://github.com/quicksilver/Quicksilver/blob/master/Quicksilver/Code-QuickStepCore/QSObject_FileHandling.m
# get the latest version of this script at: https://gist.github.com/korylprince/be2e09e049d2fd721ce769770d983850
import os
import uuid
import Foundation
servers = ("smb://server.example.com/share", "vnc://server.example.com")
user = "administrator"
items = []
for server in servers:
item = {}
item["Name"] = unicode(server)
url = Foundation.NSURL.URLWithString_(unicode(server))
bookmark, _ = url.bookmarkDataWithOptions_includingResourceValuesForKeys_relativeToURL_error_(0, None, None, None)
item["Bookmark"] = bookmark
item["uuid"] = unicode(uuid.uuid1()).upper()
item["visibility"] = 0
item["CustomItemProperties"] = Foundation.NSDictionary.new()
items.append(Foundation.NSDictionary.dictionaryWithDictionary_(item))
data = Foundation.NSDictionary.dictionaryWithDictionary_({
"items": Foundation.NSArray.arrayWithArray_(items),
"properties": Foundation.NSDictionary.dictionaryWithDictionary_({"com.apple.LSSharedFileList.ForceTemplateIcons": False})
})
Foundation.NSKeyedArchiver.archiveRootObject_toFile_(data, "/Users/{user}/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.FavoriteServers.sfl2".format(user=user))
os.system("killall sharedfilelistd")
Some caveats:
Foundation.NSKeyedUnarchiver
and append data to it pretty easily as well.sharedfilelistd
.Hope someone finds this useful!
Posted on 05-11-2018 09:09 AM
@korylprince This did the trick for me. Much appreciated.
I just needed a simple way to deploy/mange SMB file server URL favorites which appear in the Finder's "Connect to Server..." box. All previous options have been "broken" since 10.13 High Sierra. Our file servers dont change often, but when they do its critical that all users know how to manually navigate to the new servers (in situations when a login script didn't/couldn't mount them)
I'm not a Python scripter (yet), so what I need to figure out next is how to extend your single-user focus out to recursively apply to ALL local homedirs in /Users.
Posted on 05-14-2018 07:22 AM
@dstranathan Here's an updated script that will loop through all active users.
Edit: The latest version of these scripts are available here.
# get the latest version of this script at: https://gist.github.com/korylprince/be2e09e049d2fd721ce769770d983850
import os
import subprocess
import uuid
import Foundation
servers = ("smb://server.example.com/share", "vnc://server.example.com")
def get_users():
"Get users with a home directory in /Users"
# get users from dscl
dscl_users = subprocess.check_output(["/usr/bin/dscl", ".", "-list", "/Users"]).splitlines()
# get home directories
homedir_users = os.listdir("/Users")
# return users that are in both lists
users = set(dscl_users).intersection(set(homedir_users))
return [u.strip() for u in users if u.strip() != ""]
def set_favorites(user, servers):
"Set the Server Favorites for the given user"
# generate necessary structures
items = []
for server in servers:
item = {}
# use unicode to translate to NSString
item["Name"] = unicode(server)
url = Foundation.NSURL.URLWithString_(unicode(server))
bookmark, _ = url.bookmarkDataWithOptions_includingResourceValuesForKeys_relativeToURL_error_(0, None, None, None)
item["Bookmark"] = bookmark
# generate a new UUID for each server
item["uuid"] = unicode(uuid.uuid1()).upper()
item["visibility"] = 0
item["CustomItemProperties"] = Foundation.NSDictionary.new()
items.append(Foundation.NSDictionary.dictionaryWithDictionary_(item))
data = Foundation.NSDictionary.dictionaryWithDictionary_({
"items": Foundation.NSArray.arrayWithArray_(items),
"properties": Foundation.NSDictionary.dictionaryWithDictionary_({"com.apple.LSSharedFileList.ForceTemplateIcons": False})
})
# write sfl2 file
Foundation.NSKeyedArchiver.archiveRootObject_toFile_(data, "/Users/{user}/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.FavoriteServers.sfl2".format(user=user))
# loop through users and set favorites
if __name__ == "__main__":
for user in get_users():
try:
set_favorites(user, servers)
print "Server Favorites set for " + user
except Exception as e:
# if there's an error, log it an continue on
print "Failed setting Server Favorites for {0}: {1}".format(user, str(e))
# kill sharedfilelistd process to reload file. Finder should be closed when this happens
os.system("killall sharedfilelistd")
I've also added some comments to explain what the code does. Also note that this won't do anything for a User who hasn't signed in yet. This only works for users that already have a home directory created in /Users
. All of the caveats from my post above still apply.
Posted on 05-25-2018 11:45 AM
@korylprince Very nice. I have been using this script with a jamf policy to generate shortcuts:
when used as a script payload, the even variables are urls and the odd variable is the finder name.
I don't know python yet, but this gives me an excuse to learn.
#!/bin/bash
evens=( "$4" "$6" "$8" "${10}" )
odds=( "$5" "$7" "$9" "${11}" )
for ((i=0;i<${#evens[@]};++i)); do
if [[ -n ${evens[i]} ]]; then
sfltool add-item -n "${odds[i]}" com.apple.LSSharedFileList.FavoriteServers "${evens[i]}" &> /dev/null &&
sleep 2
/usr/libexec/PlistBuddy -c "Add URL string '${evens[i]}'" "/Users/$3/Desktop/Server Aliases/${odds[i]}.afploc"
fi
done
Posted on 06-22-2018 12:11 PM
@korylprince are you using #!/usr/bin/python to run this?
I have run the script using #!/usr/bin/python and get this echoed in terminal - "Server Favorites set for username" , but nothing shows even after logout/login or restart.
Maybe I am missing something in the compiler?
Thanks
Michael
Posted on 07-13-2018 02:02 PM
@korylprince, where do I send the bitcoins?!
Thank guy guys, this is great!
Posted on 07-18-2018 02:03 PM
@mlitton,
I was just running sudo python /path/to/script.py
, but using #!/usr/bin/python
will work as well. All Finder windows must be closed or the changes may not apply.
I have updated my scripts. One can be used to overwrite the current favorites, and the other can merge into existing favorites, optionally also removing specified servers. If the scripts are run as root, they will affect all users. If they are run as a normal user they will just affect that user.
You can see them on GitHub.
Posted on 07-19-2018 08:50 AM
I have been using versions of Kory's scripts - they work great. I finally have robust control over deploying and managing Server URL favorites. I'm a happy camper.
I use have both versions of the script (destructive and non-destructive). There was time when I needed to add a single specific new SMB server. I didn't want to break/delete any user's existing Server Favorites (used a non-destructive version). In another situation, we migrated to new SMB servers, so I replaced ALL Server URL Favorites with new Favorites - so user's weren't confused (I used a destructive 'nuke & pave' version of the script).
Posted on 07-27-2018 08:49 AM
@djdavetrouble I'm not nearly as familiar with python as I should be. Did you get anywhere in your version such that you could set both the server and the Finder name?
Posted on 09-11-2018 02:41 PM
I'm in the same boat. Is there any version of any of these scripts that allows for, at least, adding an entry and it's "friendly name"?
Posted on 09-11-2018 02:50 PM
This is super clunky but works from 10.9 to 10.13 (running as the user):
#!/bin/bash
path="/path/you/want/to/add"
function side_shortcut () {
/usr/bin/osascript > /dev/null 2>&1 <<-END
tell application "Finder" to activate
tell application "System Events"
try
keystroke "t" using {command down, control down}
end try
end tell
END
}
/usr/bin/open "$path"
side_shortcut
exit 0
Posted on 09-14-2018 06:34 AM
Hi guys so I'm running into a slight issue with this and feel like I'm missing something. Here is the script I'm currently running.
#!/bin/sh
python - <<EOF
import sys
sys.path.append('/usr/local/bin')
from FinderSidebarEditor import FinderSidebar # Import the module
sidebar = FinderSidebar() # Create a Finder sidebar instance to act on.
sidebar.removeAll() # Remove All Favorites from sidebar
sidebar.add("/Applications") # Add '/Applications' favorite to sidebar
sidebar.add("/Users/testuser/Desktop") # Add 'User Desktop' favorite to sidebar
sidebar.add("/Users/testuser/Documents") # Add 'User Documents' favorite to sidebar
sidebar.add("/Users/testuser/Downloads") # Add 'User Downloads' favorite to sidebar
EOF
Now if I run this locally, or as a command through ARD it does exactly what I expect it to do. However the moment I try running it through Jamf Remote it stops functioning. Logs say it completed successfully but the changes are never made to Finder for the currently logged in user. Just to further test I added the following lines at the bottom.
import os
path = '/Users/testuser/Desktop/PYTHON'
os.mkdir(path)
Running through Jamf Remote this does create a folder on the Desktop called "PYTHON" so from what I can tell the script does appear to be running correctly in every sense, Finder is just not refreshing correctly.
Forgot to mention I have tried running the script with "killall cfprefsd" and/or "killall Finder" at the end just to see if this would give any different results but it's still the same.
Thanks.
Posted on 09-18-2018 02:04 PM
I've updated my example scripts on GitHub to include the ability to set a favorite name.
Example:
servers = (("My Name", "smb://example.com/share"), "vnc://example.com")
This would create a favorite named "My Name" pointed to smb://example.com/share
and another favorite both named and pointed to vnc://example.com
.
Hopefully this should do what you're wanting.
Posted on 09-18-2018 02:23 PM
Much appreciated, @korylprince .
Because of timing and my inability to full vet and test this before we deployed I moved most of these shortcuts to NoMAD, as we can configure who has access to what based on AD security group membership and our NoMAD shares config profile.