Redirecting Local Home Folders to Shared Folders

shalford
New Contributor

We are trying to redirect locally created home folders on our 10.10 (Yosemite) workstations to a shared folder we have setup. I have attached the script we are trying to use below. The folder creation part of the script works fine. I am getting “Access Denied” when trying to delete the user folders and then trying to create the symbolic link to the share. I changed the variable $USER to $3 when pushing out through JSS.

I remember doing this with MCX in the days of OS X 10.6 but I know this is no longer supported in 10.10. Can anyone assist?

!/bin/sh

-------------- Define Directories ----------------

MYHOMEDIR=“/Volumes/HomeFolders/2016-2017/$USER”
MYDOCDIR=“/Volumes/HomeFolders/2016-2017/$USER/Documents”
MYPICDIR=“/Volumes/HomeFolders/2016-2017/$USER/Pictures”
MYMUSDIR=“/Volumes/HomeFolders/2016-2017/$USER/Music”
MYMOVDIR=“/Volumes/HomeFolders/2016-2017/$USER/Movies”
MYDESDIR=“/Volumes/HomeFolders/2016-2017/$USER/Desktop”
MYLIBDIR=“/Volumes/HomeFolders/2016-2017/$USER/Library”

----------------- Checking Folders ---------------

if [ -d "$MYHOMEDIR" ]; then
echo "$MYHOMEDIR is Available!"
else
mkdir /Volumes/HomeFolders/2016-2017/$USER
fi

if [ -d "$MYDOCDIR" ]; then
echo "$MYDOCDIR is Available!"
else
mkdir /Volumes/HomeFolders/2016-2017/$USER/Documents
fi

if [ -d "$MYPICDIR" ]; then
echo "$MYPICDIR is Available!"
else
mkdir /Volumes/HomeFolders/2016-2017/$USER/Pictures
fi

if [ -d "$MYMUSDIR" ]; then
echo "$MYMUSDIR is Available!"
else
mkdir /Volumes/HomeFolders/2016-2017/$USER/Music
fi

if [ -d "$MYMOVDIR" ]; then
echo "$MYMOVDIR is Available!"
else
mkdir /Volumes/HomeFolders/2016-2017/$USER/Movies
fi

if [ -d "$MYDESDIR" ]; then
echo "$MYDESDIR is Available!"
else
mkdir /Volumes/HomeFolders/2016-2017/$USER/Desktop
fi

if [ -d "$MYLIBDIR" ]; then
echo "$MYLIBDIR is Available!"
else
mkdir /Volumes/HomeFolders/2016-2017/$USER/Library
fi

ECHO ----------------- Redirecting Folders ---------------

Wait for OS X to Create Local Homes

sleep 4

rm -Rf "/Users/$USER/Documents"
ln -sFfh "/Volumes/HomeFolders/2016-2017/$USER/Documents" "/Users/$USER"

rm -Rf "/Users/$USER/Desktop"
ln -sFfh "/Volumes/HomeFolders/2016-2017/$USER/Desktop" "/Users/$USER"

rm -Rf "/Users/$USER/Pictures"
ln -sFfh "/Volumes/HomeFolders/2016-2017/$USER/Pictures" "/Users/$USER"

rm -Rf "/Users/$USER/Movies"
ln -sFfh "/Volumes/HomeFolders/2016-2017/$USER/Movies" "/Users/$USER"

rm -Rf "/Users/$USER/Music"
ln -sFfh "/Volumes/HomeFolders/2016-2017/$USER/Music" "/Users/$USER"

rm -Rf "/Users/$USER/Library"
ln -sFfh "/Volumes/HomeFolders/2016-2017/$USER/Library" "/Users/$USER"

ECHO ----------------- Completed Script -------------------

39 REPLIES 39

psmac
New Contributor III

Hi Shalford,

I think you're running in to ACLs on the local home folder.

If you run;

chmod -RN /Users/$USER

before your symbolic links then this should work

Paul

shalford
New Contributor

Thank you Paul! That seems like it will work for the folder ownership. Next issue, how would I go about delaying the time between when the mapped drive is created and the symlinks are mapped? it seems the script is creating the symlinks before the mapped drive is mounted. I tried using the 'sleep' command with delay of 60 and this did not work.

psmac
New Contributor III

