The Adventures of Systems Boy!

Confessions of a Mac SysAdmin...

Remote Network (and More!) Management via the Command-Line

There's a lot you can do in the Terminal in Mac OS X. It's often the most expedient method of achieving a given task. But I always get stuck when it comes time to make certain network settings via the command-line. For instance, in the lab all our machines are on Built-In Ethernet, and all are configured manually with IP addresses, subnet masks, routers, DNS servers and search domains. But sometimes we need to make a change. While I suppose it's easy enough to go over to the computer, log in, open the System Preferences, click on the Network pane, and configure it by hand in the GUI, this becomes a problem when you have to interrupt a staff member busily working on whatever tasks staff members tend to busily work on. Also, it doesn't scale: If I have to make a change on all 25 Macs in the lab, the above process becomes tedious and error-prone, and exponentially so as we add systems to the network. When performing such operations on multiple computers, I generally turn to Apple's wonderful Remote Desktop. But ARD (I'm still using version 2.2) lacks the ability to change network settings from the GUI. Fortunately, there is a way.

ARD comes with command-line tools. They're buried deep in the ARD application package, for some reason, making them a serious pain to get at, but they're there and they're handy as hell in situations like the above. You can use these tools to set up virtually anything normally accessible via the System Preferences GUI. Including network settings. There are two main commands for doing this:
systemsetup for making general system settings, and networksetup for making network settings.

Both commands are located in the folder:

You'll need to type the full path to use the commands, or cd into the directory and call them thusly:

Or you can do what I do and add an alias to them in your .bash_profile:
alias networksetup='sudo /System/Library/CoreServices/RemoteManagement/'

There are no man pages for these commands, but to get an idea of what they do and how they work, just run them without any arguments and they'll print a list of functions. Or you can run the commands with the -printcommands flag to get an abbreviated list of functions. There is also a PDF reference online. The syntax for these tools is not always straightforward, but by and large looks something like this:
networksetup -option <"network service"> <parameter 1> <parameter 2> <etc...>

For "network service" you'll want to enter the name of the interface as it's called in the preference pane, surrounded by quotes. You also need to run these commands as root. Here's an example that makes network settings (IP address, subnet mask and router, respectively) for Built-In Ethernet:
sudo networksetup -setmanual "Built-In Ethernet"

Here's an example for setting multiple search domains:
sudo networksetup -setsearchdomains "Built-In Ethernet"

Why these tools aren't included in the GUI version of ARD is almost as confounding as the fact that they're buried deep within the guts of the app. The wordy syntax doesn't help either (I'd much prefer typing "en0" to "Built-In Ethernet" any day). But despite being difficult to access, I've found these commands to be unbelievably useful from time to time. And though I certainly do hope to edify TASB readers as to the existence and use of these tools, I must confess, my main reason for this post is as a reminder to myself: I'm always forgetting where the damn things are and what the hell they're called.

So there you have it. Remote network (and more!) management via the command-line.

Please resume admin-ing.

So a scenario occurred to me which might be a bit tricky with regards to the above information: Say you want to change the router setting for your 25 lab macs. Nothing else, just the router. The obvious way to do this would be to send a networksetup command to all of your Macs via ARD. The problem is that the networksetup command has no way of specifying only the router address, without setting the IP address and subnet mask as well. The only way to set the router address is with the -setmanual flag, and this flag requires that you supply an IP address, subnet mask and router address, respectively:
sudo networksetup -setmanual "Built-In Ethernet"

If you send this command to every Mac in your lab, they'll all end up with the same IP address. This will wreak havoc in numerous ways, the worst of which will be the fact that you now have lost all network contact with said lab Macs and will have to go and reset all the IP addresses by hand on each machine. The solution is to specify the current IP address on each machine, which you could do by sending an IP-specific version of the command to each machine individually. But that sort of defeats the purpose of using ARD in the first place. A better way is to substitute a variable in place of the IP address option in the above command. The variable will get the IP address of the machine it's run on. This is what I use:
ifconfig -m en0 | grep "inet " | awk {'print$2'}

