MacOS Ventura Sonoma Preferred Network Manipulation using networksetup

DinnerTIME
New Contributor II

Warning: I'm just learning how to script using The Odin Project. This is a crude, but so far is effective way of checking to see if my users are on a particular wifi network, and switch them over to another as needed.

Problem: We're moving away from having static admin accounts deployed on our devices and are trialing the creation of just-in-time admin accounts when servicing a computer.

For this to work, wifi needs to be enabled at the MacOS login screen (NoMAD 1.5). This is achieved by pushing out a computer level config profile with a wifi payload, Wifi A. So far so good. Wifi A is heavily restricted and does not allow general internet access.

However, after the user logs in, they will then have access to our normal enterprise wifi - Wifi B.

How can I then ensure that my users are always connected to Wifi B upon logging in? I decided to create a launch agent that runs every 60 seconds and checks for the currently connected wifi network. If the user is found to be on Wifi A this launch agent will run a script which switches them to Wifi B and makes Wifi B the preferred network.

Simple, if not for the fact that in the most recent versions of MacOS, you can no longer manually specify your preferred wifi networks. MacOS will now always make its most recently connected network its top preferred network. In addition to this, I've found that when switching wifi off then on, MacOS will immediately try to connect to the last network it had a connection to and therefore make that network its most preferred network.

My current work around is to leverage the networksetup utility :

  • User is on Wifi A and to macos, this is now the top preferred network
  • Remove both Wifi A and Wifi B as the preferred networks. Wifi still connected.
  • Switch Airport power off
  • Add Wifi B back in which now becomes the preferred network
  • Switch Airport power on.
  • Remove Wifi B as preferred network (again).
  • Add Wifi A as a preferred network at index 99 (that gets added to bottom of list)
  • Add Wifi B as a preferred network at index 0. Because this is the last network added using the network setup utility it is now the preferred network.

The network index value is now quite unreliable. The network I want my users to be on has to be added as the final step.

The script I based this on is linked here. Thanks @Asnyder 

This isn't in production yet, and I'd love some feedback so let me know what you think.  Can I improve anything? And if you think there's a better / different way to achieve the same outcome or if I've made any serious mistakes. Thank you.

note - I did find that networksetup -setairportnetwork to be wholly unreliable in my testing. Hence the airport port power off and on.

 

 

 

#!/bin/bash
                                             
# Begin Variable Definitions
#Replace WIFINAME with your school WiFi.  Leaving it empty will disconnect from any network.

 #MacOS Ventura and Sonoma have a weird thing where they will kind of ignore the index value
 #in the "networksetup -addpreferredwirelessnetworkatindex <device> <SSID> <Index> <Security type>
 #MacOS will also always add the most current wifi network to the top of the list
 #MacOS will also try to immediately connect to the last known good network after being switched off
 #

wifiGood="wifiB"
wifiBad="wifiA"
currentWifi=`networksetup -getairportnetwork en0 | awk '{print $4}'`
#MyWifi=`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport --getinfo | grep " SSID" | awk '{print $2}'`

# End of Variable Definitions

# Begin Function Declarations


disconnect ()
{
        echo "Time to disconnect"
        # send disconnect command to en0
        networksetup -removepreferredwirelessnetwork en0 $wifiGood;
        networksetup -removepreferredwirelessnetwork en0 $wifiBad;
        echo "Removed both $wifiGood and $wifiBad from preferred networks"
        
        echo "attempting to disassociate from "$wifiBad" ..."
        /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -z $wifiBad
        echo "Switching Wifi off.."
        networksetup -setairportpower en0 off;
        echo "Re-adding "$wifiGood" to the Preferred Network list..."
        networksetup -addpreferredwirelessnetworkatindex en0 $wifiGood 0 WPA2E;
        echo "Switching Wifi on.."
        networksetup -setairportpower en0 on;
        sleep 5;
        networksetup -removepreferredwirelessnetwork en0 $wifiGood;
        networksetup -removepreferredwirelessnetwork en0 $wifiBad;
        echo "Removed both $wifiGood and $wifiBad from preferred networks"
        echo "Re-adding "$wifiBad" to the Preferred Network list..."
        networksetup -addpreferredwirelessnetworkatindex en0 $wifiBad 99 WPA2;
        echo "Re-adding "$wifiGood" to the Preferred Network list..."
        networksetup -addpreferredwirelessnetworkatindex en0 $wifiGood 0 WPA2E;

}




# End Function Declarations

#########################

#program starts here

if [ "$currentWifi" == "$wifiBad" ]
            then # Asset is on the $wifiBad Wifi
            echo "I am connected to the "$wifiBad" Wifi"
            disconnect
            else
            echo "I am not connected to the "$wifiBad" wifi"
        fi
    networksetup -listpreferredwirelessnetworks en0
       exit 0;

        

 

 

 

 

2 REPLIES 2

sdagley
Esteemed Contributor II

@DinnerTIME Be aware the method you're using will break any Wi-Fi configuration that uses 802.1x authentication you remove and then add back. The following post contains a Python script that doesn't have that problem and will sort a given list of SSIDs to be the highest priority SSIDs. I have not used this script in quite  while, so I don't know if it still works on macOS Sonoma, but there have been reports it did function with macOS Ventura: https://community.jamf.com/t5/jamf-pro/re-order-wifi-preferred-networks/m-p/262367/highlight/true#M2...

YanW
Contributor III

Remove WiFi A then turning off and on WiFi should switch you to WiFi B without deleting and re-adding. 

On the safer side, use this to determine the Wi-Fi Interface

 

wifiInterface=$( networksetup -listallhardwareports | awk '/Wi-Fi/{getline; print $NF}' ) 

 

WiFi Screenshot.png