Hi Scott,

Here's the code i normally use when we do this for our education customers;

#!/bin/sh

#Redirect home folders to server
mounted=1
folders=("Music" "Movies" "Pictures" "Documents")

echo "starting redirects"

while [ $mounted -gt 0 ]; do
echo "sleeping"
sleep 5

if [ -d "$MYHOMEDIR" ]; then

    chmod -RN /Users/$USER

    for i in "${folders[@]}"; do

        if [ -d "$MYHOMEDIR/$i" ]; then

            echo "$i available, testing existing sym links"

            if [ ! -L /Users/$USER/$i ]; then

                echo "$i folder not linked, now linking"
                rm -R /Users/$USER/$i
                ln -s "$MYHOMEDIR/$i" /Users/$user/

            else

                echo "$i already linked, going away now"
            fi
        fi
    done

    mounted=`expr $mounted - 1`
else
    echo "$MYHOMEDIR not available, waiting..."
fi

done

This waits for the volume to become available, checks to see if the symbolic link is already created and only creates if needed.

The only other thing to consider is how the share is initially mounted - are you mounting it as part of the script?

dsavageED
Contributor III

You could probably use something like netstat to ensure the connection is in place, with a loop. I have used similar code to wait for an application launching at login, so in theory the following should work:

serverIP="123.456.789.101"
count=0

if ! ping -c 1 $serverIP | grep -q '1 packets received'
then
    echo no response to ping, server down.
else
    # While I can ping the server and it is not mounted wait until it is or the counter is maxed.
    # "$serverIP.445" is for an SMB server.
    until netstat -an | grep "ESTABLISHED" | grep "$serverIP.445"; do
        sleep 2
        # Safety counter to kill the loop just incase.
        if [ $count -gt 60 ];
        then
            echo max tries reached, breaking
            break
        fi
        count=$[$count+1]
    done
fi

Note that this is cobbled together from 2 pieces of code I have used in the past so...

EDIT - probably go with psmac's example :-)

shalford
New Contributor

Paul,

I tried to mount the drive in both a separate script and the same script as the symlink redirect code. I was unsuccessful in both.

How are you achieving this?

Also, would you recommend keeping the Libraries folder local to the machine?

psmac
New Contributor III

Hi Scott,

Which part is failing for you?

Paul

shalford
New Contributor

Paul,

When I mount the drive manually on the workstation and run the script from terminal I get the following message.

“/Volumes/HomeFolders/2016-2017/?? not available, waiting...
sleeping

I added the 'MYHOMEDIR' variable location above the 'folders' array. Was this correct?

!/bin/sh

Redirect home folders to server

mounted=1

MYHOMEDIR=“/Volumes/HomeFolders/2016-2017/$USER”
folders=("Music" "Movies" "Pictures" "Documents")

I see that your script does not automatically create the folders on the server if they do not exist, do you have something for this?

psmac
New Contributor III

Hi Scott,

I tend to have a script run on the server to create user home folders and generate the containing folders as needed, but if you want to populate the contents from the client, then try something like this;

#!/bin/sh

USER=`whoami`
MYHOMEDIR="/Volumes/HomeFolders/2016-2017/$USER"

#MOUNT SHARE HERE

#Redirect home folders to server
mounted=1
folders=("Music" "Movies" "Pictures" "Documents")

echo "starting redirects"

while [ $mounted -gt 0 ]; do
echo "sleeping"
sleep 5

if [ -d "$MYHOMEDIR" ]; then

    chmod -RN /Users/$USER

    for i in "${folders[@]}"; do

        if [ -d "$MYHOMEDIR/$i" ]; then
            echo "$i available"
        else
           echo "$i not available, creating...."
           mkdir "$MYHOMEDIR/$i"
        fi

        echo "testing symlinks"

        if [ ! -L /Users/$USER/$i ]; then
             echo "$i folder not linked, now linking"
             rm -R /Users/$USER/$i
             ln -s "$MYHOMEDIR/$i" /Users/$USER/
        else
                echo "$i already linked, going away now"
            fi
    done

    mounted=`expr $mounted - 1`
else
    echo "$MYHOMEDIR not available, waiting..."
fi

done

Are you mounting the share "HomeFolders" or are you going directly to the users folder to mount?

