Mapping Network Drive Via Script

joemamasmac
New Contributor III

Hello All,

We have been working on a way to map network drives for our users. I have looked at the examples that were posted on the MacMule site and tried to use that as a template for our environment. Unfortunately we ran into some issues right off the bat, such as AD not properly showing group memberships.

We decided to bypass this and attempt to put some logic into our own script so it would map users drives based on the logged in user. Depending on the first letter of your username, depends on which data volume you are on. Then there is a folder for the first letter of your username, and in there is your personal network storage. The other problem was mapping shared drives, but this seems to be working ok as these folders all reside on the same volume.

My problem is, the script works fine when being run from self service, but not if I assign it as a login hook. I am trying to figure out how I can get this to run at login, and a way (other than self service) to get this to operate whenever the user needs to remount their drives. After sleep, if connecting in via VPN, etc.

What would you recommend, and does anyone have any suggestions on my script? Thanks for any suggestions.

Joe

#!/bin/sh

echo "$USER = $USER"

checkGroupMembership() {
    #if dsmemberutil checkmembership -U $USER -G $group | grep -iq "user is a member of the group"; then
    if [[ $(dsmemberutil checkmembership -U "$USER" -G "$1") =~ "is a member" ]]; then
        return 0
    else
        return 1
    fi
}

# Group for personal storage for nonperson accounts
#group="storage-data-GENERIC-mapdrive"
# Group for personal storage for person accounts
#group="storage-data-${USER:0:1}-mapdrive"

# Mount Personal storage (G:) for person accounts
# XXX: Handle mounting Personal storage (G:) for nonperson accounts from smb://storage3.mydomain.com/DATA3/GENERIC/${USER}
case ${USER:0:1} in
    [a-gA-G]*)
        echo "DATA1 (a-gA-G) case reached"        
        # open "smb://storage1.mydomain.com/DATA1/${USER:0:1}/${USER}"
        #if checkGroupMembership "storage-data-${USER:0:1}-mapdrive"; then
            osascript -e "try" -e "mount volume "smb://storage1.mydomain.com/DATA1/${USER:0:1}/${USER}"" -e "on error" -e "end try"
        #else
        #   echo "User "$USER" is not a member of Group "storage-data-${USER:0:1}-mapdrive""
        #fi
        ;;
    [h-mH-M]*)
        echo "DATA2 (h-mH-M) case reached"
        # open "smb://storage1.mydomain.com/DATA2/${USER:0:1}/${USER}"
        osascript -e "try" -e "mount volume "smb://storage1.mydomain.com/DATA2/${USER:0:1}/${USER}"" -e "on error" -e "end try"
        ;;
    [n-sN-S]*)
        echo "DATA3 (n-sN-S) case reached"
        # open "smb://storage1.mydomain.com/DATA3/${USER:0:1}/${USER}"
        osascript -e "try" -e "mount volume "smb://storage1.mydomain.com/DATA3/${USER:0:1}/${USER}"" -e "on error" -e "end try"
        ;;
    [t-zT-Z]*)
        echo "DATA4 (t-zT-Z) case reached"
        # open "smb://storage1.mydomain.com/DATA4/${USER:0:1}/${USER}"
        osascript -e "try" -e "mount volume "smb://storage1.mydomain.com/DATA4/${USER:0:1}/${USER}"" -e "on error" -e "end try"
        ;;
    *)
        echo "Default case reached"
        ;;
esac

# Mount Shared storage (T:) for all accounts
echo "SHARED case reached"
# open "smb://storage1.mydomain.com/DATA4/${USER:0:1}/${USER}"
osascript -e "try" -e "mount volume "smb://sharepoint.mydomain.com/SHARED"" -e "on error" -e "end try"

exit 0
5 REPLIES 5

Look
Valued Contributor III

You will probably find $USER is still root when it runs at a guess.
You might be able to get round it by finding the front user with something like.
ls -l /dev/console | /usr/bin/cut -d " " -f 4
The problem I had from the login hook was getting the mounts to connect automatically using Kerberos as the user logged in as the script was running as root.

I scripted mounting the drives as well.
Implemented it as a LaunchAgent that called the script (this will make it run as the user) and deployed both as a dmg from Casper.
The other thing I did that is proving useful is have it read the shares to be mounted form a file that is stored on a read only location on the network (basically contains entries along the lines of sharename, grouptocheck, sharetype, sharepath).
The script mounts this location invisibly, reads the config, then mounts the appropriate shares that match the groups for the user.

joemamasmac
New Contributor III

Thanks for the info Sam. Any chance you might be able to share your script with me so I could see how you are doing this?

Joe

Kaltsas
Contributor III

I use a combination of a LaunchAgent and an Applescript to mount network shares. If you email me at alexander-kaltsas at uiowa dot edu I can provide you more information.

It's built off information from MacMule with some logic for our environment. Mostly I'm busy to strip out our internal stuff right now and email will remind me.

Look
Valued Contributor III

The script, removed a few specifics for our organisation, it probably needs tweaking for use anywhere else, but feel free to steal/borrow and otherwise use any pieces that are useful to you, It's been a veeeeery long time since I was scripting anything (almost 20 years...) so my code will have to be excused somewhat 🙂
It mounts an invisible share //COMPANY/netlogon/osx
Reads a txt files that has the lines of info about the shares.
Mounts them to a folder hidden inside the users library to prevent other users seeing them
Makes a link to this inside there main user directory to allow browsing to it from save dialogues etc...

#Cobbled together from bits of the internet by Sam Look 2014
#Intended to be run from a LaunchAgent
#Reads ShareFile and mounts the shares listed, also attempts to mount AD home drive
#Currently configured for Kerberos enabled environments, you may need to remove the argument on the if statement if it does not appear to work

##### Global Variables #####
LongDomain=COMPANYDOMAIN.COMPANY.COM
ShortDomain=echo $LongDomain | cut -d"." -f1

ShareFile="/Volumes/netlogon/OSX/ShareList.txt"
#Text file containing one share per line Share-Name,ADGroup-To-Check,File-Type,Share-Path
#Path can contain %USERNAME% which will substitute

##### Functions #####

MountShare(){
#Mounts the requested share if it doesn't already exist, variables are: Share, Type, Path
RunCount=0
Limit=3
MSShare=$1
MSType=$2
MSPath=echo $3 | sed "s//////$USER@/g"
#Ensures mount as current user
while [[ "mount | grep -c "$USER.$MSShare "" -eq "0" ]] && [[ $RunCount -lt $Limit ]] ; do
let RunCount=$RunCount+1
echo "Attempt $RunCount to mount $MSShare"
mkdir /Users/$USER/Library/ShareMounts/$MSShare 2> /dev/null
mount -t $MSType "$MSPath" /Users/$USER/Library/ShareMounts/$MSShare
if [[ "mount | grep -c "$USER.
$MSShare "" -eq "0" ]] ; then
sleep 5
fi
done
if [[ "mount | grep -c "$USER.*$MSShare "" -lt "1" ]]; then
echo "$MSShare mount FAILURE"
else
echo "$MSShare mount SUCCESS"
fi
}

##### Main start #####

#Gather the relevant info
FrontUser=ls -l /dev/console | awk '{ print $3 }'
Ugroup=dscacheutil -q user -a name $USER |grep gid:
ADgroup=dscacheutil -q group -a name "Domain Users"|grep gid:

#Proceed if user is front and is a network user and has a valid Kerberos ticket
if [[ "$USER" -eq "$FrontUser" ]] && [[ "$Ugroup" == "$ADgroup" ]] && [[ "klist | grep -c "krbtgt/$LongDomain@$LongDomain"" -gt "0" ]] ; then ADHome=dscl "/Active Directory/$ShortDomain/All Domains" -read /Users/$USER | grep SMBHome: | cut -c 10- | sed 's/\///g' | sed 's///stf1///stf1.autuni.aut.ac.nz/g' | sed 's///stf2///stf2.autuni.aut.ac.nz/g' | sed 's///stu///stu.autuni.aut.ac.nz/g' ADGroups=dscl "/Active Directory/$ShortDomain/All Domains" -read /Users/$USER | awk '/dsAttrTypeNative:memberOf:/,/dsAttrTypeNative:msExchArchiveDatabaseLink:/ { print }' echo " "

#Make shares visible on desktop
if [[ 'defaults read com.apple.finder ShowMountedServersOnDesktop' != "1" ]]; then
defaults write com.apple.finder ShowMountedServersOnDesktop -bool true
fi

#Prepare for mounting shares mkdir /Volumes/netlogon 2> /dev/null mount -o nobrowse -t smbfs //$USER@$ShortDomain/netlogon /Volumes/netlogon 2> /dev/null mkdir ~/Library/ShareMounts 2> /dev/null

#Mount nwhome share if [[ $ADHome != "" ]]; then echo "#START HOME DRIVE" echo " " MountShare "echo $USER" "smbfs" "echo $ADHome" else echo "$USER mount NO ATTEMPT" fi echo " "

#Mount additional shares listed in ShareFile exec 4<$ShareFile while read -u4 ShareLine ; do if [[ "echo $ShareLine | grep -c #" -gt "0" ]]; then echo $ShareLine elif [[ $ADGroups =~ "echo $ShareLine | cut -f2 -d","" ]]; then ShareLine=echo "$ShareLine" | sed "s/%USERNAME%/$USER/g" MountShare "echo $ShareLine | cut -f1 -d","" "echo $ShareLine | cut -f3 -d","" "echo $ShareLine | cut -f4 -d","" else echo "echo $ShareLine | cut -f1 -d"," mount NO ATTEMPT" fi echo " " done
else echo "Invalid user or Kerberos"
fi

#Clear out any old or failed folders
ls -1 /Users/$USER/Library/ShareMounts/ 2> /dev/null | while read OldFolder do
if [[ "mount | grep -c "$USER.*$OldFolder "" -eq "0" ]]; then if [ -z "ls "/Users/$USER/Library/ShareMounts/$OldFolder/"" ]; then echo "Removing old or failed folder $OldFolder" echo " " rmdir "/Users/$USER/Library/ShareMounts/$OldFolder" fi
fi
done
umount -f /Volumes/netlogon 2> /dev/null

#Sort out the shortcut
if [[ "ls /Users/$USER/Library/ShareMounts/ | wc -w" -gt "0" ]] && [[ ! -d "/Users/$USER/My Network Shares" ]] ; then
ln -s /Users/$USER/Library/ShareMounts/ /Users/$USER/My Network Shares
elif [[ "ls /Users/$USER/My Network Shares 2> /dev/null | wc -w" -eq "0" ]]; then
rm /Users/$USER/My Network Shares 2> /dev/null
fi

##### Main end #####

bentoms
Honored Contributor III
Honored Contributor III

As an alternative option, we use an AppleScript app that runs via a LaunchAgent & maps the drives as the user.

No messing with mount_smbfs etc.. And as it's running as he user it will use their Kerberos ticket: https://macmule.com/2011/09/08/how-to-map-drives-printers-based-on-ad-group-membership-on-osx/