Determine Active Directory site of a given IP address

R

Rob Willis

Does anyone know if it is possible to determine in script what the
Active Directory site of a given IP address is? This is not the IP
address of the current machine - I know I can use ADSystemInfo to get
that - it is the IP address of a remote machine, and the remote
machine may or may not be running an AD aware OS, and may not even be
turned on. I just want a script that takes an IP address as input,
queries AD, and returns the AD site that IP address belongs to. If I
can't do this in script, what about VB?

Ideas gratefully received...
Rob
 
W

Wayne Tilton

(e-mail address removed) (Rob Willis) wrote in
Does anyone know if it is possible to determine in script what the
Active Directory site of a given IP address is? This is not the IP
address of the current machine - I know I can use ADSystemInfo to get
that - it is the IP address of a remote machine, and the remote
machine may or may not be running an AD aware OS, and may not even be
turned on. I just want a script that takes an IP address as input,
queries AD, and returns the AD site that IP address belongs to. If I
can't do this in script, what about VB?

Ideas gratefully received...
Rob

There is a .NET API to do this called DsAddressToSiteNames, if you're
willing to wade into those waters. If not, I've just posted a VBScript
example to http://cwashington.netreach.net/ that does it using brute
force. The script converts the IP address to decimal and then reads all
the Subnet objects out of the Configuration container, calculates the
starting and ending addresses in each subnet and compares them against
the IP address. It should show up on Clarence's site in a few days, if
you need something before than, I can post it to the group.

Wayne
 
R

Rob Willis

Wayne Tilton said:
(e-mail address removed) (Rob Willis) wrote in


There is a .NET API to do this called DsAddressToSiteNames, if you're
willing to wade into those waters. If not, I've just posted a VBScript
example to http://cwashington.netreach.net/ that does it using brute
force. The script converts the IP address to decimal and then reads all
the Subnet objects out of the Configuration container, calculates the
starting and ending addresses in each subnet and compares them against
the IP address. It should show up on Clarence's site in a few days, if
you need something before than, I can post it to the group.

Wayne

Wayne,

Thanks - that's great! Could you please post the script to the list -
I'd really like to try this out soon. One question - does your script
deal with "catchall" type subnet definitions? For example, we have
subnet definitions for entire class B networks for a site, with other
subnets within that class B defined as a class C and a different site
- this prevents us from having to define every class C network in the
class B since most of them are at the same site.

Thanks again,
Rob
 
W

Wayne Tilton

(e-mail address removed) (Rob Willis) wrote in
Wayne,

Thanks - that's great! Could you please post the script to the list -
I'd really like to try this out soon. One question - does your script
deal with "catchall" type subnet definitions? For example, we have
subnet definitions for entire class B networks for a site, with other
subnets within that class B defined as a class C and a different site
- this prevents us from having to define every class C network in the
class B since most of them are at the same site.

Thanks again,
Rob

Rob,

The script correctly handles catchall subnets by finding the smallest
subnet object that contains the specified address. It also has 'Default-
First-Site-Name' hardcoded so it may display that site name even if it
doesn't exist (has been renamed).

This is going to wrap horribly so take care reconstructing it...

Wayne

IP2Site.vbs:
'------------------------------------------------------------------------
------'
' Displays the AD Site name for the supplied dotted decimal IP address.
'
'------------------------------------------------------------------------
------'
' IP2Site.vbs witten April 4, 2003 by Wayne Tilton
'------------------------------------------------------------------------
------'
Option Explicit

WScript.Echo SiteName(WScript.Arguments.Item(0))


Function SiteName(IPAddr)

Dim ConfigNameContext
Dim DecIPAddr, MaskBits, NumAddrs, LoIPAddr, HiIPAddr, SiteAddrs
Dim SubnetContainer, LDAPQry, Subnet
Dim AdConn, AdComm, AdRS

SiteName = "Default-First-Site-Name" ' Default site name if
no matches
DecIPAddr = Dot2Dec(IPAddr) ' Convert supplied
address to decimal

ConfigNameContext = GetObject("LDAP://RootDSE").Get
("configurationNamingContext")
SubnetContainer = "CN=Subnets,CN=Sites," & ConfigNameContext
LDAPQry = "<LDAP://" & SubnetContainer & ">;
(objectCategory=subnet);cn,siteObject"

Set AdConn = CreateObject("ADODB.Connection") ' Get an ADO connection
object

AdConn.Provider = "ADsDSOObject" ' Set provider name
AdConn.Open "Active Directory Provider" ' open connection

Set AdComm = CreateObject("ADODB.Command") ' Get an ADO command
object
Set AdComm.ActiveConnection = AdConn ' Tell command object
about connection
AdComm.Properties("SearchScope") = 2 ' we want to search
everything
AdComm.Properties("Page Size") = 500 ' and we want our
records in lots of 500

AdComm.CommandText = LDAPQry ' Set the ADO
CommandText
Set AdRS = AdComm.Execute ' and run the query.

SiteAddrs = (2^31)-1 ' Really big range
AdRS.MoveFirst ' Go to 1st record in
the set
While Not AdRS.EOF ' Read 'em until they're
gone
Subnet = AdRs.Fields("cn") ' Get subnet name
MaskBits = Split(Subnet,"/") ' Split IP addr from
subnet mask
NumAddrs = (2 ^ (32 - MaskBits(1))) - 1 ' Calc # addresses based
on subnet mask
LoIPAddr = Dot2Dec(MaskBits(0)) ' Get low end of IP
range in decimal
HiIPAddr = LoIPAddr + NumAddrs ' Calc high end of range
by adding # add
' Check to see if IP is within this subnet range and if so that
it's smallest subnet with that addr
If DecIPAddr => LoIPAddr And DecIPAddr <= HiIPAddr And NumAddrs <=
SiteAddrs then
SiteName = AdRs.Fields("siteObject")
SiteName = GetObject("LDAP://" & AdRs.Fields("siteObject")).Get
("name")
SiteAddrs = NumAddrs ' Remember # addrs in
this subnet
End If
AdRS.MoveNext ' Go to next record or
EOF
Wend

Set AdRs = Nothing
Set AdComm = Nothing
Set AdConn = Nothing
End Function

' Returns the decimal value of a dotted decimal IP address
Function Dot2Dec(IPAddress)
Dim Octets
Octets = Split(IPAddress,".")
Dot2Dec = (Octets(0)*(2^24)) + (Octets(1)*(2^16)) + (Octets(2)*(2^8))
+ Octets(3)
End Function
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top