Simplify

Keeping things simple

Add routes on VPN connect with Powershell and Task Scheduler

with 12 comments

At my company we use a Microsoft ISA server for our firewall/VPN server. To be able to access the servers at my company via VPN required me to do one of two things:

  1. Use default gateway of the remote network
  2. Add static routes each time I connect via VPN

Option number one has the drawback that in such a scenario all my traffic would be directed through the VPN connection. Since my company has a very restrictive security policy which allows me to access only a couple of servers (TFS, SQL server, …). That effectively means that when connected to the VPN I can not use the internet or any other network resource.

Option number two requires that you add each of the routes to the routing table every time you connect the VPN. This can not be done via a batch script since the IP of the gateway changes on each connect.

So I thought to my self that there should be a better way to do this. With some basic Googling I quickly came up with an elegant solution. The first step towards the solution was a piece found on this blog. The blog discribes the very same problem that I was facing and provides a simple Powershell script that handles the routes. This Powershell script although it does what is need efficiently didn’t completely satisfy me.

Why? Well simply because I lazy and don’t like having to click on a power shell script on the desktop every time I make a VPN connection.

Doing some more Googling brought me to a Technet page that described how to use the Windows Task Scheduler to trigger the Powershell script execution on each VPN connect. Modifying the snippet I created this command which is executed in the Powershell command prompt.

schtasks /create /F /TN "VPN Connection Update" /TR "Powershell.exe -NonInteractive -command C:\vpn.ps1" /SC ONEVENT /EC Application /MO " *[System[(Level=4 or Level=0) and (EventID=20225)]] and *[EventData[Data='VPN NAME']]"

In this command change the path to your script, and change the last part where it says VPN NAME to the name of your VPN connection. This will ensure that the Task scheduler executes your script only and only when you connect that specific VPN connection. The complete explanation of the settings in the command can be found on before mentioned Technet page.

So I was almost there with the solution but the script it self did not satisfy me because I had to add multiple route and ensure that the routes are not already existing. I modified the original script to this version.

# ---------------------------------------------------------------------------------------
# Initial version: http://www.webboise.com/windows-powershell-script-for-adding-ip-routes-across-a-vpn/
# by Chris @ 30.9.2008
# ---------------------------------------------------------------------------------------
# Modified version: https://simpleverse.wordpress.com/2010/10/06/add-routes-on-vpn-connect-with-powershell-and-task-scheduler
# by Luka Ferlež @ 6.10.2010
# ---------------------------------------------------------------------------------------
#
#
# Add IP routes across a VPN via a DHCP assigned IP address
#
# Configuration
# ---------------------------------------------------------------------------------------
# Route IP address
$ips = @("10.20.1.0", "10.20.100.0", "10.23.2.0")
# VPN connection IP
$vpnIP = "192.168.90."
# ---------------------------------------------------------------------------------------
#
# Get the IP address of the VPN connection
$vpnip = ipconfig | findstr $vpnIP
# ---------------------------------------------------------------------------------------
#
# If we don't have an IP address on the VPN, error and quit
if (!$vpnip) {
"You do not have an IP address on the VPN"
exit
}
# Trim any leading/trailing whitespace
$vpnip = $vpnip.Trim()
# ---------------------------------------------------------------------------------------
#
# Split the contents of $vpnip in to an array
$vpnip = $vpnip.Split(" ")
# ---------------------------------------------------------------------------------------
#
# Find out the depth of our IP address in the array
$bit = $vpnip.Length - 1
# ---------------------------------------------------------------------------------------
#
# Get out just our IP address on the VPN
$vpnip = $vpnip[$bit]
# ---------------------------------------------------------------------------------------
#
# Delete routes if existing
foreach($ip in $ips) {
$hasRoute = route print | findstr $ip
if($hasRoute) {
"Deleting route " + $ip
route delete $ip
}
}
# ---------------------------------------------------------------------------------------
#
# Add whatever routes we need
foreach($ip in $ips) {
"Adding route " + $ip
route add $ip MASK 255.255.255.0 $vpnip
}

