This guide will teach you how to set the time zone in macOS using shell scripting. Accurate system time is critical for IT professionals and Managed Service Providers (MSPs). Whether it’s ensuring proper authentication, synchronizing logs, or maintaining compliance with regulatory requirements, time synchronization is the backbone of reliable IT infrastructure.
On macOS devices, managing time zones and synchronization settings can be tedious if done manually across large fleets. That’s where shell scripting comes into play. This blog post explores a shell script that automates time zone and synchronization management for macOS, providing IT teams with a scalable and reliable solution.
Background
Time configuration might appear to be a minor system setting, but it has far-reaching implications. Incorrect time zones can lead to issues with Kerberos authentication, misaligned logs, and broken scheduling services. For MSPs managing hundreds of endpoints, manual intervention is inefficient and error-prone. The provided shell script simplifies these tasks by automating:
- Listing available time zones
- Setting a specific time zone
- Enabling or disabling automatic time zone detection
- Configuring a custom network time synchronization server
- Forcing an immediate time sync
This makes it a versatile tool for IT professionals who need consistency across environments.
The Script
#!/usr/bin/env bash
#
# Description: This script sets the time zone and synchronization settings for macOS.
# By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
# Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms.
# Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party.
# Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider.
# Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations.
# Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks.
# Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script.
# EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#
# Preset Parameter: --listTimeZones
# List all time zones available on the system.
#
# Preset Parameter: --setTimeZone
# Specify a time zone to set. Use the "List Time Zones" option to get a list of available time zones. If the automatic time zone setting is enabled, it will be disabled. Example Time Zone: America/New_York
#
# Preset Parameter: --setTimeZoneAutomatically
# Set the time zone automatically based on the physical location of the device. Valid values are "Enable" or "Disable". Enabling will also enable Location Services and Wi-Fi if they are not already enabled. Leave blank to not modify the setting.
#
# Preset Parameter: --setSyncServer
# Specify the server to use for time synchronization. Only one server can be set. Example: time.apple.com
#
# Preset Parameter: --syncNow
# Sync time after updating settings for the time sync service.
#
# Minimum OS Architecture Supported: macOS 12+
# Version: 1.0
# Release Notes: Initial Release
_arg_listTimeZones=false
_arg_setTimeZone=""
_arg_setTimeZoneAutomatically=""
_arg_setSyncServer=""
_arg_syncNow=false
die() {
local _ret="${2:-1}"
echo "$1" >&2
test "${_PRINT_HELP:-no}" = yes && print_help >&2
exit "${_ret}"
}
print_help() {
printf '\n\n%s\n\n' 'Usage: [--listTimeZones] [--setTimeZone <timezone>] [--setTimeZoneAutomatically <Enable|Disable>] [--setSyncServer <server>] [--syncNow]'
printf '%s\n' 'Preset Parameter: --listTimeZones'
printf '\t%s\n' 'List all time zones available on the system.'
printf '%s\n' 'Preset Parameter: --setTimeZone'
printf '\t%s\n' 'Specify a time zone to set. Use the "List Time Zones" option to get a list of available time zones. If the automatic time zone setting is enabled, it will be disabled. Example Time Zone: America/New_York'
printf '%s\n' 'Preset Parameter: --setTimeZoneAutomatically'
printf '\t%s\n' 'Set the time zone automatically based on the physical location of the device. Valid values are "Enable" or "Disable". Enabling will also enable Location Services and Wi-Fi if they are not already enabled. Leave blank to not modify the setting.'
printf '%s\n' 'Preset Parameter: --setSyncServer'
printf '\t%s\n' 'Specify the server to use for time synchronization. Only one server can be set. Example: time.apple.com'
printf '%s\n' 'Preset Parameter: --syncNow'
printf '\t%s\n' 'Sync time after updating settings for the time sync service.'
}
parse_commandline() {
while test $# -gt 0; do
_key="$1"
case "$_key" in
--listTimeZones)
_arg_listTimeZones=true
shift
;;
--setTimeZone)
test $# -lt 2 && die "[Error] Missing value for the optional argument '$_key'." 1
_arg_setTimeZone="$2"
shift 2
;;
--setTimeZone=*)
_arg_setTimeZone="${_key##--setTimeZone=}"
;;
--setTimeZoneAutomatically)
test $# -lt 2 && die "[Error] Missing value for the optional argument '$_key'." 1
_arg_setTimeZoneAutomatically="$2"
shift 2
;;
--setTimeZoneAutomatically=*)
_arg_setTimeZoneAutomatically="${_key##--setTimeZoneAutomatically=}"
;;
--setSyncServer)
test $# -lt 2 && die "[Error] Missing value for the optional argument '$_key'." 1
_arg_setSyncServer="$2"
shift 2
;;
--setSyncServer=*)
_arg_setSyncServer="${_key##--setSyncServer=}"
;;
--syncNow)
_arg_syncNow=true
shift
;;
--syncNow=*)
_arg_syncNow="${_key##--syncNow=}"
;;
--help | -h)
_PRINT_HELP=yes die
;;
*)
_PRINT_HELP=yes die "[Error] Got an unexpected argument '$1'" 1
;;
esac
done
}
# Function to get a list of available time zones
function GetTimeZoneList() {
local timezones
if timezones=$(systemsetup -listtimezones | grep -v "Time Zone" | awk '{print $1}') && [ -z "$timezones" ]; then
echo "[Error] No time zones found." 1>&2
return 1
fi
echo "[Info] Available Time Zones:"
echo "$timezones"
}
# Function to test if location services is enabled
function TestLocationServices() {
# Check if location services are enabled
if ! value=$(defaults read /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled 2>/dev/null); then
return 1
elif [[ "$value" -eq 1 ]]; then
return 0
else
return 1
fi
}
# Function to get the wifi adapter name
function GetWifiAdapter() {
local adapter
if ! adapter=$(networksetup -listallhardwareports | awk -F: '/Wi-Fi/{getline; print $2;}' | xargs); then
return 1
fi
echo "$adapter"
}
# Function to test if the given wifi adapter is turned on
function TestWifiAdapter() {
local wifiAdapter=$1
wifiStatus=$(networksetup -getairportpower "$wifiAdapter")
if [[ "$wifiStatus" =~ "Off" ]]; then
return 1
else
return 0
fi
}
# Function to verify if the requirements for automatic time zone setting are met
function VerifyAutomaticTimeZoneRequirements() {
local wifiAdapter
# Check if location services are enabled
if ! TestLocationServices; then
autoTZBrokenReason="Location Services disabled"
return 1
fi
# Get the Wi-Fi adapter
if ! wifiAdapter=$(GetWifiAdapter); then
autoTZBrokenReason="Wi-Fi adapter not found"
return 1
fi
# Check if the Wi-Fi adapter is available and enabled
if ! TestWifiAdapter "$wifiAdapter"; then
autoTZBrokenReason="Wi-Fi adapter not enabled"
return 1
fi
return 0
}
# Function to set the automatic time zone setting
function SetAutomaticTimeZone() {
local action="$1"
local wifiAdapter
if [ -z "$action" ]; then
echo "[Error] No action specified. Use 'Enable' or 'Disable'."
return 1
fi
if [ "$action" != "Enable" ] && [ "$action" != "Disable" ]; then
echo "[Error] Invalid action specified. Use 'Enable' or 'Disable'."
return 1
fi
# If enabling automatic time zone, we need to ensure that location services and Wi-Fi are enabled
if [ "$action" = "Enable" ]; then
# Check if location services are enabled
# If not enabled, enable it
if ! TestLocationServices; then
echo "[Info] Enabling location services..."
if ! defaults write /var/db/locationd/Library/Preferences/ByHost/com.apple.locationd LocationServicesEnabled -int 1; then
echo "[Error] Failed to enable location services."
return 1
fi
echo "[Info] Successfully enabled location services."
fi
# Get the Wi-Fi adapter
if ! wifiAdapter=$(GetWifiAdapter); then
echo "[Error] No Wi-Fi adapter found. Automatic time zone setting requires Wi-Fi."
return 1
fi
# Check if the Wi-Fi adapter is available and enabled
# If not enabled, enable it
if ! TestWifiAdapter "$wifiAdapter"; then
echo "[Info] Enabling Wi-Fi..."
if ! networksetup -setairportpower "$wifiAdapter" on; then
echo "[Error] Failed to enable Wi-Fi."
return 1
fi
echo "[Info] Successfully enabled Wi-Fi."
fi
# Clear the autoTZBrokenReason variable in case it was set previously
autoTZBrokenReason=""
fi
# Enable or disable automatic time zone
if [ "$action" = "Enable" ]; then
# Set the plist file to enable automatic time zone
if ! defaults write /private/var/db/timed/Library/Preferences/com.apple.timed.plist TMAutomaticTimeZoneEnabled -bool YES; then
echo "[Error] Failed to enable automatic time zone setting."
return 1
fi
else
if ! defaults write /private/var/db/timed/Library/Preferences/com.apple.timed.plist TMAutomaticTimeZoneEnabled -bool NO; then
echo "[Error] Failed to disable automatic time zone setting."
return 1
fi
fi
# Modifying the plist file will change the ownership, so we need to set it back to the _timed user
if ! chown "_timed:_timed" /private/var/db/timed/Library/Preferences/com.apple.timed.plist; then
echo "[Error] Failed to set ownership of the plist file."
return 1
fi
# Reset the locationd service to apply changes
if ! killall locationd; then
echo "[Error] Failed to restart locationd service."
return 1
fi
}
# Function to restart the network time service
function RestartNetworkTimeService() {
# Restart the time server
if ! systemsetup -setusingnetworktime off 2>/dev/null 1>/dev/null; then
echo "[Error] Failed to stop time server."
return 1
fi
sleep 1
if ! systemsetup -setusingnetworktime on 2>/dev/null 1>/dev/null; then
echo "[Error] Failed to start time server."
return 1
fi
}
# Function to set the time zone
function SetTimeZone() {
local timezone="$1"
if [ -z "$timezone" ]; then
echo "[Error] No time zone specified."
return 1
fi
# Check if the time zone contains invalid characters
if ! [[ "$timezone" =~ ^[a-zA-Z0-9/_]+$ ]]; then
echo "[Error] Time Zone contains invalid characters. Only alphanumeric characters, underscores, and forward slashes are allowed."
return 1
fi
# Check if the time zone is valid
if ! systemsetup -listtimezones 2>/dev/null | grep -q "$timezone"; then
echo "[Error] Invalid time zone: $timezone"
return 1
fi
# If there is no reason for the automatic time zone being broken, enable it to see what the automatic time zone would be
# Then, warn if the automatic time zone is different than the requested time zone
if [ -z "$autoTZBrokenReason" ]; then
if SetAutomaticTimeZone "Enable"; then
# Wait for the automatic time zone to be set
sleep 10
autoTimeZone=$(systemsetup -gettimezone | awk '{print $3}')
if [ "$autoTimeZone" != "$timezone" ]; then
echo "[Warning] The automatic time zone for this device would be '$autoTimeZone' but the selected time zone is '$timezone'."
echo "[Info] If you want to use the automatic time zone, please enable the 'Set Time Zone Automatically' option."
fi
# If we are not disabling the automatic time zone later, disable it here so we can set the time zone
if [ "$_arg_setTimeZoneAutomatically" != "Disable" ]; then
# Print this message only if the automatic time zone was enabled at script runtime
if [ "$autoTimeZoneBeforeChange" = "1" ]; then
echo "[Info] Disabling the automatic time zone setting so that we can set the specified time zone."
fi
SetAutomaticTimeZone "Disable"
fi
fi
fi
# Set the time zone
if systemsetup -settimezone "$timezone" 2>/dev/null 1>/dev/null; then
return 0
else
echo "[Error] Failed to set time zone."
return 1
fi
}
# Function to set the sync server
function SetSyncServer() {
local server="$1"
# Error if a server was not provided
if [ -z "$server" ]; then
echo "[Error] No sync server specified."
return 1
fi
# Check if the server responds on UDP 123 (NTP port)
if ! nc -z -u "$server" 123 > /dev/null 2>&1; then
echo "[Error] The server at '$server' did not respond on UDP port 123."
return 1
fi
# Check if network time is enabled and enable it if not
if systemsetup -getusingnetworktime 2>/dev/null | grep -q "Off"; then
echo "[Info] Network time is currently disabled. Enabling it now."
if systemsetup -setusingnetworktime on 2>/dev/null 1>/dev/null; then
echo "[Info] Network time enabled."
else
echo "[Error] Failed to enable network time."
return 1
fi
fi
# Set the sync server
if systemsetup -setnetworktimeserver "$server" 2>/dev/null 1>/dev/null; then
return 0
else
echo "[Error] Failed to set sync server."
return 1
fi
}
# Function to sync the time immediately
function SyncNow() {
# Look for the sntp or ntpdate command to synchronize time
if command -v sntp >/dev/null; then
if sntp -sS "$(systemsetup -getnetworktimeserver | awk '{print $4}')" 2>/dev/null 1>/dev/null; then
return 0
else
return 1
fi
elif command -v ntpdate >/dev/null; then
if ntpdate -u "$(systemsetup -getnetworktimeserver | awk '{print $4}')" 2>/dev/null 1>/dev/null; then
return 0
else
return 1
fi
else
echo "[Error] No time sync command found. Either sntp or ntpdate should be available."
return 1
fi
}
# Execute command line parsing function with the passed arguments
parse_commandline "$@"
# If environment variables for the script parameters are set, override the command line argument values
if [[ $listTimeZones == "true" ]]; then
_arg_listTimeZones=true
fi
if [[ -n $setTimeZone ]]; then
_arg_setTimeZone=$(echo "$setTimeZone" | xargs) # Remove leading/trailing whitespace
fi
if [[ -n $setTimeZoneAutomatically ]]; then
_arg_setTimeZoneAutomatically=$(echo "$setTimeZoneAutomatically")
fi
if [[ -n $setSyncServer ]]; then
_arg_setSyncServer=$(echo "$setSyncServer" | xargs) # Remove leading/trailing whitespace
fi
if [[ $syncNow == "true" ]]; then
_arg_syncNow=true
fi
# Error if no arguments are provided
if [[ $_arg_listTimeZones == false && -z "$_arg_setTimeZone" && -z "$_arg_setSyncServer" && $_arg_syncNow == false && -z "$_arg_setTimeZoneAutomatically" ]]; then
_PRINT_HELP=yes die "[Error] No arguments provided. At least one argument is required to run this script." 1
fi
# Check if the script is being run as root. If not, exit with an error message.
if [[ $(id -u) -ne 0 ]]; then
_PRINT_HELP=no die "[Error] This script must be run with root permissions. Try running it with sudo or as the system/root user." 1
fi
# Initialize the exit code
exitCode=0
# List time zones if requested
if [[ $_arg_listTimeZones == true ]]; then
if [[ -n "$_arg_setTimeZone" ]] || [[ -n "$_arg_setSyncServer" ]] || [[ $_arg_syncNow == true ]] || [[ -n "$_arg_setTimeZoneAutomatically" ]]; then
echo "[Error] The 'Set Time Zone', 'Set Time Zone Automatically', 'Set Sync Server', and 'Sync Now' options cannot be used together with 'List Time Zones'."
echo ""
exitCode=1
fi
if ! GetTimeZoneList; then
echo "[Error] Failed to retrieve time zone list."
exitCode=1
fi
exit $exitCode
fi
# Error if an invalid value is provided for setTimeZoneAutomatically
if [[ $_arg_setTimeZoneAutomatically && ! $_arg_setTimeZoneAutomatically =~ ^(Enable|Disable)$ ]]; then
_PRINT_HELP=yes die "[Error] Invalid value for 'Set Time Zone Automatically'. Use 'Enable' or 'Disable'." 1
fi
# Error if setTimeZone is provided and setTimeZoneAutomatically is set to Enable
if [[ $_arg_setTimeZone && $_arg_setTimeZoneAutomatically = "Enable" ]]; then
_PRINT_HELP=yes die "[Error] You cannot enable automatic time zones and specify a time zone at the same time." 1
fi
# Check if setSyncServer has more than one server
if [ "$(
echo "$_arg_setSyncServer" |
tr ',' ' ' | # Replace commas with spaces
tr ' ' '\n' | # Split into lines
wc -l # Count lines
)" -gt 1 ]; then
die "[Error] Multiple time sync servers are not supported. Please provide a single server." 1
fi
# Initiate variable to track if settings are changed
_settingsChanged=false
# Get the current time zone and sync server settings
if ! syncServerBeforeChange=$(systemsetup -getnetworktimeserver | awk '{print $4}'); then
die "[Error] Failed to retrieve current sync server." 1
fi
if ! timeZoneBeforeChange=$(systemsetup -gettimezone | awk '{print $3}'); then
die "[Error] Failed to retrieve current time zone." 1
fi
if ! autoTimeZoneBeforeChange=$(defaults read /private/var/db/timed/Library/Preferences/com.apple.timed.plist TMAutomaticTimeZoneEnabled 2>/dev/null); then
autoTimeZoneBeforeChange=0 # Default to 0 if the key does not exist
fi
# Check if automatic time zone is broken so that autoTZBrokenReason can be set
VerifyAutomaticTimeZoneRequirements
echo ""
# Set the time zone if specified
if [ -n "$_arg_setTimeZone" ]; then
if [ "$timeZoneBeforeChange" = "$_arg_setTimeZone" ]; then
echo "[Info] Time zone is already set to '$_arg_setTimeZone'."
else
echo "[Info] Changing the time zone from '$timeZoneBeforeChange' to '$_arg_setTimeZone'."
if SetTimeZone "$_arg_setTimeZone"; then
echo "[Info] Successfully changed the time zone from '$timeZoneBeforeChange' to '$_arg_setTimeZone'."
_settingsChanged=true
else
echo "[Error] Failed to set the time zone to '$_arg_setTimeZone'."
exitCode=1
fi
fi
echo ""
fi
# Set automatic time zone if specified
if [ -n "$_arg_setTimeZoneAutomatically" ]; then
currentValue=$(defaults read /private/var/db/timed/Library/Preferences/com.apple.timed.plist TMAutomaticTimeZoneEnabled 2>/dev/null)
# If a reason for automatic time zone being broken is set, we will force the change
if [ -n "$autoTZBrokenReason" ]; then
forceChange=true
fi
if [ "$_arg_setTimeZoneAutomatically" = "Enable" ]; then
if [ "$currentValue" = "1" ] && [ "$forceChange" != true ]; then
echo "[Info] The automatic time zone setting is already enabled."
else
echo "[Info] Enabling the automatic time zone setting."
# Enable automatic time zone setting
if SetAutomaticTimeZone "Enable"; then
sleep 10
echo "[Info] Successfully enabled the automatic time zone setting."
_settingsChanged=true
else
echo "[Error] Failed to enable the automatic time zone setting."
exitCode=1
fi
fi
elif [ "$_arg_setTimeZoneAutomatically" = "Disable" ]; then
if [ "$currentValue" = "0" ] || [ -z "$currentValue" ]; then
echo "[Info] The automatic time zone setting is already disabled."
else
echo "[Info] Disabling the automatic time zone setting."
# Disable automatic time zone setting
if SetAutomaticTimeZone "Disable"; then
echo "[Info] Successfully disabled the automatic time zone setting."
_settingsChanged=true
else
echo "[Error] Failed to disable the automatic time zone setting."
exitCode=1
fi
fi
fi
echo ""
fi
# Set the sync server if specified
if [ -n "$_arg_setSyncServer" ]; then
if [ "$syncServerBeforeChange" = "$_arg_setSyncServer" ]; then
echo "[Info] Time sync server is already set to '$_arg_setSyncServer'."
else
echo "[Info] Changing the time sync server from '$syncServerBeforeChange to '$_arg_setSyncServer'."
if SetSyncServer "$_arg_setSyncServer"; then
echo "[Info] Successfully changed the time sync server from '$syncServerBeforeChange' to '$_arg_setSyncServer'."
_settingsChanged=true
else
echo "[Error] Failed to set the sync server to '$_arg_setSyncServer'."
exitCode=1
fi
fi
echo ""
fi
# If settings were changed, restart the time service and print the previous settings
if [ "$_settingsChanged" = true ]; then
echo "[Info] Settings have been changed. Restarting the time service to apply changes."
# Restart the time service to apply changes
if ! RestartNetworkTimeService; then
echo "[Error] Failed to restart the time service."
exitCode=1
else
echo "[Info] Time service restarted successfully."
fi
echo ""
echo "*** Previous Time Sync Settings: ***"
if [ -n "$timeZoneBeforeChange" ]; then
echo "Time Zone: $timeZoneBeforeChange"
fi
if [ -n "$syncServerBeforeChange" ]; then
echo "Sync Server: $syncServerBeforeChange"
fi
if [ -n "$autoTimeZoneBeforeChange" ]; then
if [ "$autoTimeZoneBeforeChange" = "0" ]; then
echo "Automatic Time Zone: Disabled"
else
if [ -n "$autoTZBrokenReason" ]; then
echo "Automatic Time Zone: Enabled but not working (Reason: $autoTZBrokenReason)"
else
echo "Automatic Time Zone: Enabled"
fi
fi
fi
fi
echo ""
# Retrieve the current time sync settings
echo "*** Current Time Sync Settings: ***"
if ! currentTimeZone=$(systemsetup -gettimezone | awk '{print $3}'); then
echo "[Error] Failed to retrieve current time zone."
exitCode=1
fi
if ! currentSyncServer=$(systemsetup -getnetworktimeserver | awk '{print $4}'); then
echo "[Error] Failed to retrieve current sync server."
exitCode=1
fi
if ! currentAutoTimeZone=$(defaults read /private/var/db/timed/Library/Preferences/com.apple.timed.plist TMAutomaticTimeZoneEnabled 2>/dev/null); then
currentAutoTimeZone=0 # Default to 0 if the key does not exist
fi
# Print the current settings
if [ -n "$currentTimeZone" ]; then
echo "Time Zone: $currentTimeZone"
fi
if [ -n "$currentSyncServer" ]; then
echo "Sync Server: $currentSyncServer"
fi
if [ -n "$currentAutoTimeZone" ]; then
if [ "$currentAutoTimeZone" = "0" ]; then
echo "Automatic Time Zone: Disabled"
else
if [ -n "$autoTZBrokenReason" ]; then
echo "Automatic Time Zone: Enabled but not working (Reason: $autoTZBrokenReason)"
else
echo "Automatic Time Zone: Enabled"
fi
fi
fi
# Sync the time immediately if requested
if [ "$_arg_syncNow" = "true" ]; then
echo ""
echo "[Info] Syncing the time with the new settings."
if ! SyncNow; then
die "[Error] Failed to synchronize time." 1
else
echo "[Info] Time synchronized successfully."
fi
fi
# Get the current time and print it
currentTime=$(date +"%Y-%m-%d %T")
echo ""
echo "*** Current System Time: ***"
echo "$currentTime"
exit $exitCode
Detailed Breakdown
The script begins by parsing command-line arguments, allowing administrators to choose specific operations:
- Listing time zones
The –listTimeZones flag uses systemsetup -listtimezones to output all available macOS time zones. - Setting a time zone
The –setTimeZone <timezone> parameter validates the requested time zone and applies it using systemsetup -settimezone. - Automatic time zone management
Using –setTimeZoneAutomatically Enable|Disable, the script toggles macOS’s automatic time zone detection. If enabling, it ensures Location Services and Wi-Fi are active, restarting services as needed. - Setting a synchronization server
With –setSyncServer <server>, administrators can point macOS to a preferred NTP server. The script validates connectivity by checking UDP port 123. - Immediate synchronization
The –syncNow option forces synchronization via sntp or ntpdate.
Behind the scenes, the script also safeguards against conflicts (e.g., preventing simultaneous use of –setTimeZone and –setTimeZoneAutomatically Enable), checks for root permissions, and reports both current and previous configurations for auditing.
Potential Use Cases
Imagine an MSP managing remote macOS devices spread across multiple regions. A client reports authentication failures because their laptops show incorrect times. Instead of remote desktop sessions, the MSP deploys this script via their RMM tool. With one command, they enforce –setSyncServer time.apple.com –syncNow across all endpoints, ensuring consistent time settings and resolving authentication issues within minutes.
Comparisons
Traditionally, administrators would manually adjust settings through System Preferences or use standalone commands like systemsetup. While effective for one machine, these methods lack scalability. Configuration management tools like Jamf provide enterprise-level solutions but may be excessive for smaller environments. This script strikes a balance—lightweight, easily deployable, and compatible with RMM tools like NinjaOne.
Implications
Accurate time synchronization directly impacts IT security. Authentication protocols rely on precise timekeeping, and even slight drift can cause failures. For forensic investigations, misaligned logs can complicate timelines and jeopardize compliance. Automating these configurations reduces human error and enforces organizational standards across distributed environments.
Recommendations
- Test before deployment: Run the script on a pilot group before broad rollout.
- Use a trusted NTP server: Prefer vendor or corporate NTP servers to ensure reliability.
- Audit settings regularly: Use the reporting functionality to validate compliance.
- Document policies: Define when to use automatic vs. manual time zones.
Final Thoughts
Managing time zone and synchronization settings on macOS doesn’t need to be complex. This shell script provides a straightforward, repeatable solution for IT professionals and MSPs who value precision and efficiency. When paired with NinjaOne’s automation and policy deployment capabilities, administrators can push this script fleet-wide, ensuring all devices remain synchronized and compliant without manual intervention. The result is a more secure, consistent, and reliable environment across the enterprise.