Skip to content

Instantly share code, notes, and snippets.

@haircut
Last active September 24, 2018 19:58
Show Gist options
  • Save haircut/b5d5bea915a58c9b61160c857e7a08a2 to your computer and use it in GitHub Desktop.
Save haircut/b5d5bea915a58c9b61160c857e7a08a2 to your computer and use it in GitHub Desktop.
Forget all saved SSIDs with whitelisting
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
Forget saved SSIDs with whitelisting
This script removes ALL saved SSIDs on a Mac except for those configured in a
whitelist – see SSID_WHITELIST variable below.
Thanks to @sepiemoini for suggestion of "MERGE_CURRENT_SSID" behavior
author: Matthew Warren
@haircut on #macadmins slack
created: 2018-04-20
modified: 2018-09-24
'''
import objc
import subprocess
from SystemConfiguration import SCNetworkInterfaceGetLocalizedDisplayName, \
SCNetworkInterfaceGetBSDName, \
SCNetworkInterfaceGetHardwareAddressString, \
SCNetworkInterfaceCopyAll
# SSIDs to skip and NOT remove
# NOTE: If you configure Wi-Fi via Configuration Profile you must exclude those
# configured SSIDs here. The `networksetup` binary does not care about
# your profiles!
SSID_WHITELIST = ['DoNotRemove', 'CorpWifi', 'onboarding']
# Merge currently-connected SSID into whitelist?
# If `True`, the SSID to which the device is currently connected will be merged
# into the whitelist and not removed from the preferred SSID list. This is
# is provided as an option in case you DO want to remove a particular SSID even
# if the device is currently connected. Set to `False` if you prefer the latter
# behavior.
MERGE_CURRENT_SSID = True
# Completion message
# This message is displayed in a dialog after non-whitelisted SSIDs are removed
COMPLETE_MSG = """
All non-institutional networks have been forgotten. You may need to reconnect
to your home network and re-enter its password.
"""
# Managed Mac?
# If False, the completion dialog will simply appear on screen
# If 'jamf', the Self Service application will come to the foreground and
# display the completion dialog
# If 'munki', the Managed Software Center application will come to the
# foreground and display the completion dialog
# examples:
# MANAGED = False
# MANAGED = 'jamf'
# MANAGED = 'munki'
MANAGED = 'jamf'
def getwifiinterface():
'''Returns the name of the wifi interface'''
network_interfaces = SCNetworkInterfaceCopyAll()
interfaces = {}
for interface in network_interfaces:
interfaces[SCNetworkInterfaceGetLocalizedDisplayName(interface)] = (
SCNetworkInterfaceGetBSDName(interface),
SCNetworkInterfaceGetHardwareAddressString(interface)
)
wifi_interface = None
try:
wifi_interface = interfaces['Wi-Fi'][0]
except KeyError:
pass
return wifi_interface
def get_current_ssid():
'''returns the current SSID'''
wifi_ssid = None
objc.loadBundle('CoreWLAN',
bundle_path='/System/Library/Frameworks/CoreWLAN.framework',
module_globals=globals())
wifi = CWInterface.interfaceNames()
if wifi:
for iname in wifi:
interface = CWInterface.interfaceWithName_(iname)
if interface:
try:
wifi_ssid = interface.ssid()
except AttributeError:
pass
return wifi_ssid
def getssids(interface):
'''Returns a list of saved SSIDs for the provided interface'''
cmd = ['networksetup', '-listpreferredwirelessnetworks', interface]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, _ = proc.communicate()
return [item.strip() for item in output.splitlines()[1:]]
def removessid(ssid, interface):
'''
Removes the passed ssid from the preferred SSID list on the passed
interface
'''
cmd = ['networksetup', '-removepreferredwirelessnetwork', interface, ssid]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, _ = proc.communicate()
return True if proc.returncode == 0 else False
def osascript(osastring):
'''Wrapper to run AppleScript commands'''
cmd = ['/usr/bin/osascript', '-e', osastring]
proc = subprocess.Popen(cmd, shell=False, bufsize=1,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(out, err) = proc.communicate()
if proc.returncode != 0:
print >> sys.stderr, 'Error: ', err
if out:
return str(out).decode('UTF-8').rstrip('\n')
def alertcomplete():
'''Alerts user process is complete'''
# determine which management app should display the completion dialog
if MANAGED == 'jamf':
mgmtapp = 'Self Service'
elif MANAGED == 'munki':
mgmtapp = 'Managed Software Center'
else:
mgmtapp = 'System Events'
# bring management app to foreground
osascript('tell application "%s" to activate' % mgmtapp)
# show dialog
cmd = ('tell application "%s" to display dialog "%s" buttons {"Okay"} '
'with icon note giving up after 120' % (mgmtapp, COMPLETE_MSG))
prompt = osascript(cmd)
def main():
'''Main'''
interface = getwifiinterface()
ssids = getssids(interface)
if MERGE_CURRENT_SSID:
current_ssid = get_current_ssid()
if current_ssid is not None:
if current_ssid not in SSID_WHITELIST:
SSID_WHITELIST.append(current_ssid)
for ssid in ssids:
if ssid not in SSID_WHITELIST:
if removessid(ssid, interface):
print "Removed SSID", ssid
else:
print "Unable to remove SSID", ssid
alertcomplete()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment