SMB Share mounting and which way is right for me.

dmitchell
Contributor

I have found many scripts here and on the internet but I am not having luck creating a policy to mount a network share. We have a basic drive that everyone has access to, I want to basically have a script that mounts this drive automatically for our Mac users. I want to start off here. Each department has their own network share and their own personal drive which I would also like to mount eventually but that seems a bit more complicated as access to those drives are based off of AD group membership.

Can someone throw me a script that will simply map a network share?

Currently I tried using

#!/bin/sh

protocol="$4" # This is the protocol to connect with (afp | smb)
    echo "Protocol: $4"
serverName="$5"   # This is the address of the server, e.g. my.fileserver.com
    echo "Server: $5"
shareName="$6"    # This is the name of the share to mount
    echo "Sharename: $6"

# Mount the drive 
    mount_script=`/usr/bin/osascript  > /dev/null << EOT
    tell application "Finder" 
    activate
    mount volume "$protocol://${serverName}/${shareName}"
    end tell
EOT`

exit 0

I set parameters 4,5 and 6 as follows
4 smb
5 myshare.myorg.edu
6 volume

I receive "48:67 execution error: Finder got an error: Some parameter wasn't understood. (-1715)"

1 ACCEPTED SOLUTION

Look
Valued Contributor III

Here is my current iteration for an AD environment.
It's intended to be run as a login or self service policy and scoping is done on the policy (we have an AD group for access to each share which is a pretty good group to use). You specify the share as the first parameter ($4).
It probably needs a bit of tweaking since 10.13 as it occassionally fails for some reason, probably a timing issue with Finder being ready.
Basically it, seperates out to seperate process, then waits until the Finder has loaded, then mounts the requested share as the logged in user.
Not specifying a share defaults to the SMB Home in AD.

#!/bin/bash
#2017 Version Samuel Look
#All care no responsibility
#Mounts the requested share if it doesn't already exist if left blank it will attempt to mount AD SMBhome
#Accepts shares in the form smb://server/share
#Intended to be run as a Login policy from Casper on AD bound machines only and has only been tested in this context.

##### Start seperate process #####
(

##### SUBROUTINES #####

Share_Path_Valid() {
if [[ -z "$Share_Path" ]]; then
Machine_Domain=$(dscl /Active Directory/ -read . SubNodes | awk '{print $2}')
Share_Path="$(dscl "/Active Directory/$Machine_Domain/All Domains" -read /Users/$Current_User SMBHome | awk '!/is not valid/' | sed -e 's/SMBHome: /smb:/g' -e 's/\///g')"
fi
if [[ "$Share_Path" ]]; then
logger "Sharemount:$Share_Name Path check PASS $Share_Path"
return 0
else
logger "Sharemount:$Share_Name Path check FAIL"
return 1
fi
}

#####

User_Ready() {
Loop_End=$((SECONDS + 60))
Current_User=$(stat -f%Su /dev/console | awk '!/root/')
while [[ -z "$Current_User" ]] && [[ $SECONDS -lt $Loop_End ]]; do
sleep 10
Current_User=$(stat -f%Su /dev/console | awk '!/root/')
done
if [[ "$Current_User" ]]; then
logger "Sharemount:$Share_Name User check PASS $Current_User"
return 0
else
logger "Sharemount:$Share_Name User check FAIL"
return 1
fi
}

#####

Finder_Ready() {
Loop_End=$((SECONDS + 60))
while [[ -z "$(ps -c -u $Current_User | awk /CoreServicesUIAgent/)" ]] && [[ $SECONDS -lt $Loop_End ]]; do
sleep 10
done
if [[ "$(ps -c -u $Current_User | awk /Finder/)" ]]; then
logger "Sharemount:$Share_Name Finder check PASS"
return 0
else
logger "Sharemount:$Share_Name Finder check FAIL"
return 1
fi
}

#####

Not_Mounted() {
if [[ -z "$(mount | awk '/'$Current_User'/ && //'$Share_Name' /')" ]]; then
logger "Sharemount:$Share_Name Mount check PASS $Share_Name"
return 0
else
logger "Sharemount:$Share_Name Mount check FAIL already mounted"
return 1
fi
}

#####

Mount_Drive() {
True_Path=$(echo $Share_Path | sed 's//////'$Current_User'@/g')
logger "Sharemount:$Share_Name Attempting to mount $True_Path"
sudo -u $Current_User osascript -e 'mount volume "'$True_Path'"'
}

##### START #####

Share_Path=$4
Share_Name="$(echo $Share_Path | awk -F"/" '{print $NF}')"

if User_Ready && Finder_Ready && Share_Path_Valid && Not_Mounted; then
sleep 4
Mount_Drive
else
logger "Sharemount:$Share_Name Conditions not met to attempt drive mounting $Share_Path"
fi

##### End seperate process #####
) &

