Hey, Scripting Guy! How Can I Map Drives Based on IP Address?

Hey, Scripting Guy! How Can I Map Drives Based on IP Address?

  • Comments 1
  • Likes

Hey, Scripting Guy! Question

Hey, Scripting Guy! I have been using your script that maps drives based on group membership, and it works just fine. However, I need to modify the script so that drive mappings are also based on the location of the computer (more specifically, on the computer IP address). For example, we have a remote site that uses an ISDN connection and I don’t want the drive mappings to happen across this link; instead I would like the drive mappings to go to a local server. How can I modify your script so that it uses both group membership and IP address when mapping drives?

-- BT

SpacerHey, Scripting Guy! AnswerScript Center

Hey, BT. Before we begin, we’d like to give a special Scripting Guys shout-out to our new friends at Microsoft, friends who have begun reading this column and are, quite literally, hanging on our every word. Welcome aboard, guys! We just hope that you won’t be too disappointed in today’s column; after all, today the Scripting Guys are all business, with none of our usual fluff and nonsense.

Oh, what the heck; we have time for one little joke, don’t we? A blonde, a brunette, and a redhead walk into a bar. “Hey, bartender,” says the blonde. “We’re three beautiful young girls forced to spend the night alone in a strange town. Can you recommend a good Internet search engine?”

”Why, Windows Live Search, of course,” replied the bartender. “It’s not only a good Internet search engine, it’s the only Internet search engine.”

OK, so maybe it’s not a particularly funny joke. But, then again, Microsoft people have their own, unique sense of humor.

As we Scripting Guys are reminded over and over again.

Besides, it’s time to get down to business. (Although, if we haven’t already done so, we should mention that Windows Live Search is not only a good Internet search engine, it’s the only Internet search engine. Or at least the only one you should care about.)

As BT noted, he’s been using a logon script (discussed in a previous column) as a way to map network drives based on a user’s membership in a particular Active Directory group. However, he now needs to add in an additional stipulation based on the computer’s IP address (or, to be a bit more precise, the third octet in the IP address). For example, if the user belongs to the Finance Users group and the computer’s IP address is 192.168.36.1 then a drive is mapped to \\atl-fs-01\finance. Otherwise, the drive is mapped to \\atl-fs-02\finance.

This, by the way, seems to be a fairly common question: we’ve gotten several emails over the past few weeks asking how drives can be mapped based on IP address. Today’s script should help answer those questions.

Note. We’ve also gotten several emails over the past few weeks asking if we could recommend a good Internet search engine. You bet we can: Windows Live Search.

Windows Live Search. It’s not only a good Internet search engine, it’s the only Internet search engine.

Editor’s Note: In the interest of full disclosure and total honesty, we will admit that Windows Live Search might not be the only Internet search engine. (We said might.) If it isn’t, well, just pretend it is.

So how can we help BT? Like this:

On Error Resume Next

Set objSysInfo = CreateObject("ADSystemInfo")
Set objNetwork = CreateObject("Wscript.Network")

strUserPath = "LDAP://" & objSysInfo.UserName
Set objUser = GetObject(strUserPath)

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")

For Each objItem in colItems
    For Each objAddress in objItem.IPAddress
        arrIPAddress = Split(objAddress, ".")
        If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then
            strAddress = arrIPAddress(2)
            Exit For
        End If
    Next
    Exit For
Next

For Each strGroup in objUser.MemberOf
    strGroupPath = "LDAP://" & strGroup
    Set objGroup = GetObject(strGroupPath)
    strGroupName = objGroup.CN

    Select Case strGroupName
        Case "Finance Users"
            If strAddress = 36 Then
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance"
                Exit For
            Else
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\finance"
                Exit For
            End If
        Case "Human Resource Users" 
            If strAddress = 36 Then
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\hr"
                Exit For
            Else
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\hr"
                Exit For
            End If
        Case "Manufacturing Users"
            If strAddress = 36 Then
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\manufacturing"
                Exit For
            Else
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\manufacturing"
                Exit For
            End If
        Case "Shipping and Receiving Users"
            If strAddress = 36 Then
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\shipping"
                Exit For
            Else
                objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\shipping"
                Exit For
            End If
    End Select
Next

By the way, don’t be deterred by the length of this script; it’s this long simply because we’ve included drive mapping code for 4 or 5 groups. As you’re about to see, much of this script is boilerplate: it can be copied and pasted, then turned into production-ready code simply by making an occasional tweak or two. (Like changing the group name and the network path.)

We start things out by creating instances of the ADSystemInfo and Wscript.Network objects; we’ll use ADSystemInfo to help us bind to the Active Directory user account for the local user, and we’ll use the Wscript.Network object to map the network drive. After creating the two objects we then construct the ADsPath for the logged-on user by using this line of code:

strUserPath = "LDAP://" & objSysInfo.UserName

And once we have the ADsPath we can then bind to the user account in Active Directory by executing this line of code:

Set objUser = GetObject(strUserPath)

Note. OK, admittedly, that’s a pretty cursory explanation of ADSystemInfo and what we can use it for. For more information, take a look at our previous column on mapping drives based on group membership.

Or, even better, use Windows Live Search and search the Internet for more information.

Windows Live Search. It’s not only a good – oh, right; we did say that already, didn’t we?

