macOS and advanced network commands for managing DNS settings
While MDM is unequivocally a must for managing macOS at (really any) scale, there are times when the core capabilities of MDM won’t meet our needs, and a custom scripted approach is required.
Commands for determining the active network interface and working with DNS server settings:
When we want to programmatically determine the existing primary network interface ID, name and existing DNS servers, there are a few different ways we can go about this:
serviceGUID="$(printf "open\nget State:/Network/Global/IPv4\nd.show" | /usr/sbin/scutil | /usr/bin/awk '/PrimaryService/{print $3}')"
serviceName="$(printf "open\nget Setup:/Network/Service/${serviceGUID}\nd.show" | /usr/sbin/scutil | /usr/bin/awk -F': ' '/UserDefinedName/{print $2}')"
!!! OR !!!
activeIF=$(route -n get 0.0.0.0 2>/dev/null | awk '/interface: / {print $2}')
serviceName=$(networksetup -listnetworkserviceorder | grep "$activeIF" | awk -v FS="(Hardware Port: |,)" '{print $2}')
The problem with cataloging existing DNS servers, when they are supplied via DHCP
When DNS servers are provisioned via DHCP, a common approach for determining the IP addresses for said servers will fail:
/usr/sbin/networksetup -getdnsservers "$serviceName"
Returns with incorrect info: “There aren’t any DNS Servers set on <serviceName>”
Which is hardly useful ! So, we can proceed with the following:
For utility and extra tech-type fun, let’s use an array !
currDNS=($(/usr/sbin/networksetup -getdnsservers "$serviceName"))
if [[ ${currDNS[0]} == "There" ]]; then
currDNS=($(ipconfig getsummary $activeIF | awk -v FS="({|, |})" '/domain_name_server/ {$1=""; print $0 }'))
fi
# check the array, via
# declare -p currDNS
# For an example of working with the captured info:
# echo ${currDNS[0]}
# So now you can capture those existing DNS servers and append another
/usr/sbin/networksetup -setdnsservers "$serviceName" ${currDNS[0]} ${currDNS[1]} 8.8.8.8