##### FIN #####

View solution in original post

14 REPLIES 14

osxadmin
Contributor II
#!/bin/bash
#below this grabs the current login user and maps their "personal network drive/home folder"
###############################################
theuser=$(/usr/bin/who | awk '/console/{ print $1 }')
/usr/bin/osascript > /dev/null << EOT

        tell application "Finder" 
        activate
        mount volume "smb://servername/sharedrive/${theuser}/"
        end tell
###############################################

#below this it will map a network drive that is not specific to a user
#####################################################        
        tell application "Finder" 
        activate
        mount volume "smb://server/sharename/"
        end tell

EOT

echo $theuser
killall cfprefsd
defaults write com.apple.finder ShowMountedServersOnDesktop true
killall -HUP Finder

I forgot who gave me this script...but it wasn't me...hope it helps.

dmitchell
Contributor

@osxadmin Hmmm, so the script won't work for me being deployed in a policy and it also won't work if I execute it manually on a Mac however

#!/bin/sh

tell application "Finder" 
        activate
        mount volume "smb://server/sharename/"
        end tell

works fine executing from macOS but will not work via jamf policy. "You must specify a filesystem type with -t"

osxadmin
Contributor II

@dmitchell that script I post, it works in our enviroment, we use AD, we have JSS 9.96, I have a policy in Self Service so the end user can log into self service and click on the policy and that works for me.

Look
Valued Contributor III

Here is my current iteration for an AD environment.
It's intended to be run as a login or self service policy and scoping is done on the policy (we have an AD group for access to each share which is a pretty good group to use). You specify the share as the first parameter ($4).
It probably needs a bit of tweaking since 10.13 as it occassionally fails for some reason, probably a timing issue with Finder being ready.
Basically it, seperates out to seperate process, then waits until the Finder has loaded, then mounts the requested share as the logged in user.
Not specifying a share defaults to the SMB Home in AD.

#!/bin/bash
#2017 Version Samuel Look
#All care no responsibility
#Mounts the requested share if it doesn't already exist if left blank it will attempt to mount AD SMBhome
#Accepts shares in the form smb://server/share
#Intended to be run as a Login policy from Casper on AD bound machines only and has only been tested in this context.