This command sequence will get the IP address for the en0 interface, which is what Built-In Ethernet uses. If your machines are on wireless, you can use en1 in place of en0:
ifconfig -m en1 | grep "inet " | awk {'print$2'}

So, instead of entering the IP address in the networksetup command, we'll enter this command sequence in backticks. The command we'd send to our lab Macs would look something like this:
sudo networksetup -setmanual "Built-In Ethernet" `ifconfig -m en0 | grep "inet " | awk {'print$2'}`

This will set the subnet mask and router address — both of which would generally be consistent across machines on any given network — but will leave the unique IP address of each machine intact. You can try this on your own system first to make sure it works. Open the Network System Preference pane, and then run the command in Terminal. You'll see the changes instantly in the preferences pane, which will even complain that an external source has changed your settings. If all goes well, though, your IP address will remain the same while the other settings are changed. You should now be able to safely change the router address of all your machines using this command in ARD (remember to specify the full command path though). Save that sucker as a "Saved Task" and you can do this any time you need to with ease.


Labels: , ,

« Home | Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »
| Next »

8:06 PM

Welch covered this topic back in Feb 06, Check it out:    

8:08 PM

oh yeah, one more thing: i guess it's a personal taste kind of thing, but instead of the alias you could just put that directory in your path, so that you could call those commands buried in there. Add em in /etc/profile or elsewhere as needed.    

1:50 AM

Actually, that looks like a good article. Seems to focus more on the systemsetup bits I left out. I wasn't familiar at all with kickstart.

Yeah, like I said: This post's more a reminder to me 'cause every time I need to use those commands I end up having to look up their location on the 'net. For that reason, I'm quite painfully aware that this is covered many other places. It's just nice to have the reference handy on my own site so I don't have to go hunting, 'cause, you know, I'm lazy. Plus, writing it out helps me remember.

Thanks for the link, though. Could be useful some day.

For whatever reason, I never use /etc/profile. I guess I just learned about .bash_profile first and was never terribly comfortable altering that stuff system-wide. I have added some paths in my .bash_profile. Mostly folders full of commands though (like /Developer/Tools). If it's just a command or two, I usually do aliases. Not sure why. I guess I'm weird.



9:51 AM

I'm not near a mac right now so I can't get at a manpage for networksetup, but it would seem that if you have issues with this command setting the IP address of an interface at the same time as it sets the default route you could let it set lo0 to, no harm to doing that on as many boxen as it wants.    

11:06 AM

No, that wouldn't really work. With networksetup you have to specify a specific network interface — in this case "Built-In Ethernet" or "en0" — and you have to specify IP, Subnet and Router addresses for that interface, in that order. So if you want to change the Router setting, but not the IP Address you need to insert some variable in the command that returns the current IP Address of the system in question in place of the IP Address in the command.

It seems to me like it would be fairly common to want to change a router address across a whole bunch of machines, but leave the IP Address alone, as IP Addresses are generally unique to machines, whereas Router addresses are generally not. So yeah, I do sort of have issues with it. It's not a big deal, and I can work around it. I just wish I didn't have to. If the command were better thought out, I wouldn't.


1:10 AM

finally got a good opportunity to use 'networksetup' as I had to change to DNS info on all the machines in the entire place. worked like a charm, except on the Xserves and the Quads, it's "networksetup -setdnsservers Built-in\ Ethernet\ 1" but two batches of Send Unix command in ARD3 and voila. Though on another note changing DNS can have some funny effects everywhere. So many things depend on it, e.g. Xsan, Render apps, etc    

3:42 PM

Yes, changing DNS can have unintended effects, especially on servers, and especially if those servers are Mac OS X Servers which have some serious DNS dependencies. I've been learning a whole lot about DNS lately. If there's one thing I've realized it's that setting DNS up properly on your network at the outset is extremely important and makes life so much easier. Again, particularly before building servers. Without it, stuff just won't work right.

Anyway, glad you found success with networksetup.


» Post a Comment