Menu
Zero One Labs
  • Home
  • About
  • Scripts
  • Snippets
Zero One Labs

Wi-Fi persistence

Posted on August 13, 2019August 13, 2019 by Zan

I’ve noticed that sometimes I come home and my iMac has lost its connection to my Wi-Fi network. I’ve had enough, so I wrote a script (which I wrapped with a LaunchDaemon to keep it running), to check and make sure the Wi-Fi card is on and joined to my preferred network.

Caution: Use this script at your own risk. I coded this script to work in a very generic sense. The “sudo” commands below run as the super user, so please be cautious.

Prerequisites

Your Mac’s network preferences must have the named Wi-Fi network at the top of your preferred network names. For instance, if your preferred Wi-Fi network name was “GrandmasCookies”, then you need to go to your System Preferences app, then Network, highlight your Wi-Fi card, click the “Advanced” button (you may need to enter your admin credentials to unlock this section), and from the Wi-Fi tab, simply drag your preferred network to the top and make sure “Auto-Join” is selected (macOS Mojave and newer).

Copy the script below and save it to /usr/local/bin/wifi_persist.sh. Make sure the script is owned and readable by root.

#!/bin/bash
wifiNetwork="ENTER_YOUR_NETWORK_NAME_HERE"
# wifiNetwork - The exact name of the WiFi network you want to stay joined to.


wifiName="Wi-Fi"
# wifiName - The name of your WiFi device in System Preferences >  Network. You probably will not have to edit this line.


# Do not edit the script below. In fact, use this at your own risk.
wifiNicID="$(echo -e "open\nlist\nquit" | scutil | grep -E "Setup.*AirPort" | awk -F"/" '{print $4}')"
Network
wifiStatus="$(ifconfig "${wifiNicID}" | grep status | awk -F": " '{print $2}')"
# wifiStatus - will return "active" or "inactive"
wifiPower="$(networksetup -getairportpower "${wifiNicID}" | awk '{print $NF}')"
# wifiPower - will return "On" or "Off"
wifiCurNetwork="$(networksetup -getairportnetwork "${wifiNicID}" |awk '{print $NF}')"
# wifiCurNetwork - will return current Wi-Fi network Airport is joined
stateStat=0
theCount=0
if [[ "${1}" = "-v" ]];then
  echo "wifiNicID = $wifiNicID"
  echo "wifiNetwork = $wifiNetwork"
  echo "wifiStatus = $wifiStatus"
  echo "wifiPower = $wifiPower"
  echo "wifiCurNetwork = $wifiCurNetwork"
fi

if [[ ! "${wifiPower}" = "On" ]];then
	echo -n "Turning Wi-Fi on."
	networksetup -setairportpower "${wifiNicID}" On
	while [[ ! "${wifiPower}" = "On" ]];do
		sleep 1
		echo -n "."
		wifiPower="$(networksetup -getairportpower "${wifiNicID}" | awk '{print $NF}')"
	done
	echo
fi

if [[ ! "${wifiCurNetwork}" = "${wifiNetwork}" ]];then

	echo "Power-cycling the WiFi adapter.."
	networksetup -setairportpower "${wifiNicID}" Off
	sleep 5
	networksetup -setairportpower "${wifiNicID}" On
	echo -n "Waiting for WiFi adapter to join Wi-Fi network \""${wifiNetwork}"\"."
#	networksetup -setairportnetwork "${wifiNicID}" "${wifiNetwork}" # Will not work without plaintext password
	while [[ ! "${wifiCurNetwork}" = "${wifiNetwork}" ]];do
		sleep 1
		echo -n "."
		wifiCurNetwork="$(networksetup -getairportnetwork "${wifiNicID}" |awk '{print $NF}')"
		theCount=$((theCount + 1))
		if [[ $theCount -eq 59 ]];then
			echo "Something is taking too long. Exiting the script and letting it try again."
			break
		fi
	done
	if [[ "${wifiCurNetwork}" = "${wifiNetwork}" ]];then
		echo "Success. I am now on the Wi-Fi network \""${wifiNetwork}"\"."
		if [[ "${1}" = "-v" ]];then
			networksetup -getinfo "${wifiName}"
		fi
	else
		echo "There was an issue auto-joining the defined Wi-Fi network \""${wifiNetwork}"\". Please check to see that the defined network is set to the highest priority in your System Preferences app > Network."
		echo "Below is a list of preferred networks for the selected network interface."
		networksetup -listpreferredwirelessnetworks "${wifiNicID}"
		if [[ ! $(networksetup -listpreferredwirelessnetworks "${wifiNicID}" | grep -o "${wifiNetwork}") ]];then
			echo "As you can see, Wi-Fi network \""${wifiNetwork}"\" isn't on this list. Either you need to add this network to your preferred list, or there may be a spelling error. Or perhaps I misplaced a quotation mark in this script."
			echo "Anything is possible."
		fi
	fi
fi
if [[ "${1}" = "-v" ]];then
	echo "I hit the end."
fi
sleep 60
exit

After you’ve saved the script to your drive, run the following commands in Terminal:

sudo defaults write /Library/LaunchDaemons/org.zeroonelabs.wifi_persist.plist Label -string "org.zeroonelabs.wifi_persist"

#(this will create the launch daemon)

sudo defaults write /Library/LaunchDaemons/org.zeroonelabs.wifi_persist.plist ProgramArguments -array /usr/local/bin/wifi_persist.sh

#(this will tell it to run the script)

sudo defaults write /Library/LaunchDaemons/org.zeroonelabs.wifi_persist.plist KeepAlive -bool TRUE

#(this will tell the machine to keep running the script when it exits/closes, essentially looping it over endlessly - don't worry)

sudo launchctl load /Library/LaunchDaemons/org.zeroonelabs.wifi_persist.plist

#(this will load the launch daemon and run the script. when the script exits, it will pause for 60 seconds and run again)

  • bash
  • mac
  • wi-fi
  • Leave a Reply Cancel reply

    You must be logged in to post a comment.

    Login with your Social ID

    Categories

    • Articles
    • Bash
    • Mac
    • PackageMaker
    • Python
    • Scripts
    • Terminal
    • Uncategorized
    My LinkedIn
    ©2023 Zero One Labs | Powered by WordPress & Superb Themes