MacBook – Programmatic access to connect to a wifi network

macbook proNetworkrouterwifi

Very similar to this question, but as encouraged to do my @bmike I wanted to re-ask this question as it was not a duplicate of Create AirPort network from the command line.

I am looking for a programmatic way to connect to a wifi network. It can be saved (remembered) or unknown, preferably in Apple Script or via Automator.

I have done this on a Windows PC through the following command:

netsh wlan add profile wifi.xml user=current

(creating it, as the only available wifi network, would attempt to connect to it)

The real problem I am having is: I have a Mac Book, OSX 10.10, shared by two users. One user should be able to access (and preferably connect by default) to SSID "Wifi1" and the second user should be able to access SSID "Wifi2", but neither user should connect to the other user's wifi. The Windows netsh wlan with option user=current accomplishes this but I don't see this being supported on a Mac.

Disabling SSID remembering, and having the users type the password in each time, would of course accomplish this goal but I'm searching for a more automated solution.

I have not found a way to accomplish this via preferences, wifi priorities, remembering networks, or anything else.

Also to note, Fast User Switching is enabled (this appears to make scripting difficult in my research because there is no reliable trigger or event to listen to for the script to run).

Best Answer

This should do it, although it may need some modification. Every time a user switches, a system log entry is created. Knowing this, you can monitor for user switches quite effortlessly:

global wifi_device
on run
    set wifi_device to do shell script "networksetup -listallhardwareports|grep -A1 'Wi-Fi'|grep Device|sed 's;Device: ;;'"
end run
on idle
    set user_name to do shell script "tail -n0 -f /var/log/system.log|grep -om1 'context values set for .*'|sed -e 's;context values set for ;;'"
    if user_name is equal to "presaccount" then
        do shell script "networksetup -setairportnetwork " & wifi_device & " presaccount_network password"
    else if user_name is equal to "other_account" then
        do shell script "networksetup -setairportnetwork " & wifi_device & " other_account_network password"
    end if
    return 1
end idle

Just change the network names, passwords, and account names to whatever you need them to be.

Basically, we're checking for the log entry containing "context values set for", which occurs on every switch, and contains the username switched to. We use this username to determine which network to join, and that's it! I'd recommend only allowing admins to change the wifi network in system preferences. This actually uses nearly no resources, because the script cannot continue past the first line, until a user switches. Keep in mind that this was done on 10.11. I can't verify if the log entry is present on 10.10, so YMMV. You'll have to save this as a stay-open app in Script Editor.