Paul

shalford
New Contributor

Paul,

Your script worked great! I just added a line to create the user folder inside the "HomeFolders" share.

We are currently mounting the "HomeFolders" share using a JSS Kerberos script which I ran into a slight issue with. The script works great when I am logged in as the user and run from the command line.

When the script is ran along side the "HomeFolders" mount script the computer just sits trying to get past the log in screen. I am guessing it is stuck somewhere?

Should I try running the script as a login item?

I appreciate all the help!

psmac
New Contributor III

Hi Scott,

Sounds like the script may be written to run as the user. If you've got it set as a login policy then it will run as root and you'll likely hit issues.

Do you want to post your script and how you're calling it and I'll see if I can spot the problem.

Paul

shalford
New Contributor

Hi Paul,

I am first mounting the HomeFolder Script with the JSS script below. I am then using the script below that to redirect the home folders on the work station. Please note these are both JSS scripts and I believe the $3 variable should take care of the script being run as the user.

#!/bin/sh
####################################################################################################
#
# Copyright (c) 2010, JAMF Software, LLC.  All rights reserved.
#
#       Redistribution and use in source and binary forms, with or without
#       modification, are permitted provided that the following conditions are met:
#               * Redistributions of source code must retain the above copyright
#                 notice, this list of conditions and the following disclaimer.
#               * Redistributions in binary form must reproduce the above copyright
#                 notice, this list of conditions and the following disclaimer in the
#                 documentation and/or other materials provided with the distribution.
#               * Neither the name of the JAMF Software, LLC nor the
#                 names of its contributors may be used to endorse or promote products
#                 derived from this software without specific prior written permission.
#
#       THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
#       EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
#       WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#       DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
#       DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
#       (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#       LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
#       ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#       (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#       SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
####################################################################################################
#
# SUPPORT FOR THIS PROGRAM
#
#       This program is distributed "as is" by JAMF Software, LLC's Resource Kit team. For more
#       information or support for the Resource Kit, please utilize the following resources:
#
#               http://list.jamfsoftware.com/mailman/listinfo/resourcekit
#
#               http://www.jamfsoftware.com/support/resource-kit
#
#       Please reference our SLA for information regarding support of this application:
#
#               http://www.jamfsoftware.com/support/resource-kit-sla
#
####################################################################################################
#
# ABOUT THIS PROGRAM
#
# NAME
#   mountNetworkShare.sh -- Mount a network share.
#
# SYNOPSIS
#   sudo mountNetworkShare.sh
#   sudo mountNetworkShare.sh <mountPoint> <computerName> <loginUsername> <shareUsername>
#                               <authType> <password> <mountType> <share>
#
# DESCRIPTION
#   This script was designed to mount a network share on an event such as user login, or through a
#   self service policy.  Using Casper's policy engine, a policy can be scoped so that
#   users and groups (local or directory-based) will mount run this script, and therefore mount the
#   assigned network share.  For directory-based users, it is recommended to use the "kerberos"
#   authentication type.  For local users, the "password" authentication type must be used.
#
#   For kerberos authentication to work properly, the user must be able to manually mount the share
#   when logged in by navigating to "Go" > "Connect to Server..." in the Finder and the user must be
#   able to mount the share without authenticating.  To ensure that your directory users are
#   obtaining kerberos tickets properly, navigate to "System" > "Library" > "CoreServices" and open
#   the "Kerberos Ticket Viewer" application while a directory user is logged in.
#
####################################################################################################
#
# HISTORY
#
#   Version: 1.3
#
#   - Created by Nick Amundsen on May 8th, 2009
#   - Updated by Cam Evjen on March 5, 2010
#   - Updated by Nick Amundsen on April 30th, 2010
#   - Updated by Nick Amundsen on October 12th, 2010
#       - Improved Error Handling
#       - Simplified Variables
#       - Added Support for Reading SMB Paths from DFS Referrals
# 
####################################################################################################
#
# DEFINE VARIABLES & READ IN PARAMETERS
#
####################################################################################################

