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)