How to get a Mac to auto-reconnect to a wifi network?

Here is an Applescript and shell script to check if Airport is connected and if not to connect it.

if (do shell script "networksetup -getinfo Wi-Fi | grep -c 'IP address:'") = 1 then
    do shell script "networksetup -setairportnetwork en1 <networkName> <passwordToNetwork>"
end if
#!/bin/bash
if [ $(networksetup -getinfo Wi-Fi | grep -c 'IP address:') = '1' ]
then networksetup -setairportnetwork en1 <networkName> <passwordToNetwork>
fi

Replace <networkName> with the network's name and <passwordToNetwork> with its password. The "en1" should be correct if you have not changed your Network devices.

Now all you need to do is loop this or call it to check the connection.

Nevertheless airport should automatically reconnect if the connection is lost. Maybe try resetting all network preferences and see if that works.

How to completely reset your Network Preferences: Turn Airport off. Close System Preferences. Navigate to: /Library/Preferences/SystemConfiguration/ Make a copy, then delete the following files:

com.apple.airport.preferences.plist
com.apple.network.*
com.apple.smb.server.plist
NetworkInterfaces.plist

I'd like to comment on Kassym Dorsel's answer, but I don't have enough points to do so.

I had the same problem with my Mac server:

Wi-Fi connects to VPN and Ethernet to LAN, so if the Wi-Fi connection is lost, OS X doesn't automatically reconnect.

Considering Kassym Dorsel's answer:

  • I wasn't comfortable having my Wi-Fi password stored in the clear (admittedly it's an extremely low risk, but still).

  • I wanted it to enable Wi-Fi if it had been disabled.

  • I wanted it to handle the condition where a static IP address was assigned, Wi-Fi was enabled, but it was either still not connected or connected to the wrong Wi-Fi network (SSID).

So I modified his script to address these concerns (replace <networkName> with your preferred network SSID):

#!/bin/bash

# turn on Wi-Fi if it's turned 'Off'
if networksetup -getairportpower en1 | grep -q 'Off'
    then networksetup -setairportpower en1 on
fi

# cycle Wi-Fi power if missing 'IP address'
if [ $(networksetup -getinfo Wi-Fi | grep -c 'IP address:') = '1' ]
then
    networksetup -setairportpower en1 off
    networksetup -setairportpower en1 on
fi

# initiate connection if not connected to the correct network
if networksetup -getairportnetwork en1 | grep -q '<networkName>'
    then networksetup -setairportnetwork en1 '<networkName>'
fi

You might try to play with the airport utility (in newer OS X versions it's hidden away in /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport or a similar path).

Specifically, the JoinMode and JoinModeFallback preferences could be useful. On my machine, JoinModeFallback is set to DoNothing by default. Changing it to KeepLooking seems a promising start.

Run airport without arguments to see its help.