Viele Dinge lassen sich wunderbar mit der Powershell automatisieren. So kann man beispielsweise auch die IP-Adresse eines Netzwerkadapters per Skript ändern. Dies könnte beispielsweise sinnvoll sein, wenn jemand sich in der manuellen IP-Konfiguration nur nach Anleitung zu Recht findet. Dann kann man ihm vorher die Powershell-Datei bereitstellen. Er braucht sie dann nur als Administrator starten und kann dadurch die Netzwerkadapter-Konfiguration ändern lassen. Leider gibt es bei der IP-Konfiguration per Powershell aber ein paar unschöne Fallstricke, über die ich gestolpert bin. Eine Anleitung findest du in diesem Artikel!
IP-Einstellungen ändern
Als erstes benötigt man den Adapter, den man konfigurieren will. Für meine Zwecke war es erst einmal ausreichend den aktiven Adapter mit Hilfe eines Filters zu ermitteln und das WMI-Objekt in eine Variable zu stecken:
1 2 |
# Suche aktiven Netzwerkadapter $adapter = Get-WMIObject Win32_NetworkAdapterConfiguration -filter IPenabled=true |
Ein kleines aber bedeutendes Problem tritt auf, wenn doch mehrere Adapter aktiv sind, von denen dann der falsche umkonfiguriert wird. Dies war z. B. immer dann der Fall, wenn sich ein Notebook in den StandBy-Modus verabschiedet hat und danach ein VPN-Adapter (von OpenVPN) blöderweise noch als aktiv gekennzeichnet war. Wenn dann das Netzwerkscript zum Einsatz kommt, kann es den falschen Adapter erwischen.
Dies lässt sich z. B. wie folgt filtern:
1 2 |
# Suche aktiven Netzwerkadapter $adapter = Get-WMIObject Win32_NetworkAdapterConfiguration -filter "description!='TAP-Windows Adapter V9' and IPenabled='true'" |
Entweder kann man, wie im obigen Beispiel, Adapter mit Hilfe der description ausschließen oder es nur auf einen Adapter anwenden. Letzteres kann problematisch sein, da ein LAN-Adapter oder WLAN-Adapter auf verschiedenen Computern nicht unbedingt den gleichen Namen bekommt. Wichtig ist, dass man mehrere Bedingungen mit den “ “ umgibt. Ansonsten funktioniert es nicht.
Nachdem der richtige Adapter gefunden wurde, lassen sich die Einstellungen des Netzwerkadapters (IP-Adresse, Subnetzmaske, DNS-Server, Gateway) über entsprechende Funktionen setzen. Dies wendet man auf die Variable mit dem WMI-Objekt an:
1 2 3 |
$adapter.EnableStatic($clientip, "255.255.255.0") $adapter.SetGateways($gatewaydnsip, 1) $adapter.SetDNSServerSearchOrder($gatewaydnsip) |
In diesem Beispiel kommen die zu setzenden IP-Adressen aus Variablen. Diese werden in meinem Skript an einer anderen Stelle festgelegt.
Möchte man stattdessen von einer statischen Konfiguration zu einer automatischen Konfiguration per DHCP wechseln, benötigt man folgenden Befehl:
1 |
$adapter.EnableDHCP() |
Problem
Vielen Nicht-Administratoren ist es wahrscheinlich gar nicht bewusst, aber man kann einem Adapter grundsätzlich mehr als ein Standardgateway zuweisen. Ebenso kann man ihm auch einen ganzen Haufen IP-Adressen zuweisen. Dies funktioniert auch über die GUI:
Bei der Konfiguration via Powershell gibt es aber einen wirklich unschönen Unterschied zur Konfiguration mittels des guten alten Tools „netsh“ oder über die GUI. Denn ein einmal gesetztes Standardgateway wird durch das Ändern der Adaptereinstellungen nicht wieder entfernt. Nicht einmal dann, wenn man den Adapter auf DHCP umschaltet! Der Befehl „EnableDHCP“ ist also nicht gleichbedeutend mit einem Klick auf „IP-Adressen automatisch beziehen“ in der GUI. Bei diesem wird der Eintrag für das Standardgatewy bekanntermaßen einfach geleert.
Stattdessen wird durch den Befehl „SetGateways“ immer nur ein Wert zu den vorhandenen Gateways hinzugefügt. Auch das Ausführen von „SetGateways()“ ohne Angabe von Parametern löscht bereits vorhandene Werte nicht aus der Konfiguration.
Lösung
Da sich Standardgateway nicht durch das Anlegen eines neuen Gateways ändern lässt, kam ich am Ende nur bei einer möglichen Lösung aus. Da das Gateway letzt endlich nur als die Default Route im System hinterlegt ist, schmeiße ich diese Default Route einfach weg:
1 |
Remove-NetRoute -DestinationPrefix 0.0.0.0/0 -Confirm:$false |
Mit diesem Befehl braucht man die als Standard-Gateway hinterlegte IP-Adresse nicht zu kennen um dieses los zu werden. Problematisch ist dies allerdings, wenn man mehrere Standardgateways nutzen möchte. Diese löscht man durch den Befehl allesamt und muss diese auch wieder neu anlegen.
Den Zusatz „confirm:$false“ benötigt man wenn man den Befehl innerhalb eines Skriptes nutzt. Denn es handelt sich um einen „Remove“-Befehl, bei welchen standardmäßig eine manuelle Nachfrage durch Powershell verlangt wird.