Enabling Location Services Programmatically via Casper

bthomas
New Contributor II

I am trying to enable Location Services for 10.10 systems via Casper but I cannot find any option with configuration profiles to enable it and the few scripts I have found online do not seem to enable location services.

Specifically I am trying to enable location services to allow for OS X to update the timezone based on the location of the system.

Below is one of the failed scripts I had attempted. https://www.afp548.com/2013/07/30/enabling-location-services-programmatically/

1 ACCEPTED SOLUTION

jhbush
Valued Contributor II

@bthomas this has been working for me. I'm not sure where I picked it up from.

#!/bin/sh

launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist
uuid=`/usr/sbin/system_profiler SPHardwareDataType | grep "Hardware UUID" | cut -c22-57`
defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.$uuid LocationServicesEnabled -int 1
chown -R _locationd:_locationd /var/db/locationd
launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

exit 0

View solution in original post

35 REPLIES 35

cwaldrip
Valued Contributor

There's this discussion from Oct '11 on disabling. I'd think it'd be a simple change to Enable. But I can't get it to work (change Disabled to false to enable is how I understand it).

RobertHammen
Valued Contributor II

Here's what I do, which seemed to work. Stole this from someone.

launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist
uuid=tick/usr/sbin/system_profiler SPHardwareDataType | grep "Hardware UUID" | cut -c22-57tick
defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.$uuid LocationServicesEnabled -int 1
chown -R _locationd:_locationd /var/db/locationd
launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

exit 0

