Programmatic Internet Connection Sharing



I have a Windows VM that can has an internet connection that acts as a tunnel into a VPN, and this VM is supposed to share this internet connection with the host. This works perfectly in principle: On that Windows VM, I have a network interface named `Outbound` which represents the VPN connection, and an interface named `Gateway` which represents the connection that is shared with the host. I use Windows Internet Connection Sharing (ICS) to provide routing to the `Gateway` interface via `Outbound`. For reasons unknown to me, however, this sometimes just breaks and the only way to get it running again is to simply disable ICS on the `Outbound` interface and re-enable it. Doing this through the UI every time became annoying, so I researched how to do it programmatically. There is [a great superuser answer](https://superuser.com/a/649183/222330) which provides _almost_ all the details you need, but not quite. <span id="more-5917"></span>Here's my current PowerShell code, which just does what I want: ``` regsvr32 /s hnetcfg.dll $net = New-Object -ComObject HNetCfg.HNetShare $net.EnumEveryConnection |% { $net.INetSharingConfigurationForINetConnection($_).DisableSharing() } $out = $net.EnumEveryConnection |? {$net.NetConnectionProps($_).Name -eq "Outbound"} $outConfig = $net.INetSharingConfigurationForINetConnection($out) $net = $net.EnumEveryConnection |? {$net.NetConnectionProps($_).Name -eq "Gateway"} $netConfig = $net.INetSharingConfigurationForINetConnection($net) $outConfig.EnableSharing(0) $netConfig.EnableSharing(1) ``` Specifically, the use of the `EnableSharing` method had alluded me for a while: If you want to provide routing to one _specific_ interface (i.e. `Gateway` in my case) then you have to call `EnableSharing(1)` on that interface while calling `EnableSharing(0)` on the one that provides the connection to be shared. One could argue that this makes sense in isolation since you can then have a many-to-many relationship between interfaces providing connectivity and interfaces being routed, but it is very confusing when compared to the user interface for this feature, where you can always only select a single interface to be routed for any connection that is to be shared. I found tons and tons of already existing code that does this, or even more, but I only found them after knowing all the right keywords. So, I am writing this blog post to add another piece of content out there, hoping that some pour soul with a similar problem may find it sooner than the rest. Cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *