Eric's Technical Outlet

Learning the hard way so you don't have to

Removing an Adapter’s Gateway Using PowerShell

While trying to improve operations and fix some bugs in the networking module in Corefig, I encountered something interesting. The new PowerShell commands (PowerShell 3.0 cmdlets found in Hyper-V Server 2012, Windows Server 2012, and Windows 8) don’t remove gateways from adapters in the way that we NETSH users are accustomed to. Strangely, it appears that some of the workarounds users found for 2008 R2 don’t work anymore.

Why It’s So Difficult

Usually when an IP address is entered, a gateway is included that matches the IP and subnet mask. However, gateways aren’t necessarily matched to anything except the adapter itself. An adapter can have an IP without any gateways or with multiple gateways. It can have multiple IPs with zero, one, or multiple gateways. Routing tables are built from the gateways that have been entered (as well as any that have been discovered). The lack of any one-to-one coupling between addresses and gateways, as well as the unique distinction of a “default” gateway that sets it apart from any others, are the underlying reasons that this isn’t as straightforward as we might wish it to be.

How To Do It

Remove-NetRoute -InterfaceAlias "Local Area Connection 42" -NextHop 192.168.0.1

-or, if you’re scripting and aren’t sure what the default gateway is:

Remove-NetRoute -InterfaceAlias "Local Area Connection 42" -DestinationPrefix 0.0.0.0/0

You’ll be asked to confirm it twice, once for the active store (what’s going on right now) and once for the persistent store (what is effected after a reboot). If you have any particular need, you can ignore one and not the other, for instance, if you need the gateway for the moment but won’t after a reboot.

This will not remove any other gateways on the adapter unless they are also generic gateways. Depending on your goal, this could be good or bad. There are a number of automatically generated routes that aid the adapter in communicating with its local subnet and sending broadcasts. The above command leaves those. If you want, you can leave off the -DestinationPrefix parameter and it will wipe them clean however you should be aware that if you aren’t going to subsequently replace the IP address with a new one, the adapter will lose the ability to communicate on its local subnet.

Scripting It

This next bit is right from what I’m planning to put into Corefig 1.1.

First, I get a PowerShell object that represents the adapter that the user is currently attempting to set:

$Adapter = Get-NetAdapter -InterfaceAlias $ListNetworkAdap.SelectedItem

Get-NetAdapter is the important command. With that, you have a variable you can pass to the next command (or through to netsh). In this example, I’ll be setting DHCP on the adapter. There is a similar command (not shown here) to apply a static IP using a different conditional execution path:

Remove-NetRoute -InterfaceAlias $Adapter.Name -Confirm $false

Corefig doesn’t check or care if the IP is being replaced or not. It removes any IPs that it finds and then either puts in all brand new addressing information or sets it to DHCP mode. Even if the user did nothing more than remove the gateway address and leave all other information the same, it treats it as though it were new information. This causes the system to automatically generate new routes. It also has the unfortunate side effect of removing any manually entered persistent routes. The tradeoff saves a substantial amount of error-prone conditional checks and complexity. Be aware of these considerations when building your own scripts.

What Else Works

You can remove the entire address:

Remove-NetIPAddress -InterfaceAlias "Local Area Connection 42" -IPAddress 10.10.10.50 -PrefixLength -DefaultGateway 10.10.10.1

If you don’t suppress confirmation (the above command doesn’t), you’ll notice that it invokes the Remove-NetRoute command. There is nothing at all wrong with this. The problem is more for scripting. If you miss the boat or a problem occurs removing the gateway while removing the IP, then you don’t really get another chance unless you push the IP back in. If a gateway isn’t removed for some reason, adding other addresses won’t overwrite the ones that are there.

When using NETSH, you can run:

netsh interface ipv4 set address name="Local Area Connection 42" source=dhcp

That will remove the default gateways. You should be able to run the command from PowerShell as is, but if you find you’re having troubles, you can call it from PowerShell scripts like this:

Invoke-Expression "netsh interface ipv4 set address name='Local Area Connection 42' source=dhcp"

or

Invoke-Expression ("netsh interface ipv4 set address name=""{0}"" source=dhcp" -f $Adapter)

If DHCP isn’t your thing, you can also use

netsh interface ipv4 set address name="Local Area Connection" address=10.10.10.50 mask=255.255.255.0 gateway=none

The nice thing about NETSH is that it cleans up the routing tables for you.

What Doesn’t Work

The things that most of us NETSH users have been trying to no avail involve using PowerShell commands that appear to approximate the NETSH commands. For instance, if you use NETSH to put an adapter in DHCP mode, it will clean off other IPs including the default gateway. That doesn’t work in PowerShell:

Remove-NetIPAddress -InterfaceAlias "Local Area Connection 42"

The above leaves you with an adapter that has no IP address, will go into DHCP mode, and will retain its gateway. During testing, I didn’t have access to a DHCP server that presents a gateway as part of its delivery, so it’s entirely possible that if a DHCP server is present that it will deliver a gateway that will override. That’s really not good enough, especially for a tool intended for public consumption like Corefig. It also leaves the probability that if an IP is ever manually set in the future that the potentially invalid gateway will still be there.

Similarly, the following leaves you in the same place:

Set-NetIPInterface -InterfaceAlias "Local Area Connection 42" -Dhcp Enabled

You’ll have an adapter trying to get a DHCP address but with a hard-coded default gateway.

Getting clever with Remove-NetIPAddress and New-NetIPAddress or Set-NetIPAddress won’t get you anywhere either:

Remove-NetIPAddress -InterfaceAlias "Local Area Connection 42"
New-NetIPAddress -InterfaceAlias "Local Area Connection 42" -IPAddress 10.10.10.50-PrefixLength 24

The above will leave you with the same default gateway you started with.

Let’s say you have an adapter with an IP of 10.10.10.50, a mask of 255.255.255.0, and a gateway of 10.10.10.1 and you want to move it into the 10.10.2.0/24 network. So, if you attempt the following:

Remove-NetIPAddress -InterfaceAlias "Local Area Connection 42"
New-NetIPAddress -InterfaceAlias "Local Area Connection 42" -IPAddress 10.10.2.50 -PrefixLength 24 -DefaultGateway 10.10.2.1

Guess what you get? You have an adapter with two gateways.

Conclusion

I’m tempted to continue using NETSH even if I have to invoke it from PowerShell. The basic reason is that it works the way I’m used to. The PowerShell commands are much more powerful and allow you to utilize gateway arrays in a way that NETSH struggles with. However, that’s really not very common utilization and we could just employ the ROUTE command if we want to get fancy with gateways. A lot of administrators haven’t even caught on that “default” in “default gateway” implies that others can be assigned to the same adapter. Few of the administrators that know that they can use multiple gateways actively put that knowledge to use. Most of them (including me) feel that it adds a layer of complexity that could be better addressed using a different solution in most cases. The only thing of importance here is that NETSH is deprecated. Start up NETSH in interactive mode on Server 2012 or Windows 8 (that means, just type “NETSH” and hit Enter). Then type “int” and hit Enter. Read the nice little warning. This message is telling you that there might not be a NETSH in .Next of the Windows operating systems.

Advertisements

4 responses to “Removing an Adapter’s Gateway Using PowerShell

  1. B September 2, 2015 at 7:33 am

    Thank you !!! great

    Like

  2. Yohann April 24, 2014 at 9:27 am

    A very special thanks to you, I have been looking this trouble for hours in my script and I never understood.
    Very good explanation.
    Again, thank you, from France

    Like

  3. Tom August 20, 2013 at 10:31 am

    Thank you, thank you, thank you. 3 hours looking for this in the weeds. Your explanation makes sense.

    Like

  4. bill April 14, 2013 at 12:06 am

    Thankyou for your knowledge the command in parenth*** has worked a treat (Remove-NetRoute -InterfaceAlias “Local Area Connection 42″ -NextHop 192.168.0.1) The boys at microsoft need to create cmdlet for this task specific. BTW I have spent the last 5 or so hours looking in the powershell help for this task, couldn’t find any direct solution.
    Thanks Again Bill

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: