I wanted to be able to switch fast between different network configurations on my Windows development PC without using any kind of 3rd party software. So I had a quick look on Stackoverflow and found the beautiful wmi package. Windows Management Instrumentation (WMI) is Microsoft’s implementation of Web-Based Enterprise Management (WBEM), an industry initiative to provide a Common Information Model (CIM) for pretty much any information about a computer system. And the wmi package is a Python wrapper for it on top of pywin32.
So in the script below I use this wmi package to switch between different network
configurations (ip address, dhcp, subnetmask, gateway). The configurations are stored in
a dictionary and can be modified on demand. I wanted to be able to use the script from
the command line but keep the hassle low. So I decided to give
click a try. Click is a Python package for creating
beautiful command line interfaces in a composable way with as little code as necessary.
It’s the “Command Line Interface Creation Kit”. It’s highly configurable but comes with
sensible defaults out of the box. A great thing about click is that you can define
choices for your variables. The choices are displayed when you call python netset.py --help. I used this to allow only the names of my defined network configurations.
from collections import namedtuple
import time
import sys
import click
import wmi
TIMEOUT_SECONDS = 20
# static configuration
Config = namedtuple('Config', 'name dhcp ip subnetmask gateway')
configs = {
'dhcp': Config('dhcp', True, None, None, None),
'static': Config('static', False, '192.168.1.110', '255.255.255.0', '192.168.1.0')
}
nic_configs = wmi.WMI().Win32_NetworkAdapterConfiguration(IPEnabled=True)
nic = nic_configs[0]
def ip_address():
ip = nic.wmi_property('IPAddress')
return ip.value[0]
def subnetmask():
subnet = nic.wmi_property('IPSubnet')
return subnet.value[0]
def gateway():
gateway = nic.wmi_property('DefaultIPGateway')
return gateway.value[0]
def dhcp_enabled():
dhcp = nic.wmi_property('DHCPEnabled')
return dhcp.value
def config_active(config):
if config.dhcp:
return dhcp_enabled()
return (config.ip == ip_address() and
config.subnetmask == subnetmask() and
config.gateway == gateway())
@click.command()
@click.option('--config', type=click.Choice(configs.keys()))
def set_nic(config):
config_name = config
config = configs[config]
if config.dhcp:
nic.EnableDHCP()
else:
nic.EnableStatic(IPAddress=[config.ip],SubnetMask=[config.subnetmask])
nic.SetGateways(DefaultIPGateway=[config.gateway])
t0 = time.perf_counter()
while not abs(time.perf_counter() - t0) > TIMEOUT_SECONDS:
if config_active(config):
click.echo('Successfully changed config to {}.'.format(config_name))
break
time.sleep(1)
else:
click.echo('Timeout')
click.echo('IP: {ip}\nSubnetmask: {subnetmask}\n'
'Gateway: {gateway}'.format(
ip=ip_address(),
subnetmask=subnetmask(),
gateway=gateway()
))
if __name__ == '__main__':
set_nic()
So this small script certainly isn't the top of the line but it was written pretty fast
and serves me well.