Modern workstations often need to adapt to different network environments dynamically. The requirement to execute specific scripts when network conditions change - whether switching between WiFi networks, detecting new Ethernet connections, or noticing VPN activations - is common in enterprise environments.
Windows Approach
For Windows systems, we can leverage the built-in Task Scheduler with event triggers:
# PowerShell script to detect network changes
Register-EngineEvent -SourceIdentifier NetworkChange -Action {
$currentNetwork = Get-NetConnectionProfile
if ($currentNetwork.Name -eq "Office-WiFi") {
# Office network actions
Set-AudioDevice -Mute $true
Set-DnsClientServerAddress -InterfaceIndex $currentNetwork.InterfaceIndex -ServerAddresses ("192.168.1.1","8.8.8.8")
} else {
# Default actions
Set-AudioDevice -Mute $false
Set-DnsClientServerAddress -InterfaceIndex $currentNetwork.InterfaceIndex -ResetServerAddresses
}
}
Linux Implementation
On Linux systems, we can use NetworkManager's dispatcher scripts:
#!/bin/bash
# /etc/NetworkManager/dispatcher.d/99-network-actions
interface=$1
status=$2
case "$status" in
up)
SSID=$(iwgetid -r)
if [ "$SSID" = "Office-WiFi" ]; then
# Office network actions
amixer set Master mute
cp /etc/resolv.conf.office /etc/resolv.conf
systemctl restart cups
else
# Default actions
amixer set Master unmute
cp /etc/resolv.conf.home /etc/resolv.conf
fi
;;
esac
For a more portable solution, consider using Python with the psutil
library:
import psutil
import time
import subprocess
last_state = None
while True:
current_state = []
for nic, addrs in psutil.net_if_addrs().items():
if addrs and nic != 'lo':
current_state.append(nic)
if current_state != last_state:
print(f"Network change detected: {current_state}")
# Add your custom logic here
if 'eth0' in current_state:
subprocess.run(["pactl", "set-sink-mute", "0", "1"])
last_state = current_state
time.sleep(5)
For more sophisticated scenarios, you might want to:
- Incorporate multiple detection methods (SSID, IP range, gateway MAC)
- Implement proper logging for debugging
- Add error handling for temporary network flaps
- Consider security implications of automatic configuration changes
In corporate environments, you might want to package this as a proper service/daemon with:
- Configuration files for different network profiles
- Proper init/systemd integration
- User permission management
- Centralized monitoring capabilities
To run scripts automatically when network connections change, we need reliable detection mechanisms. Here are the most common approaches across different operating systems:
Windows Solution
On Windows, we can use PowerShell with WMI events to monitor network changes:
# PowerShell script to monitor network changes
Register-WmiEvent -Query "SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_NetworkAdapter' AND TargetInstance.NetConnectionStatus=2"
-Action {
# Your custom actions here
Write-Host "Network connection changed!"
# Example: Change DNS when connected to office network
if (Test-Connection -ComputerName "office-router" -Count 1 -Quiet) {
Set-DnsClientServerAddress -InterfaceIndex (Get-NetAdapter | Where-Object {$_.Status -eq "Up"}).ifIndex -ServerAddresses ("192.168.1.1","8.8.8.8")
}
}
Linux Solution
For Linux systems, NetworkManager's dispatcher scripts work well:
#!/bin/bash
# Save as /etc/NetworkManager/dispatcher.d/99-network-change
INTERFACE=$1
ACTION=$2
if [ "$ACTION" = "up" ]; then
# Check if connected to office WiFi
if [[ "$(iwgetid -r)" == "OfficeWiFi" ]]; then
# Mute system
amixer set Master mute
# Change DNS
nmcli con mod "$(iwgetid -r)" ipv4.dns "192.168.1.1,8.8.8.8"
# Restart network to apply changes
nmcli con up "$(iwgetid -r)"
fi
fi
To determine when you're on specific networks, consider these identification methods:
# Python example to detect network
import socket
import subprocess
def get_current_network():
try:
# For WiFi networks
if sys.platform == "linux":
return subprocess.check_output(["iwgetid", "-r"]).decode().strip()
elif sys.platform == "darwin":
return subprocess.check_output(["/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport", "-I"]).decode()
# For gateway-based detection (cross-platform)
gateway = socket.gethostbyname(socket.gethostname())
return gateway
except:
return None
For more complex scenarios, consider these approaches:
- NetworkManager's connection-specific hooks: Create scripts that run when specific connections activate
- systemd-networkd: Use .network files with ExecStartPost directives
- Third-party tools: Tools like NetWatcher (Windows) or ifplugd (Linux) can trigger scripts
Here's a comprehensive Python script that handles multiple office network scenarios:
import os
import platform
import time
def is_office_network():
# Implement your specific office network detection logic
return True # Replace with actual detection
def set_office_settings():
if platform.system() == "Linux":
os.system("amixer set Master mute")
os.system("nmcli con mod OfficeWiFi ipv4.dns '192.168.1.1'")
os.system("lpadmin -d 'Office_Printer'")
elif platform.system() == "Windows":
os.system('netsh interface ip set dns "Ethernet" static 192.168.1.1')
# Add Windows-specific commands here
def set_home_settings():
# Revert changes when not on office network
pass
while True:
if is_office_network():
set_office_settings()
else:
set_home_settings()
time.sleep(60) # Check every minute
For a more portable solution, this Python script uses psutil to monitor network changes:
import psutil
import time
last_state = None
def network_changed():
global last_state
current = psutil.net_if_stats()
if current != last_state:
last_state = current
return True
return False
while True:
if network_changed():
print("Network state changed!")
# Add your custom logic here
time.sleep(5)
When implementing network-triggered scripts:
- Always validate network conditions before making changes
- Implement proper error handling for network operations
- Consider adding authentication for sensitive operations
- Log all automated changes for audit purposes