Our next step is to determine the IP address for the local computer, something which is a tad bit trickier than it might sound. (Why? Because computers can have multiple network adapters and/or multiple IP addresses.) To begin with, we use this block of code to connect to the WMI service on the local computer:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

And then we use this line of code to retrieve a collection of all the “real” network adapters installed on that computer:

Set colItems = objWMIService.ExecQuery _
    ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")

Note. What do we mean by “real” network adapters? Well, for better or worse (probably worse, to tell you the truth), the Win32_NetworkAdapterConfiguration class returns information about a whole host of virtual network adapters in additional to your real, live network adapters. Fortunately, we can weed out most of those phantom adapters by including a Where clause that limits returned data to those adapters where the IPEnabled property is True. Which is just exactly what we did.

That brings us to the following block of code:

For Each objItem in colItems
    For Each objAddress in objItem.IPAddress
        arrIPAddress = Split(objAddress, ".")
        If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then
            strAddress = arrIPAddress(2)
            Exit For
        End If
    Next
    Exit For
Next

What we’re doing here is setting up a For Each loop to loop through our collection of network adapters. We then immediately set up a second For Each loop, this one designed to loop through all the possible IP addresses for each adapter. (Because a single adapter can have more than one IP address, the IPAddress property stores information as an array.) Inside this second loop we use the Split function to split the first IP address on the period. If we have the IP address 192.168.1.2 that means we’ll end up with an array named arrIPAddress that contains the following items:

192

168

1

2

See how that works? Good. That means we’re ready to go on.

In order to ensure that we have a valid IP address, we next execute this line of code:

If arrIPAddress(0) <> 0 AND arrIPAddress(0) <> 169 Then

This simply makes sure that the first octet in the IP address (that is, item 0 in our array) is neither 0 nor 169. If the first octet is 0, then you’re probably looking at an adapter that has not had an IP address assigned to it; if the first octet is 169 then you’re looking at an adapter that is using an auto-assigned IP address. If neither of these conditions is True we’re going to assume that we have a valid IP address. With that in mind, we use the following line of code to assign item 2 in the array (the third octet in the IP address) to a variable named strAddress:

strAddress = arrIPAddress(2)

Note. Remember, the first item in an array has the index number 0 and the second item in an array has the index number 1. That’s why we reference arrIPAddress(2) when retrieving the value of the third octet; the third item in an array has the index number 2.

Once we have a valid address we then call the Exit For statement to exit our For Each loop. That means that we’re going to use the first valid IP address we find, even if a computer has multiple IP addresses assigned to it. (Which probably won’t cause too many problems; logon scripts are typically run against client machines, and client machines typically don’t have multiple IP addresses assigned to them.)

Now we’re ready to start looping through the collection of groups that the logged-on user belongs to, something we do using this line of code (the MemberOf attribute is a multi-valued attribute containing a list of all the groups the user is a member of):

For Each strGroup in objUser.MemberOf

What do we do inside this loop? Well, to begin with, for each group in the collection we use this block of code to bind to the group account in Active Directory and retrieve the value of the group’s CN (common name) attribute:

strGroupPath = "LDAP://" & strGroup
Set objGroup = GetObject(strGroupPath)
strGroupName = objGroup.CN

From there we set up a Select Case statement and start checking to see if the user is a member of a particular group. If he or she is, we then map drive X accordingly. For example:

Case "Finance Users"
    If strAddress = 36 Then
        objNetwork.MapNetworkDrive "X:", "\\atl-fs-01\finance"
        Exit For
    Else
        objNetwork.MapNetworkDrive "X:", "\\atl-fs-02\finance"
        Exit For
    End If

It shouldn’t be too hard to see what we’re doing here. We retrieve the name of the first group that the user belongs to and check to see if that group happens to be named Finance Users. If the group is named Finance Users, we then check to see if the third octet of our IP address is equal to 36; that’s what this line of code is for:

If strAddress = 36 Then

If the third octet is equal to 36 we then map drive X to \\atl-fs-01\finance; if the third octet is not equal to 36 then we map the drive to \\atl-fs-02\finance. In either case, once we’ve mapped drive X we then use the Exit For statement to exit our For Each loop; this will help prevent an error from occurring if a user happens to belong to more than one of the target groups. (Why would an error occur? Because we might try mapping drive X to \\atl-fs-01\shipping even though we’ve already mapped drive X to \\atl-fs-01\finance. That’s a no-no.)

Note. So suppose a user does belong to multiple groups; would it possible to map multiple drives, assigning an unused drive letter as needed? Yes, although, needless to say, that would require some additional work. We don’t have time to discuss that additional work today, but we can at least point you to another column that shows you how to determine the next available drive letter on a computer.

We hope that answers your question, BT. As for the Scripting Guys, it’s time to go search the Internet using Windows Live Search. Windows Live Search. It’s not only a good search engine, it’s – well, you can fill in the rest yourself. We’ve got searching to do!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • I know this is an old post but it was the first one on a Internet Search Engine!

    We use pretty much the exact same method for setting proper Proxy Script, list of favorites and home page.. But now with IP V6 in Win7 we need to disable IP V6 in order for the script to run properly. Is there a way to filter out IP V6 like you do with IPEnabled = True?

    Thanks Comquest