Friday, September 28, 2007

SNTT - Listing all the IP addresses for a computer

There are times you may want to know whether the current user is connected to your internal network. The really basic way is to just try opening a database. If it fails you know the user isn't connected. :-P But what if something else is going on and the server you try to connect to is down, or you decommission that server or you just want to make the code portable enough so it works in any environment?

The easy way to do this is to retrieve the local IP address. If it's in your range you know the computer is online. Most methods to get the local IP only give you the first one registered. This means if someone is connecting over a VPN the IP address you get won't tell you anything about access to the corporate network. You need to enumerate all the IP interfaces that are connected and figure out if one is connected to the LAN.

Now, how do you go about this? Well, you could go the low tech route and Shell("ipconfig /all > ip.txt") and then parse it. That's certainly doable, but then you have to make sure the user can write to the folder where you put the file, and be sure you clean it up. It gets messy. You could use Windows API calls, such as GetAdaptersInfo, but that doesn't tell you if the connection is actually active, just that an IP address is assigned (think disabled NIC's with static IP's), so then you need to add on a couple more API calls to verify whether each interface is enabled. Bleh.

Enter WMI. Microsoft started shipping Windows Management Instrumentation (WMI) with Windows 2000, and it's also in Windows XP. Alongside WMI is Windows Scripting Host (WSH), which is an object wrapper around a lot of really cool functionality that you had to delve into obscure API calls to get previously. Using WMI and WSH you can easily get all the adapters in a computer, determine if they are active, and know with certainty what the user is connected to.

Function GetIPAddress() As String

Dim nicSet As Variant
Dim strIPAddress As String

'must have error handler enabled, as all
'adapters do not return all information
On Error Resume Next

Set nicSet = GetObject("winmgmts:{impersonationLevel=impersonate}"). _
InstancesOf("Win32_NetworkAdapterConfiguration")

Forall nic In nicSet
If nic.IPEnabled Then
strIPAddress = nic.IPAddress(0)
If Left$(strIPAddress, 3) = "10." Or Left$(strIPAddress, 3) = "192" Then
GetIPAddress = strIPAddress
Exit Forall
End If
End If
End Forall

Set nicSet = Nothing
End Function


This LotusScript was converted to HTML using the ls2html routine,
provided by Julian Robichaux at nsftools.com.

3 comments:

  1. Very nice tip! MSDN is not organized very well, so what was the best resource you have found for learning more about WMI and WSH?

    ReplyDelete
  2. Corey, that's an excellent question. As you indicate, MSDN can be daunting to wade through. I have O'Reilly's VBScript book, which covers a bit of WMI. I also frequent the #visualbasic channel the EFnet IRC network, and there are some people there who are familiar with WMI and are willing to help with questions and at least point you in a direction (even if they do so with their middle finger). One channel operator even contributed to an MS Press title on WMI and WSH. If you visit the IRC channel just be sure you've at least made some attempt to solve the problem yourself first. They're pretty unforgiving of people who don't at least try to Google an answer. And that's actually the best bet: Google. Search for what you're trying to accomplish, throw in "WMI" as a search term, and you usually find some results.

    ReplyDelete
  3. Yeah, I loves me some WMI. Since I occasionally have to mess with the OS of about 4000 machines, WMI is my hero...

    ReplyDelete