# HARDCODED VALUES SET HERE
shareUsername="$3"    #The username of the user to be used to mount the share - leaving this to $3 will mount the share as the currently logged in user
authType="kerberos"   #Valid values are "kerberos" (default) or "password"
password=""           #Note this only needs to be set if authentication type is "password"
mountType="smb"       #The type of file share. Valid types are "afp", "smb", or "dfs".  DFS only supports the "kerberos" authentication method
share='smb://csdmacserv02.csdfm.local/HomeFolders'            #The address of the share you are mounting - if left blank, the script will search for the "SMBHome" attribute in the user record
                        #Example Values:
                                #SMB Share: smb://server.company.com/share
                                #AFP Share: afp://server.company.com/share
                                #DFS Path: \server.company.comdfsroot	arget

# CHECK TO SEE IF A VALUE WERE PASSED IN FOR PARAMETERS $3 THROUGH $9 AND, IF SO, ASSIGN THEM

if [ "$4" != "" ] && [ "$shareUsername" == "" ]; then
    shareUsername=$4
fi

if [ "$5" != "" ] && [ "$authType" == "" ];then
    authType=$5
fi

if [ "$6" != "" ] && [ "$password" == "" ]; then
    password=$6
fi

if [ "$7" != "" ] && [ "$mountType" == "" ]; then
    mountType=$7
fi

if [ "$8" != "" ] && [ "$share" == "" ];then
    share=$8
fi


####################################################################################################
# 
# SCRIPT CONTENTS - DO NOT MODIFY BELOW THIS LINE
#
####################################################################################################
loginUsername="$3"
OS=`/usr/bin/defaults read /System/Library/CoreServices/SystemVersion ProductVersion | awk '{print substr($1,1,4)}'`

if [ "$loginUsername" == "" ]; then
    echo "Error:  This script must be run at the login trigger.  Please correct the trigger that is being used to run the policy."
    exit 1
fi

if [ "$authType" == "" ]; then
    echo "Error:  The parameter 'authType' is blank.  Please specify the auth type you would ike to use.  Valid values are 'password' or 'kerberos'"
    exit 1
fi

if [ "$mountType" == "" ]; then
    echo "Error:  The parameter 'mountType' is blank.  Please specify the mount type you would ike to use.  Valid values are 'afp', 'smb', or 'dfs'"
    exit 1
fi

if [ "$mountType" == "dfs" ] && [ "$authType" == "password" ]; then
    echo "Error:  The DFS mount type only supports kerberos authentication."
    exit 1
fi

if [ "$mountType" == "dfs" ] && [ "$share" != "" ]; then
    #Convert the characters in the share over to the proper format
    share="\\$share"
fi

if [ "$share" == "" ] && [ "$mountType" != "afp" ]; then
    #If the share parameter is blank, try to read the SMBHome attribute (home directory) from the LDAP server
    echo "Attempting to read SMBHome attribute from user record since the 'share' parameter is blank..."
    share=`/usr/bin/dscl /Search read /Users/$loginUsername SMBHome | head -1 | awk '{print $2}'`
    #If the share is still blank, report an error.
    if [ "$share" == "" ]; then
        echo "Error:  Could not obtain a share from dscl.  Please specify the path to the share you would like to mount."
        exit 1
    else
        if [ "$mountType" == "dfs" ]; then
            #Convert the characters in the share over to the proper format
            share="\\$share"
        elif [ "$mountType" == "smb" ]; then
            #Convert the characters in the share over to the proper format
            share="\\$share"
            share=`echo $share | sed 's:\:/:g'`
            share="smb:$share"
        fi
        echo "Share determined to be: $share."
    fi
fi

#Determine a volume name based on the share
volumeName=`echo "$share" | sed 's:\: :g' | sed 's:/: :g' | awk '{print $(NF-0)}'`
echo "Volume name will be created as $volumeName..."
if [ -d "/Volumes/$volumeName" ]; then
    result=`ls -A /Volumes/$volumeName`
    if [ "$result" == "" ]; then
        echo "Removing Empty Directory: /Volumes/$volumeName..."
        rmdir "/Volumes/$volumeName"
    else
        echo "Error: Directory /Volumes/$volumeName is not empty."
        exit 1
    fi
fi