##### Start seperate process #####
(

##### SUBROUTINES #####

Share_Path_Valid() {
if [[ -z "$Share_Path" ]]; then
Machine_Domain=$(dscl /Active Directory/ -read . SubNodes | awk '{print $2}')
Share_Path="$(dscl "/Active Directory/$Machine_Domain/All Domains" -read /Users/$Current_User SMBHome | awk '!/is not valid/' | sed -e 's/SMBHome: /smb:/g' -e 's/\///g')"
fi
if [[ "$Share_Path" ]]; then
logger "Sharemount:$Share_Name Path check PASS $Share_Path"
return 0
else
logger "Sharemount:$Share_Name Path check FAIL"
return 1
fi
}

#####

User_Ready() {
Loop_End=$((SECONDS + 60))
Current_User=$(stat -f%Su /dev/console | awk '!/root/')
while [[ -z "$Current_User" ]] && [[ $SECONDS -lt $Loop_End ]]; do
sleep 10
Current_User=$(stat -f%Su /dev/console | awk '!/root/')
done
if [[ "$Current_User" ]]; then
logger "Sharemount:$Share_Name User check PASS $Current_User"
return 0
else
logger "Sharemount:$Share_Name User check FAIL"
return 1
fi
}

#####

Finder_Ready() {
Loop_End=$((SECONDS + 60))
while [[ -z "$(ps -c -u $Current_User | awk /CoreServicesUIAgent/)" ]] && [[ $SECONDS -lt $Loop_End ]]; do
sleep 10
done
if [[ "$(ps -c -u $Current_User | awk /Finder/)" ]]; then
logger "Sharemount:$Share_Name Finder check PASS"
return 0
else
logger "Sharemount:$Share_Name Finder check FAIL"
return 1
fi
}

#####

Not_Mounted() {
if [[ -z "$(mount | awk '/'$Current_User'/ && //'$Share_Name' /')" ]]; then
logger "Sharemount:$Share_Name Mount check PASS $Share_Name"
return 0
else
logger "Sharemount:$Share_Name Mount check FAIL already mounted"
return 1
fi
}

#####

Mount_Drive() {
True_Path=$(echo $Share_Path | sed 's//////'$Current_User'@/g')
logger "Sharemount:$Share_Name Attempting to mount $True_Path"
sudo -u $Current_User osascript -e 'mount volume "'$True_Path'"'
}

##### START #####

Share_Path=$4
Share_Name="$(echo $Share_Path | awk -F"/" '{print $NF}')"

if User_Ready && Finder_Ready && Share_Path_Valid && Not_Mounted; then
sleep 4
Mount_Drive
else
logger "Sharemount:$Share_Name Conditions not met to attempt drive mounting $Share_Path"
fi

##### End seperate process #####
) &

##### FIN #####

dmitchell
Contributor

@Look Thanks! This worked perfectly!

neilmartin83
Contributor II

If you're in an AD environment, check out NoMAD - it can handle shares really well (and if your Macs are bound it'll sign in at login/launch with the kerb ticket and do it automagically).

https://nomad.menu/help-center/shares-menu/

jartron3030
New Contributor II

I am having my own issues that are slightly different than OP's and hope that someone else who comes upon this thread might be able to give me some advice...

I am using a variation of the script that the OP @dmitchell initially describes, a modification that was made by @ShaunRMiller83 on a thread from 2015:

#!/bin/sh

UID1=$(id -u $3)
    echo "UID: $UID1"
protocol="$4" # This is the protocol to connect with (afp | smb)
    echo "Protocol: $4"
serverName="$5"   # This is the address of the server, e.g. my.fileserver.com
    echo "Server: $5"
shareName="$6"    # This is the name of the share to mount
    echo "Sharename: $6"

if [[ "$UID1" -ge 1000 ]]; 
    then echo "User "$3" is an Active Directory account"
      # Mount the drive 
        mount_script=`/usr/bin/osascript  > /dev/null << EOT
        tell application "Finder"
        mount volume "$protocol://${serverName}/${shareName}/$3/"
        end tell
EOT`
    else 
        echo "Logged in user is a local user"
fi
exit

Our staff machines are bound to our domain and our users are logging in with their AD user accounts. I am trying to mount the logged in AD user's specific network share, which is not SMBhome; the script DOES mount the correct share, as I defined in JSS by parameters $4, $5, and $6, however when the user tries to open their share they receive a Finder error that reads:

“The folder [AD username] can’t be opened because you don’t have permission to see its contents.”

I don’t know what I am missing to cause this error, as the user’s credentials MUST be correct in order to authenticate against the domain and allow login, but for some reason it’s not passing the credentials in order to allow the user to open the share. I am confused as to how/why the share is even able to seemingly mount at all if the permissions are being read as being incorrect.

I also tried to use @Look’s script, in which I defined parameter $4 in JSS as “smb://server/users/“; this also DOES mount the share that encompasses the user shares, “smb://server/users/“ and also allows the currently logged in user to access and browse the share’s contents which consists of a list of other user shares… this means that the only way that they would be able to get into their own share is to browse, find and drill down into theirs, but I can’t figure out how to use that script to mount the user’s specific share, “smb://server/users/user/“… I tried defining parameter $4 in JSS as both “smb://server/users/$Current_User/“ and “smb://server/users/$3/“, but both returned Finder errors that the network location does not exist…

