How do you dynamically change the proxy configuration on Windows laptop computers depending on network, all using PowerShell?

Determining if an IP address is within a range is quite cumbersome when you think about it in terms of programming…

Here was the problem we had to solve while migrating from a proxy solution:
Today, all managed computers (100’000+) that we have in our domain are using a proxy to gain access to the outside, there are 5 proxy servers split out by region (As an example: Europe, North America, Australia, Singapore, and China). These proxy servers are configured on the clients using our home grown computer management system which is backboned by PowerShell… we specify a configuration value on the computer and the agent that is installed on the computer assigns the proper proxy server to Internet Options. However, starting now, we are in the middle of rolling out default routes at all sites and that project will take about many months to complete….

The problem:

We can dynamically change the configuration value of all computers at a site in our system to “Disable Proxy” and Windows would just use the default route… easy, right?

Well, what happens when we assign that new value to 20 mobile laptops at one site and then those users travel to a different site that does not have the same solution in place? (a specified proxy is required) Well, the internet would not work for that computer… obviously 

So, our problem was, how do we dynamically change the proxy configuration on laptop computers depending on if that computer was located as a legacy proxy site or default route site, all using PowerShell?

Before implementing what we did…. we investigated a lot of options (like .pac files) but we needed something dynamic that could be changed on the fly.
The first solution we played with was we ended up getting the IP address on a computer and checking if it was in range of a list of networks on a distributed file share (UNC), this worked but it was very slow and the project did not want to list each network on a text file because there are dozens of networks at one location and that list would become massive over time. Remember, we are talking about 500+ sites in 60+ countries… we had to think big.

So, the solution we implemented and we are using today is kind of just combining a bunch of stuff we already knew. Here are the steps:

  1. Laptop computers grab a list of networks from a DFS – I will talk about what this looks like and how it is setup below
  2. PowerShell checks if their current IP address is within any network on that list – we do a lot of checking like (is the computer on VPN?, is the computer on a local network (home)?, etc. etc.) – this all happens client side
  3. Depending on the flow, the PowerShell script modifies the proxy settings and refreshes Internet Settings to instantly update computer – this is done in the user’s context since proxy settings are in HKCU.

The list of networks is maintained by a network administrator (from the rollout project) in a DFS, the text file looks something like this:
10.0.0.0/20#Site A LAN
10.60.20.0/23#Site B Wireless

Then the admin double clicks on a RunMe.cmd file that just calls a PowerShell script in the same directory to create the actual file that the computer grabs, which contains:
167772160..167776255#10.0.0.0/20#10.0.0.0-10.0.15.255#Site A LAN
171709440..171709951#10.60.20.0/23#10.60.20.0-10.60.21.255#Site B Wireless
(the PowerShell script that creates the script also copies the previous file into a backup folder in case of rollback purposes)

The first part of each line is the IP address’ span in decimal format, separated by “..” so that PowerShell treats that as an array. The rest of each line is just information, like the entered network, the actual span and the comment. We transport this information to the local client for logging purposes like “proxy disabled because it is in span XXX called XXX”

When the logon script runs, it fetches the file (if newer than the one it might already have) and does a check, as an example:
If ((Convert-IPAddressToDecimal $ipAddress) -in 171709440..171709951)
{
         #Do things
}

If you think of another solution, I would love to hear it…. Or if you want me to go into details or need the functions to convert IP Address’ let me know as well.

Tack!
/Matt

Visual Studio 2013 Cool Features!

Hey,

At work today we updated all development machines that myself and colleague use to Visual Studio 2013 (not really update but we installed it along side 2010). I must say, I was a huge skeptic of the new IDE but after using it for 8 hours today… I am a huge believer!

Why? Here are four features that I love:

1. User settings are now synced with your account you use with VS2013… this will save me a huge amounts of time. Why? Well my department is also in charge of evaluating, testing and preparing new models of computers in the environment and every year it seems someone comes to me and hands me a laptop and says “use this now”… I comply and roll my eyes knowing that I will spend the next business day setting it up to be perfect (I like everything to be in a particular way). Now… I will install VS2013 through a deployment machine (automated), I will fire it up and log on with my live account and boom…. all settings are synced. No more turning on line numbers or changing the VS theme to blue. Its all done for me   🙂

2. Code Peeking, at first I didn’t know about this one, but in the afternoon I was in a WebEx meeting with our Microsoft go to person and I was running through the code for Hyper-V 2012 R2 integration and was clicking on methods and hitting F12 to jump to it, like any programmer would do. All I heard on the phone was “No, no, no… Alt+F12 Matt!”… my mind was blown. It showed me the code while still being on the same page!

Code Peeking, awesome!!
Code Peeking, awesome!!

3. Not really a VS2013 feature but one of my favorites that came along, 64 bit Edit and Continue – If you are starting any new projects of have the possibility to convert an existing one to .NET Framework 4.5.1, I highly suggest you do so for the sole reason of debugging on the fly. Just like the 32 bit .NET applications, you can now debug the application and make changes while still debugging… no more error messages!!

vs2013_01

4. Code Map (this is only available in Visual Studio 2013 Ultimate), you ever wonder what code is talking to or linked together? Now you can right click and choose “Show on Code Map” and boom… A graph appears showing this exact information. I believe this was introduced in VS2012 but I never used that version (it was the Vista of Visual Studio, haha).

One word of warning though, do not go deleting or commenting out code just because it is not linked to something else. For example, WPF data binding does not show on Code Map… investigate the same way you would before before doing something stupid  🙂

vs2013_02

vs2013_03

Enjoy!

/Matt