none
VBS script using WMI objects to get IP address of VPN PPTP connection RRS feed

  • Question

  • I have used the following statement for years in XP and it's worked great. But in Windows 7 64-bit, I'm not getting any IP information back.  First of all, I've browse the WMI in a gui browser and there is nothing on the PptpMiniport interface with any useful information.  IPEnabled is always false no matter if your connected to the vpn or not, and there is never any IPAddress value.  I'm a n00b to scripting, so hopefully we can find a way to do this with your help!

     

    Set colAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
    For Each objAdapter In colAdapters

        If InStr(objAdapter.IPAddress(0), PPTPNetwork) > 0 Then VPNIPAddress = objAdapter.IPAddress(0)
       
    Next

     

     

    Thanks!

     

    Troy Brown

     

    Wednesday, October 27, 2010 2:39 AM

Answers

  • Perhaps the script below will meet your needs. It runs the route command you specified and parses the output for the IP address.

    Option Explicit
    
    Dim objShell, strCmd, objExecObject, strLine, arrValues, strIP
    Dim objRegExp
    
    Set objShell = CreateObject("Wscript.Shell")
    
    strCmd = "%comspec% /c route print 10.10.10.0"
    
    ' Use regular expression to help parse command output.
    ' We need to replace all whitespace with a single space character.
    Set objRegExp = New RegExp
    objRegExp.Global = True
    objRegExp.Pattern = "\s+"
    
    ' Run the command.
    Set objExecObject = objShell.Exec(strCmd)
    
    ' Read the outpuot
    Do Until objExecObject.StdOut.AtEndOfStream
      strLine = objExecObject.StdOut.ReadLine()
      ' Look for the header line for active routes.
      If (InStr(strLine, "Network Destination") > 0) Then
        ' The IP address should be on the next line.
        strLine = Trim(objExecObject.StdOut.ReadLine())
        ' Replace all whitespace with a single space character.
        strLine = objRegExp.Replace(strLine, " ")
        ' The IP address should be the 4th value (delimited by single spaces).
        arrValues = Split(strLine)
        strIP = arrValues(3)
        Exit Do
      End If
    Loop
    
    Wscript.Echo "IP Address: " & strIP
    

     

    Richard Mueller


    MVP ADSI
    • Marked as answer by IamMred Tuesday, November 9, 2010 4:25 AM
    Monday, November 8, 2010 5:15 PM
    Moderator

