Ecco un pacchetto per configurare una rete Wi-Fi su Windows (con netsh), Linux (con nmcli) e MacOS (con networksetup).
Potrebbe essere notevolmente migliorato, ma così com'è, funziona sulla mia flotta
setup.py:
Codice: Seleziona tutto
# -*- coding: utf-8 -*-
from setuphelpers import *
import platform
# Wifi settings
wifi_ssid = r'MY-WIFI-NETWORK'
wifi_password = r'my-wifi-password'
hidden_ssid = False
# Globally enable verbose mode
all_verbose = False
def install():
if platform.system() == 'Windows':
set_wifi_profile_windows(ssid=wifi_ssid, password=wifi_password, hidden=hidden_ssid, verbose=all_verbose)
elif platform.system() == 'Darwin':
set_wifi_profile_macos(ssid=wifi_ssid, password=wifi_password, verbose=all_verbose)
elif platform.system() == 'Linux':
set_wifi_profile_linux(ssid=wifi_ssid, password=wifi_password, hidden=hidden_ssid, verbose=all_verbose)
else:
error('Operating System not supported !')
def uninstall():
if platform.system() == 'Windows':
remove_wifi_profile_windows(ssid=wifi_ssid, verbose=all_verbose)
elif platform.system() == 'Darwin':
remove_wifi_profile_macos(ssid=wifi_ssid, verbose=all_verbose)
elif platform.system() == 'Linux':
remove_wifi_profile_linux(ssid=wifi_ssid, verbose=all_verbose)
else:
error('Operating System not supported !')
#### MACOS WIFI FUNCTIONS
def set_wifi_profile_macos(ssid, password, verbose=False):
r"""Configure and apply WIFI profile on MacOS using networksetup
Args:
ssid: network SSID to connect
password: wifi pre-shared key
verbose: if set to True, display commands used (default: False)
Notes:
- networksetup does not care about hidden network, this method works in all cases
- networksetup does not care about authentication and encryption modes, it always use the most secure option possible
- the configured SSID will be set to connect automatically by default
For more informations see https://www.hexnode.com/mobile-device-management/help/scripts-to-manage-wi-fi-network-settings-on-macos-devices/
"""
# Remove existings profiles first
remove_wifi_profile_macos(ssid, verbose=verbose)
time.sleep(2)
print(r'Creating or updating WLAN profile %s...' % ssid)
cmd = r'sudo networksetup -setairportnetwork en0 %s %s' % (ssid, password)
if verbose:
print(r'Command used: %s' % cmd)
run(cmd)
def remove_wifi_profile_macos(ssid, verbose=False):
r"""Remove WIFI profile if exists on MacOS using networksetup
Args:
ssid: profile SSID to remove
verbose: if set to True, display command used
"""
print(r'Removing WLAN profile %s if exists...' % ssid)
# Note: WIFI stay connected after removal but can't reconnect after reboot or disconnection
cmd = r'sudo networksetup -removepreferredwirelessnetwork en0 %s ' % ssid
if verbose:
print(r'Command used: %s' % cmd)
run_notfatal(cmd)
#### WINDOWS FUNCTIONS
def set_wifi_profile_windows(ssid, password, authentication_mode="WPA2PSK", encryption_mode="AES", connection_mode="auto", hidden=False, verbose=False):
r"""Configure and apply WIFI profile on Windows using netsh
Args:
ssid: network SSID to connect
password: wifi pre-shared key
authentication_mode: authentication method to use for connection (default: WPA2PSK)
encryption_mode: encryption type to use for connection (default: AES)
connection_mode: wether to enable wifi automatic connection, can be 'auto' or 'manual' (default: auto)
hidden: if set to True, configure a hidden network (default: False)
verbose: if set to True, display generated XML and commands used (default: False)
For more informations see https://learn.microsoft.com/fr-fr/uwp/schemas/mobilebroadbandschema/wlan/schema-root
"""
import tempfile
if connection_mode not in ("auto", "manuel"):
error("Error: connection_mode can be 'auto' or 'manual' only !")
xml_template = """<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>{tmpl_ssid}</name>
<SSIDConfig>
<SSID>
<name>{tmpl_ssid}</name>
</SSID>
<nonBroadcast>{tmpl_hidden}</nonBroadcast>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>{tmpl_connection_mode}</connectionMode>
<MSM>
<security>
<authEncryption>
<authentication>{tmpl_authentication_mode}</authentication>
<encryption>{tmpl_encryption_mode}</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>passPhrase</keyType>
<protected>false</protected>
<keyMaterial>{tmpl_password}</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>"""
if hidden:
hidden_value = r'true'
else:
hidden_value = r'false'
# Replace variables in template
xml_data = xml_template.format(
tmpl_ssid = ssid,
tmpl_hidden = hidden_value,
tmpl_connection_mode = connection_mode,
tmpl_authentication_mode = authentication_mode,
tmpl_encryption_mode = encryption_mode,
tmpl_password = password
)
# Remove existings profiles first
remove_wifi_profile_windows(ssid, verbose=verbose)
time.sleep(2)
# Use try/finally to ensure XML file is always deleted
try:
# Use temporary file
with tempfile.NamedTemporaryFile(mode="w+", suffix=".xml", delete=False, encoding="utf-8") as tmpfile:
tmpfile.write(xml_data)
tmpfile.flush() # force write on disk
xml_file = tmpfile.name
if verbose:
tmpfile.seek(0)
print("XML content:\n%s" % tmpfile.read())
print(r'Creating or updating WLAN profile %s...' % ssid)
cmd = r'netsh wlan add profile filename=%s user=all' % xml_file
if verbose:
print(r'Command used: %s' % cmd)
run(cmd)
finally:
remove_file(xml_file)
def remove_wifi_profile_windows(ssid, verbose=False):
r"""Remove WIFI profile if exists on Windows using netsh
Args:
ssid: profile SSID to remove
verbose: if set to True, display command used
"""
print(r'Removing WLAN profile %s if exists...' % ssid)
cmd = r'netsh wlan delete profile name= %s' % ssid
if verbose:
print(r'Command used: %s' % cmd)
run_notfatal(cmd)
#### LINUX FUNCTIONS
def set_wifi_profile_linux(ssid, password, hidden=False, verbose=False):
r"""Configure and apply WIFI profile on Linux using nmcli
Args:
ssid: network SSID to connect
password: wifi pre-shared key
hidden: if set to True, configure a hidden network (default: False)
verbose: if set to True, display commands used (default: False)
Note:
- nmcli does not care about authentication and encryption modes, it always use the most secure option possible
- the configured SSID will be set to connect automatically by default
For more informations see https://networkmanager.dev/docs/api/latest/nmcli.html
"""
if hidden:
hidden_value = r'yes'
else:
hidden_value = r'no'
print(r'Creating or updating WLAN profile %s...' % ssid)
# Remove existings profiles first
remove_wifi_profile_linux(ssid, verbose=verbose)
time.sleep(2)
# Get interface name
cmd = "nmcli d | grep wifi | grep -v p2p | awk \'{print $1}\'"
if verbose:
print(r'Getting wifi interface name with command: %s' % cmd)
ifname = run(cmd).strip()
if ifname == "":
error(r'Error getting wifi interface name !')
# Add connection
cmd = r'nmcli con add type wifi con-name %s ssid "%s" ifname %s' % (ssid, ssid, ifname)
if verbose:
print(r'Creating wifi connection with command: %s' % cmd)
run(cmd)
# Try to connect (sometimes nmcli needs time to be able to interact with previously created connection)
cmd = r'nmcli dev wifi con "%s" name "%s" password "%s" hidden %s' % (ssid, ssid, password, hidden_value)
if verbose:
print(r'Connecting to wifi network with command: %s' % cmd)
try_nb = 12
sleep_duration = 5
for i in range(1, try_nb):
time.sleep(sleep_duration)
try:
print(r'Trying to connect... %s/%s ' % (i, try_nb), end="")
run(cmd)
except:
print(r'FAILED')
continue
else:
print(r'SUCCESS')
return True
error(r'Error: cannot connect to wifi network %s after %s attempts !' % (ssid, try_nb))
def remove_wifi_profile_linux(ssid, verbose=False):
r"""Remove WIFI profile if exists on Linux using nmcli
Args:
ssid: profile SSID to remove
verbose: if set to True, display command used
"""
print(r'Removing WLAN profile %s if exists...' % ssid)
cmds = [r'nmcli con delete "%s" ' % ssid,
r'nmcli con delete "Auto %s" ' % ssid] # Linux Mint create a "Auto <SSID>" connection when configured through GUI, ensure it's deleted too
if verbose:
print(r'Commands used: %s' % cmds)
for cmd in cmds:
run_notfatal(cmd)