This script allows you to simply add the necessary routes at the top of the script, and the script will process them, enjoy.

Written by Luka Ferlež

October 6, 2010 at 22:21

12 Responses

Subscribe to comments with RSS.

  1. Very cool solution. I happened across this from the track-back to my blog. (I’m a bad blogger and don’t post often.) Looks like I’ll update my script 🙂 Cheers!

    Chris

    October 6, 2010 at 22:39

  2. I prefer to have my DHCP set my routes via DHCP option 121. On this way, no additional scripting is needed on the client side. And no admin rights required at all.

    -Kai

    KaiWilke

    November 8, 2010 at 0:58

    • I agree.

      But in our current office setup I don’t have access to our corporate DHCP with which I could set up something like this.

      Also when working from your home network where the DHCP is your feature-limited router this is something what is difficult to achieve.

      Luka Ferlež

      November 8, 2010 at 23:50

      • Well you should consider two things to get it up in running in your environment.

        1.) Install the DHCP directly on your TMG/ISA/RRAS server. Configure the DHCP Scopes to reflect the RRAS IP address scopes (RRAS will still assign the IPs to your client with its own scope). After configure DHCP-Relay to forward the DHCP Option request to your localhost DHCP server. Add Option 121 to your localhost DHCP scope… DONE!

        2.) Your home network (router, etc. ) doesnt matter at all. The clients will connect to the DHCP over the VPN channel and is getting DHCP-Relayed to receive just the option 121 for “this” VPN connection. But you can add also other DHCP Options (e.g. DNS Domain, NetBIOS stuff, etc.) if needed.

        As you can see, just a simple configuration change is needed, but the results are priceless.

        HTH,

        -Kai

        KaiWilke

        November 9, 2010 at 10:31

  3. […] VPNに接続したときに自動でルーティングを書き換えたいというのはよくある要求だと思うのですが、日本語文献はなかなかない、もしくは環境ややり方が古いのですよね… 今回は、https://simpleverse.wordpress.com/2010/10/06/add-routes-on-vpn-connect-with-powershell-and-task-sched… をもとに設定します。 […]

  4. cool sir, thanks!

    Marcel

    January 14, 2012 at 12:51

  5. You can simplify VPN IP parsing …

    $vpnip = $vpnip.Trim()
    $vpnip = $vpnip.Split(” “)
    $bit = $vpnip.Length – 1
    $vpnip = $vpnip[$bit]

    … with just one line:

    $vpnip = $vpnip.trim().split(” “)[-1]

    Viliam Pucik

    April 13, 2013 at 22:24

  6. How do I check whether the VPN connectivity is up or down (Cisco Anyconnect) using automated scripts powershell and c++APIs ???
    Can anybody please help me to create a script so that i can login and logout to and from VPN??
    Thanks.

    bhoomi

    August 13, 2013 at 23:42

  7. I keep getting “The requested operation requires elevation.” when the script tries to execute “route add”. I tried setting the /RU option of schtask to “SYSTEM” but I get an error. Any ideas?

    aurum1369

    March 20, 2014 at 6:21

    • Solved my own issue. Run the scheduler command like this – PS must be started with Run as Administrator or you will get an error “Access denied”:

      schtasks /create /RU "SYSTEM" /NP /F /TN "Office VPN Connection Update" /TR "Powershell.exe -NonInteractive -command C:\Scripts\OfficeVPN.ps1 >C:\Temp\VPNroute.log" /SC ONEVENT /EC Application /MO " *[System[(Level=4 or Level=0) and (EventID=20225)]] and *[EventData[Data='Office VPN Connection']]"
      

      I also added a redirect of the command output to create a log for debugging purposes.

      aurum1369

      March 21, 2014 at 18:59


Leave a comment