if [ "$authType" == "kerberos" ]; then
    ##MOUNT A SHARE WITH KERBEROS AUTHENTICATION
    echo "Attempting to mount $mountType $share using $loginUsername's kerberos ticket..."

    #CREATE A LAUNCH AGENT TO MOUNT THE DRIVES
    /usr/bin/su -l "$loginUsername" -c "/usr/bin/defaults write ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName Label -string com.jamfsoftware.mapdrive.$volumeName"
    if [ "$mountType" == "smb" ] || [ "$mountType" == "dfs" ]; then
        if [ "$mountType" == "dfs" ]; then
            #Lookup SMB referral for DFS Share
            #Convert share into format acceptable for smbclient
            share=`echo $share | sed 's:\:/:g'`
            #Lookup the DFS SMB referral
            echo " Looking up SMB referral for DFS Share: $share..."
            share=`/usr/bin/smbclient $share -k -c showconnect | tail -1`
            echo " Share name referral found to be: $share."
            #Convert referral over to format acceptable for SMB mounting
            share="smb:$share"
        fi
        if [[ "$OS" < "10.6" ]]; then
            #Convert share over to proper format
            share=`echo $share | sed 's#smb://##g'`
            #Write out a launch agent
            /usr/bin/su -l $loginUsername -c "/usr/bin/defaults write ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName ProgramArguments -array /bin/sh -c "/bin/mkdir /Volumes/$volumeName; /sbin/mount_smbfs //$loginUsername@$share /Volumes/$volumeName""
        else
            #Apple bug in 10.6 prevents us from using mount_smbfs... if that bug gets fixed, we will revert to it

            #Write out a launch agent
            echo "Writing out launch agent to /Users/$loginUsername/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist"
            /usr/bin/su -l "$loginUsername" -c "/usr/bin/defaults write ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName ProgramArguments -array /bin/sh -c replaceMe"

            #Convert share over to proper format
            share=`echo $share | sed 's#smb://##g'`

            #Write in the proper mount command to the plist.  Using sed because defaults write doesn't like quotes or double quotes.
            /usr/bin/su -l "$loginUsername" -c "/usr/bin/plutil -convert xml1 ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist"
            /usr/bin/sed "s:replaceMe:/usr/bin/osascript -e 'mount volume ("smb://$share")':g" "/Users/$loginUsername/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist" > "/private/tmp/com.jamfsoftware.mapdrive.$volumeName.plist.tmp"
            /bin/mv "/private/tmp/com.jamfsoftware.mapdrive.$volumeName.plist.tmp" "/Users/$loginUsername/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist"
            /usr/sbin/chown "$loginUsername":staff "/Users/$loginUsername/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist"
            /bin/chmod 644 "/Users/$loginUsername/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist"
        fi
    else
        #Mount Over AFP Using Kerberos

        #Convert share over to proper format
        share=`echo $share | sed 's#afp://##g'`

        #WRITE OUT LAUNCH AGENT TO MOUNT THE DRIVES
        /usr/bin/su -l "$loginUsername" -c "/usr/bin/defaults write ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName ProgramArguments -array /bin/sh -c "/bin/mkdir /Volumes/$volumeName ; /sbin/mount_afp -N 'afp://;AUTH=Client%20Krb%20v2@"$share"' /Volumes/$volumeName""
    fi
    /usr/bin/su -l "$loginUsername" -c "/usr/bin/defaults write ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName RunAtLoad -bool true"

    #LOAD THE LAUNCH AGENT
    if /usr/bin/su -l "$loginUsername" -c "/bin/launchctl list | grep com.jamfsoftware.mapdrive.$volumeName"
    then
        echo "Unloading com.jamfsoftware.mapdrive.$volumeName..."
        /usr/bin/su -l "$loginUsername" -c "/bin/launchctl unload ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist"
    fi
    echo "Loading com.jamfsoftware.mapdrive.$volumeName..."
    /usr/bin/su -l "$loginUsername" -c "/bin/launchctl load ~/Library/LaunchAgents/com.jamfsoftware.mapdrive.$volumeName.plist"
else
    ##MOUNT A SHARE WITH PASSWORD AUTHENTICATION
    if [ "$password" == "" ]; then
        echo "It appears that you are attempting to mount a sharepoint using password authentication, but the password parameter is blank.  Please enter a password for the 'password' parameter of this script."
        exit 1
    fi
    echo "Attempting to mount $mountType://$serverAddress/$share using a password..."
    serverAddress=`echo "$share" | sed 's:/: :g' | awk '{print $2}'`
    share=`echo "$share" | sed 's:/: :g' | awk '{print $3}'`
    /usr/bin/su "$loginUsername" -c "/usr/local/jamf/bin/jamf mount -server "$serverAddress" -share "$share" -type "$mountType" -username "$shareUsername" -password "$password""
fi


exit 0

2nd script.

#!/bin/sh

MYHOMEDIR="/Volumes/HomeFolders/2016-2017/$3"

#MOUNT SHARE HERE

#Redirect home folders to server
mounted=1
folders=("Music" "Movies" "Pictures" "Documents")

echo "starting redirects"

while [ $mounted -gt 0 ]; do
echo "sleeping"
sleep 5

if [ -d "$MYHOMEDIR" ]; then

chmod -RN /Users/$3

for i in "${folders[@]}"; do

if [ -d "$MYHOMEDIR/$i" ]; then
echo "$i available"
else
echo "$i not available, creating...."
mkdir "$MYHOMEDIR/$i"
fi

echo "testing symlinks"

if [ ! -L /Users/$3/$i ]; then
echo "$i folder not linked, now linking"
rm -R /Users/$3/$i
ln -s "$MYHOMEDIR/$i" /Users/$3/
else
echo "$i already linked, going away now"
fi
done

mounted=`expr $mounted - 1`
else
echo "$MYHOMEDIR not available, waiting..."
mkdir "$MYHOMEDIR"
fi

done

psmac
New Contributor III

Hi Scott,

Sorry for the late reply

Are you running these as two separate policies or as two scripts within the same policy? The only reason i ask is that they will run in alphabetical order, so just wanted to make sure the link script isn't running before the mount script.

Also, to run the second script as a login triggered policy, you'll probably need to add a couple of things in to make some of the commands function correctly.

sudo -u $3

this would need to go before the lines for;

ln -s

and

mkdir

so they become

sudo -u $3 ln -s
sudo -u $3 mkdir

this way they get run as the logged in user rather than the root user that is executing the script.

Also, have you checked the policy logs to see which bit it is getting stuck on?

Paul

chrisx
New Contributor

Hi Everbody,

I''m looking for a similar solution
We use Open Directory with a local library/home.

So what i basacally want is:
When the User logs in with his username and password it should check who is actually logged in and mount the documents,pictures,movies into his Finder sidebar from the user home which is located on the server..

Can anyone help me out with this?

Thanks a lot.

psmac
New Contributor III

Hi Christian,

Which bit do you need help with? If you can mount the home, then the above scripts will symlink some of the local home folders to the network home.

If you want to then stick some of the folders in the Finder sidebar I would download and install on each client "my sides";

https://github.com/mosen/mysides/releases

You can then run code similar to below on the client;

#Run MySides to properly modify the Finder Sidebar - only runs once per user
if [ ! -e /Users/$user/.sidebarshortcuts ]; then
    /usr/local/bin/mysides remove all
    #/usr/local/bin/mysides add All My Files file:///System/Library/CoreServices/Finder.app/Contents/Resources/MyLibraries/myDocuments.cannedSearch/
    #/usr/local/bin/mysides add iCloud x-apple-finder:icloud
    /usr/local/bin/mysides add Mac Home file:///Volumes/$user
    /usr/local/bin/mysides add domain-AirDrop nwnode://domain-AirDrop
    /usr/local/bin/mysides add Applications file:///Applications
    /usr/local/bin/mysides add Desktop file:///Users/$user/Desktop
    /usr/local/bin/mysides add Documents file:///Volumes/$user/Documents
    /usr/local/bin/mysides add Downloads file:///Users/$user/Downloads
    /usr/local/bin/mysides add Movies file:///Volumes/$user/Movies
    /usr/local/bin/mysides add Music file:///Volumes/$user/Music
    /usr/local/bin/mysides add Pictures file:///Volumes/$user/Pictures

    touch /Users/$user/.sidebarshortcuts
fi

Let me know if you need anything else.

Paul

chrisx
New Contributor

HI Paul

Thanks for your quick reply, really appreciate that.

Okay basically we use a Open Directory Server on a OSX Server. We used to have Networkusers/Networkhomes...but there are to many problems with it you porably know yourself. :-) That's why we would like to switch the to local libraries so what I do in OSX Server App, I just switch them to use local library. The Users still authenticate thow LDAP/OD Server from OSX, so everybody has his personal login.

And now what I would like is:
After the User logs in, it should mount the personal networkhome automatic, without selecting it.
(With profilemanager or a profile I can't set any variables like $USER or %short_name% so this is the first issue.

Now if we get the above problem solved I would like to have the user homedirectory (which is located on the server) mounted to the Finder, so that it is easier for the students to save files from word for example.. if that works with the symlink that's even a better solution or let's say magic solution :D

thanks for your help really nice of you.
cheers Christian

chrisx
New Contributor

I just tested the mysides, that works really good.. so then I only have to solve the problem.. with mounting the user homedirectory, which is located on the server without selecting it at login.... would you run the script with launchagent?

psmac
New Contributor III

No problem at all, hope I can help!

I'm guessing you don't run Casper? If you don't, then you'll need to look at LoginHooks. You need to make a shell script and place it somewhere out of the way on the clients system & make sure to set the script to be executable;

sudo chmod u+x /path/to/your/script.sh

Two things about loginhooks;

  1. They run as root
  2. The $1 variable is the username that's logging in

Firstly get the mounting working, so add something like this to your script;

#!/bin/bash

sudo -u $1 osascript -e "try" -e "mount volume "afp://your.server.fqdn/Home Share/$1"" -e "end try"

Try this out and report back!

Paul

psmac
New Contributor III

Launch Daemons are the best way as LoginHooks have been depreciated for a while now, but LoginHooks are a little easier to explain.

Let me know how it goes.

Paul

chrisx
New Contributor

wow, thanks for the quick response, we use loginhook for other scripts.

I will try it out tmr in office and let u know.

Thanks for the speedy reply.
Very kind of you.

chrisx
New Contributor

I tried it.. the problem is if I do /usr/local/bin/mysides add Documents file:///Volumes/$user/Documents
The $USER is not recognized...

If I do: file:///Volumes/"usernamevolume"/Documents of course it works...
it looks like it has problem with the variables... i mounted the uservolume manually

With: sudo -u $1 osascript -e "try" -e "mount volume "afp://your.server.fqdn/Home Share/$1"" -e "end try" (I edited afp://...)
I get unknown user...

any ideas?

psmac
New Contributor III

Hi Christian,

Are you testing this from a loginhook?

I would wrap everything in to one loginhook script that mounts the home and then does the mysides magic. That way you should always be able to refer to $1 as you users short name which

You could do the below - this gets the logged in user if not passed via the loginhook (good for testing)

#!/bin/bash

#Get the logged in user if not passed to the script already
if [ $1 == "" ]; then
    user=`ls -l /dev/console | cut -d " " -f 4`
else
    user=$1
fi

sudo -u $user osascript -e "try" -e "mount volume "smb://your.server.fqdn/Home Share/$user"" -e "end try"

/usr/local/bin/mysides add Documents file:///Volumes/$user/Documents
#add more etc

exit 0

Paul

chrisx
New Contributor

Hi Paul,

I'm using iHook, if I put the .sh File into the directory it will not Log me in.. something is causing problems.
If I delete the .sh file with your script I can login normaly.. something blocks.

psmac
New Contributor III

What happens if you run the script manually? Are any errors thrown out?

I presume you can mount the share manually through Go -> Connect to server?

chrisx
New Contributor

008:~ admin$ bash home.sh
home.sh: line 4: [: ==: unary operator expected
sudo: unknown user: osascript
Added sidebar item with name: Documents
008:~ admin$

if [ $1 == "" ]; then (Do I have to edit anything here?)

sudo: unknown user: osascript ( I guess this doesn't work because of the first problem...
because if I run for example: sudo -u admin osascript -e "try" -e "mount volume "afp://server.auen.lan/Home Share/$user"" -e "end try"

Cheers

I get prompted to put my password in

psmac
New Contributor III

Hi Christian,

Apologies - the $1 should be wrapped in quotes on line 4 otherwise it fails when the variable is empty. Updated script;

#!/bin/bash

#Get the logged in user if not passed to the script already
if [ "$1" == "" ]; then
    user=`ls -l /dev/console | cut -d " " -f 4`
else
    user=$1
fi

sudo -u $user osascript -e "try" -e "mount volume "smb://your.server.fqdn/Home Share/$user"" -e "end try"

/usr/local/bin/mysides add Documents file:///Volumes/$user/Documents
#add more etc

exit 0

Paul

chrisx
New Contributor

HI Paul,

I get it working on the local admin account with the bash script manually and it mounts everything automatic.
now i tried to doit on a normal user and I get the error: “You are not in the sudoers file

If I add the script in iHook it hangs because I guess the "normal" user is not allowed to run the command.

I added chmod +x plus chmod 777

any idea how to solve that problem :)? We are getting nearer ;-)

psmac
New Contributor III

Hi Christian,

I've never used iHook, so it may not run under the root context as LoginHooks do.

Try removing the

sudo -u $user

bit and try again?

chrisx
New Contributor

okay!

Manually trying the script with bash scriptname everything is working wonderful.
Now when I put it on Login Hook, it puts the Folders to the Finder, but it's not mounting the volume.. i tried to put it in as the last script but it didn't help.
I guess it's executing it to early.

How could we handle that, running the whole thing with an apple script?

something additional: Can I add an other line to the script that if a admin logs in it's not mounting anything?
if thats possible, what should I do.

or maybe there are other/better possibilities to run the .sh script instead of iHook

Thanks for your help. very very kind!

Cheers Christian

chrisx
New Contributor

all good! I made a LaunchAgent service with the plist file, everything works like a charm now!

Just would be cool if we could make this login for all users except: User: admin for example..

can we extend that script for that?

thanks and cheers Christian

psmac
New Contributor III

Hi Christian,

Excellent news!

We can skip admins, no problem. After the script works out who the user is, but before the mount line add;

exclude=("root" "admin" "ladmin")

#Check to see if user is in the exclude list, if so exit
for x in "${exclude[@]}"; do
    if [ "$x" == "$user" ]; then
        logger "$user is a local user. Exiting..."
        exit 0
    fi
done

Just amend the exclude array to any user you don't want to run this for.

Paul

chrisx
New Contributor

Okay, Will check that out. Thank you.

It looks like sometimes the script is still executing to early. Is there a option in LaunchAgent so that it loads the script after a few seconds later?

I tried doing sleep in the script it self, but doesn't seem to help, as we use iHook for some other things aswell.

Or would you recommend doit by automator or apple script or so?

Christian

chrisx
New Contributor

Hi Paul,

I've made an automator workflow and let it start when the User Logs in. That also works!

BUT: When I create a brand new User on the server which also has to creates his localhome for te first time on the Mac,
than the automator doesn't run. I've tried with sleep of 10 + 20seconds but it doesn't help. I can see the automator script in the start items on the User already the first time.. (i made a profile for that). Of course it works when I klick on the automator app, but I would like it all automatically :-)

But it's not running it...and because students always change their workstation I would need a solution for that..
any suggestions for this issue?

Thanks Paul
Cheers

chrisx
New Contributor

Correction!!!

I got it working now! the .plist file in LaunchAgent had a Permission Issue, i made 777 but it has to have 644!
Now everything is fine and also with brand new users it's working ;-)

thanks a lot u made my day :-)

psmac
New Contributor III

Awesome news!

chrisx
New Contributor

HI psmac

any idea to get this working:

I would like to exclude all accounts with this script from: dscl localhost -list /Local/Default/Users

i tried but can't gett it working.
many thanks for your help

psmac
New Contributor III

Hi Christian,

If you change your exclude line to the below it should work;

exclude=(`dscl localhost -list /Local/Default/Users`)

Let me know how you get on!

Paul

chrisx
New Contributor

Hey Man !!!!

I was very close with:

exclude=`dscl localhost -list /Local/Default/Users`

I forgot the ( )

Thanks!

I own you something! can I make a donation?

Joeborner
New Contributor II

you can also use the below to exclude system accounts. It's worth noting that if you have users who have usernames starting with an underscore this will exclude them too, but hopefully that won't affect too many people.

exclude=(`dscl localhost -list /Local/Default/Users | grep -v ^_`)

psmac
New Contributor III

No worries Christian, hope it helps mate.

Donations to the beer fund of your choice.