replace tick with the tick mark from the tilde key (upper left corner on a US keyboard, JAMF Nation interprets this somehow, @jake can this behavior be fixed or changed?

nessts
Valued Contributor II

@RobertHammen I would think if you put it in the quoted text and escape the tick ` it might have worked

uuid=`system_profiler SPHardwareDataType | grep "Hardware UUID" | cut -c22-57`

or apparently you have to escape the ticks to get them to show up in both just `

jhbush
Valued Contributor II

@bthomas this has been working for me. I'm not sure where I picked it up from.

#!/bin/sh

launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist
uuid=`/usr/sbin/system_profiler SPHardwareDataType | grep "Hardware UUID" | cut -c22-57`
defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.$uuid LocationServicesEnabled -int 1
chown -R _locationd:_locationd /var/db/locationd
launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

exit 0

View solution in original post

bthomas
New Contributor II

Thank you all for the quick responses however I cannot get the script to enable location services via a policy which calls the the script. I manually ran the on a test system and I believe the problem comes in with the uuid= line because this is the output of grep and cut. I believe the last line is the intended output but I am not that great with scripting to know how to clean up the output.

2015-03-13 19:36:58.810 system_profiler[511:11331] platformPluginDictionary: Can't get X86PlatformPlugin, return value 0 2015-03-13 19:36:58.813 system_profiler[511:11331] platformPluginDictionary: Can't get X86PlatformPlugin, return value 0 564DFCEF-B4E6-7B6A-BE36-42ACC85B9ED0

jhbush
Valued Contributor II

@bthomas I just tested this out again and location services activated as expected. By chance are you running an older version of 10.9?

bthomas
New Contributor II

@jhbush1973 I am running 10.10.2 on my test systems. Production systems are the same OS version. The OS is built using AutoDMG from the 10.10.2 installer downloaded from the Mac App Store.

Kumarasinghe
Valued Contributor

Try this script with an additional line inserted;

#!/bin/sh

# enable location services
/bin/launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist
uuid=$(/usr/sbin/system_profiler SPHardwareDataType | grep "Hardware UUID" | cut -c22-57)
/usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd."$uuid" LocationServicesEnabled -int 1
/usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.notbackedup."$uuid" LocationServicesEnabled -int 1
/usr/sbin/chown -R _locationd:_locationd /var/db/locationd
/bin/launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

exit 0

bthomas
New Contributor II

@jhbush1973 Your script did work for me. I found that it didn't work on my VM due to some weirdness with the hardware ID. I can now enable location services on 10.10.2. Thanks for everyones help!

bbeaudre
New Contributor

This does not turn location services on a 10.11 machine. Anyone try the above command on Elcapitan?

bpavlov
Honored Contributor

Works for me. This is the script I use which is meant to use Casper variables which you need to populate.

#!/bin/sh

#Use "/usr/sbin/systemsetup -listtimezones" to see a list of available list time zones.
#This script is meant to be used with Casper.
# $4 variable should be filled with the TimeZone information (ie: America/Chicago, America/New_York )
# $5 variable should be filled with the TimeServer information (ie: time.apple.com )
TimeZone="$4"
TimeServer="$5"

############# Pause for network services #############
/bin/sleep 10
######################################################

#Disable network time
/usr/sbin/systemsetup -setusingnetworktime off

#Set an initial time zone
/usr/sbin/systemsetup -settimezone "$TimeZone"

#Set specific time server
/usr/sbin/systemsetup -setnetworktimeserver "$TimeServer"

# enable location services
/bin/launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist
uuid=`ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}'`

/usr/bin/defaults write /private/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd."$uuid" LocationServicesEnabled -int 1
/usr/bin/defaults write /private/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.notbackedup."$uuid" LocationServicesEnabled -int 1
/usr/sbin/chown -R _locationd:_locationd /var/db/locationd
/bin/launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

# set time zone automatically using current location
/usr/bin/defaults write /Library/Preferences/com.apple.timezone.auto Active -bool true

#Re-enable network time
/usr/sbin/systemsetup -setusingnetworktime on

#Detect the timezone
/usr/sbin/systemsetup -gettimezone

#Get the time from time server
/usr/sbin/systemsetup -getnetworktimeserver

exit 0

dvasquez
Contributor II

@bpavlov your script works well.

Thank you for sharing. I was concerned about the enable locations services portion and "ioreg" command to get the system uuid but I get why your doing it, very cool.

I can say this works in 10.11.6

Thank you

russeller
Contributor III

This seemed like the right place to put this. Been testing my 10.12 first boot script and found that defaults will put the UUID of a ByHost preference in the plist name itself now in 10.12. The original script will actually write the UUID to the plist twice (once by defaults and once by the uuid string) when ran. I removed the uuid stuff from the above script and it works for me. Here is an updated version for 10.12:

#!/bin/bash

## Unload locationd
launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist

## Write enabled value to locationd plist
defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -int 1

## Fix Permissions for the locationd folder
chown -R _locationd:_locationd /var/db/locationd

## Reload locationd
launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

exit 0

Hope this helps and please let me know if there is improvement needed.

JustDeWon
Contributor III

@ssrussell thanks for this.. I will give it a twirl..

cgiordano
Contributor

@ssrussell I've combined the lengthier script above with your script and I'm not having much luck. I'm in Seattle but as a test I'm setting the initial time zone as "America/New_York" and setting the timer server as "time.apple.com," however even after everything gets reloaded it won't update the time zone to be Seattle or Cupertino or any city in the Pacific time zone.

For clarity's sake, here's the script that I'm trying:

#!/bin/sh

#Use "/usr/sbin/systemsetup -listtimezones" to see a list of available list time zones.
#This script is meant to be used with Casper.
# $4 variable should be filled with the TimeZone information (ie: America/Chicago, America/New_York )
# $5 variable should be filled with the TimeServer information (ie: time.apple.com )
TimeZone="America/New_York"
TimeServer="time.apple.com"

############# Pause for network services #############
/bin/sleep 10
######################################################

#Disable network time
/usr/sbin/systemsetup -setusingnetworktime off

#Set an initial time zone
/usr/sbin/systemsetup -settimezone "$TimeZone"

#Set specific time server
/usr/sbin/systemsetup -setnetworktimeserver "$TimeServer"

## Unload locationd
launchctl unload /System/Library/LaunchDaemons/com.apple.locationd.plist

## Write enabled value to locationd plist
defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -int 1

## Fix Permissions for the locationd folder
chown -R _locationd:_locationd /var/db/locationd

## Reload locationd
launchctl load /System/Library/LaunchDaemons/com.apple.locationd.plist

# set time zone automatically using current location
/usr/bin/defaults write /Library/Preferences/com.apple.timezone.auto Active -bool true

#Re-enable network time
/usr/sbin/systemsetup -setusingnetworktime on

#Detect the timezone
/usr/sbin/systemsetup -gettimezone

#Get the time from time server
/usr/sbin/systemsetup -getnetworktimeserver

The output I'm getting is:

setUsingNetworkTime: Off Set TimeZone: America/New_York setNetworkTimeServer: time.apple.com setUsingNetworkTime: On Time Zone: America/New_York Network Time Server: time.apple.com

Any suggestions?

russeller
Contributor III

@cgiordano When you mentioned setting the Time Zone to Seattle or Cupertino are you talking about setting the TimeZone variable to something like: America/Seattle if so, I found that from this command sudo systemsetup -listtimezones which this link has the list, it doesn't have Seattle or Cupertino as options. Your only option is America/Los_Angeles. Using New York and LA worked for me when I used your script and switched them back and forth. I hope I understood your question correctly, but as far as I can tell your script works perfectly.

EDIT: words are hard

cgiordano
Contributor

@ssrussell Maybe I'm misunderstanding the purpose of the script but at the end of the script should it be automatically setting the location? If so, it's not doing that for me. It's leaving the TimeZone set to NY. I thought it was supposed to set the time zone automatically...

russeller
Contributor III

@cgiordano I'm sorry, the purpose was basically to click the "Enable Location Services" checkbox under "Security & Privacy" PrefPane. This makes it to where when the user launches an app like Maps.app it'll prompt them to allow Maps to use Location Services (which doesn't require admin rights). If that checkbox isn't checked then it requires admin rights to check it from that "Security & Privacy" PrefPane. This could lead to frustrated non-admin users.

28f8ce9ecc8040f99614b66ad5823f6e

I'm not sure how to check this box, this is what you want:

85c3aeb9cb7c432493a4f9cac3c70369

cgiordano
Contributor

Yup...I got it now. I guess I was getting confused by the other scripts in this post. I'm not sure the point setting a time zone if we're automatically going to set it via enabling "Set time zone automatically using current location" with the command:

/usr/bin/defaults write /Library/Preferences/com.apple.timezone.auto Active -bool true

Thanks for the assistance and the clarity.

chad_fox
Contributor II

@ssrussell thank you for sharing! Works great in Sierra.

jonesju
New Contributor II

@ssrussell Thanks! That script worked for me as well! 10.12

ammonsc
Contributor II

@ssrussell Thanks for the script that is perfect. Do you know if there is a way to enable all items in the Location Services to be turned on?

btrabue
New Contributor

Wondering the same thing that ssrussell is. Is this possible, because I am not seeing that the apps can be enabled within location services with a non-admin.

russeller
Contributor III

@ammonsc @btrabue I'm not sure about how to enable all the items in Location Services programmatically. I'll continue to test and let you know what I find.

bearzooka
Contributor

@ssrussell Thanks for the Sierra update of this script.

Nevertheless, when I try to run it directly into the Terminal I get an error saying something like "operation not permitted while system integrity protection is engaged". Do you know if this is something I might be doing wrong or a configuration that I need to change in order to integrate this into a larger script?

Thanks!

russeller
Contributor III

@bearzooka You're getting that error because the script is trying to unload that System Daemon. I'm not sure if that is a 10.12.4 thing. I was originally running this outside a user session over the loginwindow, but if it is a SIP thing, it shouldn't matter where it is being run from. You can still run the defaults write command, it just may not be applied until a reboot occurs. I'll test this and let you know what I find.

gda
New Contributor III

Because I have to work on fixing time zone settings too I found an easy way to enable location services.

I just ran this command in a root shell to enable the location services without a reboot.

sudo -u _locationd defaults write -currentHost com.apple.locationd LocationServicesEnabled -int 1

And this command to disable location services:

sudo -u _locationd defaults write -currentHost com.apple.locationd LocationServicesEnabled -int 0

brunerd
Contributor

@gda Thanks for those commands, real slick! Using sudo to run as locationd and using -currentHost so folks don't need to fiddle with UUIDs or file ownership issues. Looking at a lot of the code out there, mine included, I can't believe I haven't grasped currentHost before this! Although I've found defaults in 10.12+ will automatically append the UUID when you write to a ByHost path... anyway the currentHost option needs to be declared immediately after the command and before the "action verb":

Enabling Location Services:

sudo -u _locationd defaults -currentHost write com.apple.locationd LocationServicesEnabled -int 1

Disabling Location Services:

sudo -u _locationd defaults -currentHost write com.apple.locationd LocationServicesEnabled -int 0

Note: This still works in 10.14

Update: I misspoke, things are actually quite messed up in 10.14.0

sshort
Valued Contributor

This works for me in High Sierra + Mojave

/usr/bin/defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -int 1

csa
New Contributor III

@sshort Please share how you got this to work in High Sierra and Mojave. Location services are now protected by SIP I get the following error:
2018-10-27 18:51:44.864 defaults[7230:223088] Could not write domain /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd; exiting

brunerd
Contributor

Just to update, my above post...
Writing to the plist as locationd does not work in in Mojave (sorry too many test laptops
Despite the file being owned by
locationd:_ locationd you indeed get the "Could not write domain" error

What's more and worse is that despite this it will allow you to write to the plist as root:

bash-3.2# ls -l /private/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd* -rw------- 1 root wheel 148 Oct 30 10:11 /private/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.57B6A0CC-1731-5A1B-A795-004AD89C0060.plist -rw------- 1 root wheel 74 Oct 30 10:12 /private/var/db/locationd/Library/Preferences/ByHost/com.apple.locationd.notbackedup.57B6A0CC-1731-5A1B-A795-004AD89C0060.plist

The really really bad downside to this is that if you unlock the Privacy Preference pane and check "Enable Location Service" it is unable to write those changes to disk! Despite checking and unchecking those plists don't budge, and if you leave it checked and reboot, you'll find it unchecked when it comes back up. Even if you write 1 as the value, because of the file mode, locationd can't read the plist and the only way to fix the permissions is to reboot in Recovery, where you can change ownership back to locationd

Yeah... I hope they fix this in 10.14.1 prolly too late for a bug report... of course, this is just Apple forcing their hand to let users run as admins, which I am all for, treat adults like adults... of course Macs are in education and everyone being an admin is not always ideal. Having Date/Time and Location prefs in MDM would be the ideal way to manage this

mchit
New Contributor II

Although the command stated by @sshort did enable Location Service for Mojave and High Sierra, it was not enabling it for the specific apps. Is there a way around to enable location services for a specific app like Safari etc since loading and unloading of locationd.plist is prevented by SIP ? Thanks.

gda
New Contributor III

@brunerd thanks for the fix. 😉

I tested again on 10.14.1 and it worked fine for me.
Location services got enabled on my client & test client as soon as I ran the command:

sudo -u _locationd defaults -currentHost write com.apple.locationd LocationServicesEnabled -int 1

nstrauss
Contributor II

Appears Apple cut off the above solutions in Mojave. This defaults command works for me on 10.4.1 as of today...

sudo defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -int 1

csa
New Contributor III

FYI - confirmed that @nstrauss solution works on 10.14.0, 10.14.1 and 10.14.2. Thank you so much, we have been trying to this working for a while.