All replies

  • Hello Troy,

    I'm running Windows 7 64-bit, and found several instances of Win32_NetworkAdapterConfiguration where IPEnabled was $true. Unfortunately I haven't got a VPN connection to test with, but I must at least ask .... are you using the native Windows VPN client, or a 3rd party piece of software that's creating a new virtual connection? It's possible that, if it's a 3rd party program (eg. Cisco, SonicWall, Juniper, etc.), that the virtual network adapter driver isn't properly reporting the IP information back to WMI. Just a thought ...

    Cheers,

    Trevor Sullivan
    http://trevorsullivan.net

    Wednesday, October 27, 2010 6:12 AM
    Moderator
  • I find that the Win32_NetworkAdapterConfiguration class works the same in 64-bit Windows 7. In Vista and above, the address can be IPv4 or IPv6. Your snippet doesn't indicate the value assigned to PPTPNetwork, but perhaps it is part of an IPv4 address and your machine only has IPv6 enabled. To troubleshoot you might have the code retrieve all addresses found in the array objItem.IPAddress. Perhaps:

    For Each objAdapter In colAdapters
      VPNIPAddress = Join(objItem.IPAddress, ",")  
    Next
    

    IPv4 addresses are similar to 172.16.22.8, but IPv6 address are similar to 2010:836B:4179::836B:4179.

    Richard Mueller


    MVP ADSI
    Wednesday, October 27, 2010 6:40 AM
    Moderator
  • Actually, there are two arrays, the array of adapters and the array of IP Addresses. You only check the first address in the array, objItem.IPAddress(0). Maybe this will work:

    For Each objAdapter In colAdapters
      For Each strIP In objItem.IPAddrss
        If (InStr(strIP, PPTPNetwork) > 0) Then
          VPNIPAddress = strIP
        End If
      Next
    Next
    
    Richard Mueller
    MVP ADSI
    Wednesday, October 27, 2010 7:00 AM
    Moderator
  • Thanks for the reply.  I am using the native Windows client, and I've tried it on multiple machines.  I have IPEnabled = True on several interfaces as well, but the miniports for the VPNs never change (or at least the pptp doesn't.  It's the only one I've tried)

     

    The PPTPNetwork variable is the first 3 octets of the expected IP.  But when I get the values I only have the physical IP addresses in the list and not the VPN.  It works perfectly on XP.

     

    Thanks again for any ideas.

     

    Troy

    Thursday, October 28, 2010 4:22 PM
  • Here is the full script for your reference:

     

    'The username for the VPN connection
    VPNUsername = "vpntest"
    
    'The password for the VPN connection
    VPNPassword = "vpntest"
    
    'In Windows, the name of the VPN connection as it is appears in Network Connections
    VPNConnection = "name"
    
    'The IP range that is provided to PPTP clients, without that last octet (this is used for matching purposes)
    PPTPNetwork = "10.10.10."
    
    'The route command that should be executed, without the gateway
    ' - route add *network* mask *netmask*
    RouteCommand = "route add 10.11.11.0 mask 255.255.254.0"
    
    '*********************************
    'Task: Establish Dialup Connection
    	
    Set Shell = CreateObject("WScript.Shell")
    Shell.Run "Rasdial " & VPNConnection & " " & VPNUsername & " " & VPNPassword, 6, True
    Set Shell = Nothing
    
    '*********************************
    'Task: Obtain *Correct* IP Address
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "!\\" & strComputer & "\root\cimv2")
    Set colAdapters = objWMIService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
    For Each objAdapter In colAdapters
    
    	If InStr(objAdapter.IPAddress(0), PPTPNetwork) > 0 Then VPNIPAddress = objAdapter.IPAddress(0)
    	
    Next
    	
    Set colAdapters = Nothing
    Set objWMIService = Nothing
    
    '*************************
    'Task: Add Route Statement
    
    Set Shell = CreateObject("WScript.Shell")
    Shell.Run RouteCommand & " " & VPNIPAddress, 6, True
    Shell.Run RouteCommand & " " & VPNIPAddress, 6, True
    Set Shell = Nothing
    
    

    Thursday, October 28, 2010 8:01 PM
  • I would suggest replacing your For Each/Next with the following:

    For Each objAdapter In colAdapters
      For Each strIP In objAdapter.IPAddress
        If (InStr(strIP, PPTPNetwork) > 0) Then
          VPNIPAddress = strIP
        End If
       Next
    Next
    

     

    I think I had typos when I suggested this earlier. The idea is that the address you are looking for may not be the first one in the array. Does this help?

    Richard Mueller


    MVP ADSI
    Friday, October 29, 2010 9:48 PM
    Moderator
  • Thanks for the script update.  I think it makes more sense, however the value is still coming up blank.  VPNIPAddress never gets a value.  When I look at all the values for IPAddress in a WMI GUI explorer, there is nothing there.  I see the arrays in some of the other interfaces.  I'm just afraid the pptp adapter in Win7 doesn't behave the same in the WMI as it did in XP.

     

    Please don't give up yet.

    Here's another idea.  I don't know much about screen scraping, but if I run the route command on the specific IP of the pptp server the assigned IP of the connection is displayed.  In this case the number I need assigned to VPNIPAdress is 192.168.210.101: 

    >route print 10.10.10.0

     

    ===========================================================================
    Interface List
     63...........................LCLS_Local
     23...00 24 d7 4c 68 79 ......Microsoft Virtual WiFi Miniport Adapter
     13...f0 de f1 16 43 bb ......Intel(R) 82577LM Gigabit Network Connection
     15...00 24 d7 4c 68 78 ......Intel(R) Centrino(R) Ultimate-N 6300 AGN
     17...00 23 c3 ce 75 28 ......Hamachi Network Interface
     19...00 50 56 c0 00 01 ......VMware Virtual Ethernet Adapter for VMnet1
     20...00 50 56 c0 00 08 ......VMware Virtual Ethernet Adapter for VMnet8
     28...08 00 27 00 88 13 ......VirtualBox Host-Only Ethernet Adapter
      1...........................Software Loopback Interface 1
     22...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter
     31...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #6
     14...00 00 00 00 00 00 00 e0 Microsoft 6to4 Adapter
     18...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #3
     16...00 00 00 00 00 00 00 e0 Teredo Tunneling Pseudo-Interface
     21...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #4
     29...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #2
     30...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #5
     34...00 00 00 00 00 00 00 e0 Microsoft 6to4 Adapter #2
    ===========================================================================

    IPv4 Route Table
    ===========================================================================
    Active Routes:
    Network Destination        Netmask          Gateway       Interface  Metric
        10.10.10.0    255.255.255.0     10.255.254.0  192.168.210.101     26
    ===========================================================================
    Persistent Routes:
      None

    IPv6 Route Table
    ===========================================================================
    Active Routes:
      None
    Persistent Routes:
      None

    Saturday, October 30, 2010 2:47 AM
  • Richard,

    You've been so much help already. Do you have any ideas on how to continue?

    Troy

    Wednesday, November 3, 2010 7:24 PM
  • Perhaps the script below will meet your needs. It runs the route command you specified and parses the output for the IP address.

    Option Explicit
    
    Dim objShell, strCmd, objExecObject, strLine, arrValues, strIP
    Dim objRegExp
    
    Set objShell = CreateObject("Wscript.Shell")
    
    strCmd = "%comspec% /c route print 10.10.10.0"
    
    ' Use regular expression to help parse command output.
    ' We need to replace all whitespace with a single space character.
    Set objRegExp = New RegExp
    objRegExp.Global = True
    objRegExp.Pattern = "\s+"
    
    ' Run the command.
    Set objExecObject = objShell.Exec(strCmd)
    
    ' Read the outpuot
    Do Until objExecObject.StdOut.AtEndOfStream
      strLine = objExecObject.StdOut.ReadLine()
      ' Look for the header line for active routes.
      If (InStr(strLine, "Network Destination") > 0) Then
        ' The IP address should be on the next line.
        strLine = Trim(objExecObject.StdOut.ReadLine())
        ' Replace all whitespace with a single space character.
        strLine = objRegExp.Replace(strLine, " ")
        ' The IP address should be the 4th value (delimited by single spaces).
        arrValues = Split(strLine)
        strIP = arrValues(3)
        Exit Do
      End If
    Loop
    
    Wscript.Echo "IP Address: " & strIP
    

     

    Richard Mueller


    MVP ADSI
    • Marked as answer by IamMred Tuesday, November 9, 2010 4:25 AM
    Monday, November 8, 2010 5:15 PM
    Moderator
  • Richard,

    You are a genius!  That worked beautifully!

     

    Troy

    Wednesday, November 10, 2010 8:58 PM
  • Enhancement on Richard's scripts - this version does not display a visible CMD console and makes different assumptions about the formatted output of the route command.  We use the script via BGInfo so do not require the "WScript." (context) specified on lines 12 and 46, if you're running this script raw then add "WScript." ahead of the CreateObject on 12 and the the Echo on 46.

    Dim ObjFSO, strTempFolder, strTemp, strTextLine, strIP, intMaxMetric, intMetric, arrValues

    ' Ask for temp file location and name
    Set ObjFSO = CreateObject("Scripting.FileSystemObject")
    strTemp = ObjFSO.GetSpecialFolder(2) & "\" & ObjFSO.GetTempName

    ' Direct output to a temp file (no command chell visible)
    WSHCmd = "%comspec% /c route print -4 0.0.0.0 2>&1 >" & strTemp

    ' If the script is used via BGInfo then drop `WScript` due to context
    ' Set WshShell = WScript.CreateObject("WScript.Shell")
    Set WshShell = CreateObject("WScript.Shell")
    return = WshShell.Run(WSHCmd, 0, true)

    ' Use regular expression to help parse command output.
    ' We need to replace all whitespace with a single space character.
    Set objRegExp = New RegExp
    objRegExp.Global = True
    objRegExp.Pattern = "\s+"

    ' Don't assume there is only one default g/w (MS VPN, dual LAN, etc), find the one with the lowest metric
    intMaxMetric = 32767
    ' Read our temp file line by line, doing regex replacement as we go
    Set objFile = objFSO.OpenTextFile(strTemp, 1)
    Do Until objFile.AtEndOfStream
     strTextLine = objRegExp.Replace(objFile.ReadLine, " ")
     ' Look for destination 0.0.0.0 and netmask 0.0.0.0 (i.e. default g/w)
     if InStr(strTextLine, "0.0.0.0 0.0.0.0") <> 0 then
      arrValues=split(strTextLine)
      ' Metric is "fifth" field in string
      intMetric = cint(arrValues(5)) 
      ' If this is the lowest metric so far in the table, record the i/f IP
      if intMetric < intMaxMetric then
       intMaxMetric = intMetric
       strIP = arrValues(4)
      end if
     end if
    Loop

    ' Close and remove the temp file
    objFile.close
    objFSO.DeleteFile strTemp

    ' If the script is used via BGInfo then drop `WScript` due to context
    'wscript.echo strIP
    echo strIP


    -- All opinions expressed here are my own and although they comply with my employers code of practice regarding the use of social media my employer cannot be held accountable for them --

    Monday, July 23, 2012 12:45 PM
  • It is much easier to do this with WMI so why does everyone parse a text file?

    Set wmi = GetObject("winmgmts:")
    'Set routes = wmi.ExecQuery("select * from Win32_IP4RouteTable where destination = '0.0.0.0'")
    Set routes = wmi.ExecQuery("select * from Win32_IP4RouteTable")
    WScript.Echo "Destination,Gateway,NetMask,Metric1"
    For Each r In routes
        WScript.Echo r.name,r.nexthop,r.mask,r.metric1
    Next


    ¯\_(ツ)_/¯

    Monday, July 23, 2012 4:27 PM
  • It is much easier to do this with WMI so why does everyone parse a text file?

    Perhaps because there is still a need to support pre-XP clients?

    In any case, this question is already marked as answered. If anyone needs help, please start a new thread; thanks.

    Bill

    Monday, July 23, 2012 4:30 PM
    Moderator