Programmatically Grab Active DNS Servers On macOS

One of my favorite things about grabbing things with scripts is just how many ways (and sometimes how needfully or needlessly convoluted you can make them) to grab the same pieces of information. For example, something as simple as what hosts you use to resolve names on a Mac. There are a number of ways to grab what DNS server a device is using in macOS. So when you’re running a script you might choose to grab DNS information one way or another, according to what you’re after. Some of this might seem more complicated than it should be. And that’s correct…


The /etc/resolv.conf file is updated automatically to look at what servers are used to resolve names used for DNS. The easiest way to see theses to simply cat it and grep for nameserver: cat /etc/resolv.conf | grep nameserver


The next way we’ll grab DNS information is using scutil. Here, we use the –dns option, which outputs a lot of DNS stuffs, including all the built-in resolvers: scutil --dns To just grab the name servers: scutil --dns | grep nameserver We can also simplify the output to just the servers with awk: scutil --dns | grep nameserver | awk '{print$3}'


The second way is using networksetup. This command has an option to get a DNS server in (shocker) -getdnsservers. However, you have to list the interface for each. So below we’ll dump all interfaces into an array using -listallhardwareports and then read them in using a for loop and querying the name servers. interfaces=( "$(networksetup -listallhardwareports | grep Hardware | cut -c 16-900)" ) for i in "${interfaces[@]}" do networksetup -getdnsservers $i done The one tricky thing in this one is I initially forgot to quote the interfaces as they went into the array, which meant each word of the interface was an item in the array and therefore the -getdnsservers option failed. Once I quoted, it was all happy. The other thing I can point out is I used cut instead of sed because it was easier to quote; however, it seems unlikely the name can be more than 890 characters, so I think it’s fine…


You can also use dig. Here, you’ll query for a name without using an @ option, but omit everything but the line with the server that responded: dig | grep SERVER: The output is kinda’ fug:
For simpler output, we’ll use sed to constrain the output to just what’s between the parenthesis: dig | grep SERVER: | sed 's/^.*(//;s/)$//'


nslookup is a tool similar to dig, used for querying names. We’ll basically do the same thing as above, just using awk as it’s just a standard position in a line: nslookup | grep Server: | awk '{print$2}'


Then there’s system_profiler, the command line interface for System Profiler. Here, we can query the SPNetworkDataType. This is going to produce a lot of output, so we can limit it to just the DNS servers using grep to constrain to just the lines we want and awk for just the columns in those lines, as follows: system_profiler SPNetworkDataType | grep "Domain Name Servers:" | awk '{print$4}'


@knapjack added to use hosts. I had to use verbose mode to pull the local name server as follows: host -v -t ns | grep Received | awk '{print $5}'


Thanks to the lovely Allister (@sacrilicious), we also have ipconfig to add to the list: /usr/sbin/ipconfig getpacket en0 2> /dev/null | grep name_ | cut -d' ' -f3- There are tons of ways to find things in macOS. Do you have a way to find a DNS server that I didn’t think of here?

Command Line System Information

When you click on About This Mac and then click on More Info… you see the Apple System Profiler.  This tool, dating back to the Classic OS (prehistory so-to-speak) can be used to access a wide variety of information about your system, including installed hardware, software and some settings.  Some of this information can also be obtained through other tools.  For example, the networksetup command can obtain a wide variety of information about various network settings.  But it helps to have one tool to query for any information you may need about a computer (well, much of the information you may need).   While it is fairly straight forward to sit down and and open Apple System Profiler and look for information, this can be fairly tedious to do en masse.  Luckily, there is a command line version of the Apple System Profiler, aptly named system_profiler.  This command can be used to view any of the information from the Apple System Profiler, which you can then parse and use in scripts in a variety of ways.  This allows you to, for example, go far beyond what Apple Remote Desktop can provide in terms of reports and even write relevant information from systems into an out-of-band database, common in enterprise environments looking to centralize asset management for Macs into an existing Windows or Linux solution. Using the system_profiler command is fairly straight forward.  If you just run system_profiler then it will show you far more information than you can likely use.  Essentially, every field from Apple System Profiler will be displayed, including installed Frameworks, Fonts, Extensions, etc.  Therefore, a healthy dose of grep can help immensely.  But what do you grep for?  Well, find a field in Apple System Profiler and note the section it’s in under the Contents column of the application.  Then, run the following command:
system_profiler -listdatatypes
You should see an output similar to the following (notice the similarity with the items from the GUI):
SPHardwareDataType SPNetworkDataType SPSoftwareDataType SPParallelATADataType SPAudioDataType SPBluetoothDataType SPDiagnosticsDataType SPDiscBurningDataType SPFibreChannelDataType SPFireWireDataType SPDisplaysDataType SPHardwareRAIDDataType SPMemoryDataType SPPCCardDataType SPPCIDataType SPParallelSCSIDataType SPPowerDataType SPPrintersDataType SPSASDataType SPSerialATADataType SPUSBDataType SPAirPortDataType SPFirewallDataType SPNetworkLocationDataType SPModemDataType SPNetworkVolumeDataType SPApplicationsDataType SPExtensionsDataType SPFontsDataType SPFrameworksDataType SPLogsDataType SPManagedClientDataType SPPrefPaneDataType SPStartupItemDataType SPUniversalAccessDataType
Now if you match up the item from the Contents section of the graphical app to the one most closely resembling it from this list you should have where that information is going to be stored.  For example, let’s say that we want to know which computers have a 3rd party (non-Apple) System Preference pane installed.  Well, we can pull this from the SPPrefPaneDataType and then constrain our search to those containing the string 3rd.  Therefore, if the results of the following command show you anything at all then you have a third party System Preference Pane installed:
system_profiler SPPrefPaneDataType | grep 3rd
From here you can get far more detailed.  If you are running this en masse you’ll likely want to include the computer name, part of SPSoftwareDataType.  Then let’s say we wanted to know which systems had Flip4Mac installed – we could run the following:
system_profiler SPSoftwareDataType | grep “Computer Name”; system_profiler SPPrefPaneDataType | grep Flip4Mac 
With regular expressions we can actually get really detailed information out of system_profiler and then normalize the data for inclusion into our database; perhaps adding a , for a delimiter, etc.