Any thoughts on how I can modify either script to make it possible to auto-mount an AD user’s specific user share?

Thanks in advance!

ShaunRMiller83
Contributor III

@jartron3030

I posted this a while ago so bare with me.

I would start with two test to narrow down where the issue may be coming from.

1 - What happens when you mount the volume manually?
2- What happens if you replace the variables with actual values and run the script locally?

I have to look through my script library. I think I had another script that superseded this. That I can post when I get in front of a computer.

jartron3030
New Contributor II

Thank you for the prompt reply @ShaunRMiller83 !

I went through the two suggested tests and the results are as follows:

1 - What happens when you mount the volume manually?

It works just fine... immediately mounts the share and allows me to open and view the contents.

2- What happens if you replace the variables with actual values and run the script locally?

It worked! It mounted the drive without asking for my credentials, which makes sense to me since I am already logged in and authenticated with my AD account, and when I double-clicked the share it actually loaded it and displayed its contents. I will say, as an aside, that for this test I removed the parts of the script that define the variables and only included the "Mount the drive" section so that it looks like this:

#!/bin/sh

# Mount the drive 
    mount_script=`/usr/bin/osascript  > /dev/null << EOT
    tell application "Finder"
    mount volume "smb://SERVER.FQDN/USER-SHARE/AD-USER/"
    end tell
EOT`

exit

(filling in for my organization's specific server/share and my AD username)

The only thing that I did differently besides modifying the script is make it executable so that I could run it in Terminal.

ShaunRMiller83
Contributor III

@jartron3030

This was the script I was using. I don't have access to a JSS or AD environment to test it out right now.

#!/bin/sh

currentUser=$(ls -l /dev/console | awk '{ print $3 }')
    echo "Current User: $currentUser"
UID1=$(id -u $currentUser)
    echo "UID: $UID1"
protocol="$4" # This is the protocol to connect with (afp | smb)
    echo "Protocol: $4"
serverName="$5"   # This is the address of the server, e.g. my.fileserver.com
    echo "Server: $5"
shareName="$6"    # This is the name of the share to mount
    echo "Sharename: $6"

if [[ "$UID1" -lt 1000 ]]; then
     echo "$currentUser is a local user. This script will now quit"
     exit 0
fi

if [[ "$UID1" -ge 1000 ]]; then 
    echo "User $currentUser is an Active Directory account"
    # Mount the drive
        mount_script=`/usr/bin/osascript <<EOF
        tell application "Finder" 
        activate
        mount volume "$protocol://${serverName}/${shareName}/"
        end tell
        EOF`
fi

jartron3030
New Contributor II

@ShaunRMiller83

Sorry for the late follow-up, I've been out of the office. I implemented this version of the script and am still getting the Finder error that I initially described on my first post on 12/7. It's a very strange issue, because I can authenticate against the domain and login with my AD credentials, and I can manually connect to the network share that I am intending on connecting to, but for some reason this script only appears to mount the drive, as it does appear on the desktop and in a Finder window, but still doesn't seem to authenticate the credentials. I will continue to tweak and troubleshoot and report back with any new information. Thank you for your efforts!

Mudalige
New Contributor III

Hi All, I'm very new to MAC and we bought a jamf pro cloud license for our school. Currently not using LDAP as this is on cloud based and in near future I will be implementing Jamf Infrastructure Manager on DMZ to sync our on premise AD through JIM. Devices are already enrolled in JAMF and Bound to AD as well. I would like to mount our network AD student home drives to the devices when student log in. I have tried to map these using configuration policies. However, it seems to be nothing is mapping at the moment. would anyone be able guide me with how to set this up ? Thanks in advance.

a_stonham
Contributor II

@Mudalige Look at using NoMAD or Jamf Connect Shares. That's probably the easiest and most reliable way I have found to handle network shares.

Mudalige
New Contributor III

@a.stonham Sure thing. Thank you. Would you able to explain me how to setup either NoMAD or Jamf Connect ? Please