I do the same thing! We have a specific personal-device network which uses a captive portal to authenticate, and users (for various nonsense reasons) seem to like connecting their Macs to it. That makes the Mac lose its connection to Casper once the network requires re-authentication.
I use an ongoing offline policy to run this script at checkin:
#!/bin/sh
for interface in $(networksetup -listnetworkserviceorder | grep Hardware | awk '/Wi-Fi/ { print $NF }' | awk -F ")" '{ print $1 }')
do
echo "Disconnecting $interface from non-internal device network"
networksetup -removepreferredwirelessnetwork $interface YourNetworkSSIDHere
done
If you were looking to go the Smart Group route you could build an EA using the output from:
networksetup -listpreferredwirelessnetworks "en0"
And only include those devices that have your guest network in the list.
As a test I just created an EA with the script of:
#!/bin/bash
PreferredNetworks=$(networksetup -listpreferredwirelessnetworks "en0")
echo "<result>$PreferredNetworks</result>"
exit 0
And this is successfully returning the complete list of Preferred Networks. I then creates a Smart Group with the criteria that this EA is "like" our Guest network, and it seems to be correctly pulling only those device with this network.
Thanks so much, @musat!
I am returning the following errors on just a small handful of machines.
en0 is not a Wi-Fi interface. ** Error: Error obtaining wireless information.
When performing a quick SSH session, their en1 is their Wi-Fi interface and not their en0, hence the above error. I modified your suggested script and received the list of preferred networks for the listed en1 port and then removed it.
networksetup -listpreferredwirelessnetworks "en1"
sudo networksetup -removepreferredwirelessnetwork en1 <WirelessSSID>
My question to you now is, how do I target the few machines producing the "en0 is not a Wi-Fi interface" error and correct this?
You should never hardcode "en0" into a script that needs to know the wifi interface id to capture something or affect a change. Instead, get the wi-fi identifier first in the script using networksetup and then use that as a variable in the command later.
#!/bin/sh
WirelessPort=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')
PreferredNetworks=$(networksetup -listpreferredwirelessnetworks "$WirelessPort" | sed 's/^ //g')
echo "<result>$PreferredNetworks</result>"
Great, thanks @mm2270!
I've now gone ahead and created a Smart Computer Group which targets the machines with the older SSID which needs to be removed which is achieved by the results of newly created extension attribute. There does not appear to be a designated payload that will achieve this so I imagine that a small script removing <networkSSID> will have to be created. As mentioned above, assuming the standard en0 is the designated wireless port, the below removed the problematic SSID. How would I modify this into a script where the "en0" is not assumed and hardcoded?
networksetup -listpreferredwirelessnetworks "en0"
sudo networksetup -removepreferredwirelessnetwork en0 <WirelessSSID>
@sepiemoini Same way as in my script above. Get the id of the wireless port first, then use that in replace of en0 or en1 in the -removeprefererredwirelessnetwork command.
Truthfully, you could just skip creating an EA for this and go straight for a removal in a script. Although, the only issue is if you only had it running once per computer, later on the SSID could be added and not subsequently removed from the Mac. Using a Smart Computer Group scoped to a policy set to Ongoing would ensure that every time a machine lands in the smart group, the policy would run on it to remove the SSID on next check-in or trigger.
Awesome, thanks @mm2270! How does the bellow script look?
#!/bin/sh
WirelessPort=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')
PreferredNetworks=$(networksetup -listpreferredwirelessnetworks "$WirelessPort" | sed 's/^ //g')
echo "<result>$PreferredNetworks</result>"
sudo networksetup -removepreferredwirelessnetwork $WirelessPort <WirelessSSID>
UPDATE: that worked
One last change would be to remove sudo. It's not required in scripts Casper will run because Casper already runs them with the elevated privileges.
Hi @sepiemoini, @adamcodega is correct. Drop the sudo since its not needed.
Beyond that change though, what you seem to have is a combination of an EA and a script making a change. Maybe what I stated above wasn't clear, but my intention wasn't for you to combine the 2. I was thinking you could just have a script run on a trigger or periodic basis that would locate and remove the SSID in question. I don't know that I would do an EA output and a removal command in the same script myself. The reason is, once the echo command gets run, that gets captured, then uploaded along with other inventory data to the JSS as the result for the EA. Yet, right after the inventory collection you're removing the SSID from the Mac. So basically, you'll have Macs reporting that <WirelessSSID> is present on them, but you just removed it, so it will be inaccurate inventory. I'm not sure that's what you want.
If you wanted, you could reverse it all, like this.
#!/bin/sh
## Get the wireless port ID
WirelessPort=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')
## Run a SSID removal if its present
networksetup -removepreferredwirelessnetwork $WirelessPort <WirelessSSID> 2>/dev/null
## Collect new preferred wireless network inventory and send back to the JSS
PreferredNetworks=$(networksetup -listpreferredwirelessnetworks "$WirelessPort" | sed 's/^ //g')
echo "<result>$PreferredNetworks</result>"
This should first locate and remove the offending SSID, then collect inventory based on what the new preferred wireless network list is. If the -removepreferredwirelessnetwork command above was successful, the list should not include the <WirelessSSID> in the results.
Make sense?
As a result of this post, I ran
networksetup -listpreferredwirelessnetworks "en0"
via ARD on a bunch of our Macs and I found one MBP that had 105 saved SSIDs! Since there is no way to purge everything EXCEPT the company's SSID, I copied all the ones I wanted to delete and pasted them into an Excel spreadsheet and worked with it to create a separate
networksetup -removepreferredwirelessnetwork en0 <WirelessSSID>
for each and every SSID (minus the one I wanted to keep). I then saved that as a txt and massaged it some more to remove tabs and empty spaces, then pasted that into ARD to run on that one computer.
It's unfortunate that there's no easier way to clean them up without making the users local admins.
(I am unable to remove our company's SSID because it is controlled by an 802.1x profile. Deleting the SSID causes the 802.1x to really freak out and I found it next to impossible to rejoin the SSID with the computer cert manually. I ended up having to remove the 802.1x profile and re-adding it to fix the problem)
@mm2270 I am not sure that I am following 100% of all that. I did however make the change to the script and dropped the "sudo." My workflow is as follows: based on the preferred wireless network EA, create a smart computer group which looks for <WirelessSSID> that needs to be remove, run the below policy scoped to that group and have it run at recurring check-in and have it set to ongoing.

I understand that with your proposed workflow, there is one script and no need to specify a new EA and I fully understand the benefit of shortening this to what you have suggested. My question to you is this: will the smart computer group and scope work with this proposed procedure? I see that your script spits out the report of saved, preferred wireless networks once the one in question is removed (presumably as an EA, right?)
##Get the wireless port ID
WirelessPort=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')
##Run a SSID removal if its present
networksetup -removepreferredwirelessnetwork $WirelessPort <WirelessSSID> 2>/dev/null
##Collect new preferred wireless network inventory and send back to the JSS
PreferredNetworks=$(networksetup -listpreferredwirelessnetworks "$WirelessPort" | sed 's/^ //g')
echo "<result>$PreferredNetworks</result>"
@sepiemoini If you want to only scope the SSID removal to a Smart Group, then I suggest splitting the script up into 2 discrete scripts.
One would be the EA script, so its capturing the list of saved wireless entries:
#!/bin/sh
##Get the wireless port ID
WirelessPort=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')
##Collect new preferred wireless network inventory and send back to the JSS
PreferredNetworks=$(networksetup -listpreferredwirelessnetworks "$WirelessPort" | sed 's/^ //g')
echo "<result>$PreferredNetworks</result>"
Then create a Smart Group that would use a "Like" operator to gather any machines that have the specified SSID for removal in their results.
Create a policy that runs the following separate script on it:
#!/bin/sh
##Get the wireless port ID
WirelessPort=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')
##Run a SSID removal if its present
networksetup -removepreferredwirelessnetwork $WirelessPort <WirelessSSID> 2>/dev/null
And use the Smart Group you created before as its scope. Have it run on whatever frequency you want. Important to remember to gather new inventory after it all runs, so hopefully the preferred wireless list will no longer contain the offending SSID and the Mac will fall out of the Smart Group.
@mm2270 Perfect, that's exactly what I was attempting to do. I made a few modifications to the removal script --namely to remove the echo command that I was previously using--but believe this is good to go. Thanks!
@mm2270 brilliant! Let's say I wanted the script to look for any parameters in the policy present to use for multiple WirelessSSIDs. Can this be done?
That way I can easily add/remove SSIDs without going back into the script.
I'm trying to use this script to remove an undesired SSID from a static group (this is a one-time thing, don't really need the smart group/EA bit). I built a policy to run once and included the script, plus inventory update. In my test bed, the policy ran successfully, in that the SSID was removed, but the policy is stuck at "pending" and there is nothing in the logs to show it even ran. Any ideas appreciated.
Dan, is the policy dropping the network connection on the Macs when it removes the preferred wireless network? Guess what I'm asking or saying is, if the Mac is losing a network connection when it runs it will not be able to upload a log back to the JSS to know it ran. It's one of the things of how policies work. Basically the steps look like:
- Mac checks in with JSS to ask if there's anything it needs to run.
- JSS says "yes here are your instructions" and sends the info down to the Mac
- At that point, it's up to the local jamf binary to take over and execute the instructions
- Only at the end when the policy is "complete" does it send back a log saying "everything worked" or "there was a problem. Here are the notes"
If it never gets that log back it remains as Pending indefinitely in the JSS.
Is it possible that's the issue here?
Hmm. That's a good point, and it might be. I put the test box on a wired connection, and re-ran the policy and it worked. I'm not sure if it was on the SSID to be removed or not before it ran, but that might explain it. For the target population, that situation is very likely - in fact, that's the whole point, to get them off of it (and take it out of the remembered list). I'll play with it a bit more to see.
How do you do this step: "Then create a Smart Group that would use a "Like" operator to gather any machines that have the specified SSID for removal in their results." I can't figure out in the creation of the smart computer group how to specifically get the SSID as the criteria.
@kirk.magill Did you follow the instructions to set up an Extension Attribute that captures the SSDs on each Mac? If not, that needs to happen first before you can use it as criteria for a Smart Group.
Yep - did it wrong. I setup a script to run off a policy - which worked, but does not allow me to make the Smart Group. Thanks! @mm2270
I am having more troubles with this now. I am getting a response telling me "Script result: Network XXXX was not found in the preferred networks list.
Am I having a problem because my SSID has a space in the name? e.g. SSID Wifi ?
@kirk.magill Can you post the script you're using in its entirety? I'm guessing you just need to surround the SSID in double quotes to get around the issue, but it would help to see exactly what your version of the script looks like.
!/bin/sh
Get the wireless port ID
WirelessPort=$(networksetup -listallhardwareports | awk '/Wi-Fi|AirPort/{getline; print $NF}')
Run a SSID removal if its present
networksetup -removepreferredwirelessnetwork $WirelessPort <Sigourney Wifi> 2>/dev/null
"Sigourney Wifi" , the double quotes did it. Thanks again for the follow-up!