Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Scripting for multiple physical locations

Scripting for the Enterprise

Scripting for multiple physical locations

by  markdmac  Posted    (Edited  )
markdmac's Enterprise Ready Login Scripts
The Challenges of Multiple Locations

By Mark D. MacLachlan, The Spiders Parlor
http://www.thespidersparlor.com


This FAQ is designed to work as a supplement to the FAQ Implementing powerful and flexible login scripts! faq329-5798
Code written in [blue] blue [/blue]can be removed if you are incorporating the rest of the script as Add-In code for faq329-5798.

Supporting AD Login Scripts over multiple locations presents special challenges whether the environment is large or small. This FAQ will attempt

to shed some light on the subject and present some possible solutions to help administrators design for multiple locations.

Designing login scripts for multiple locations is indeed a challenge. There are many variables to consider.
*How many servers are there at the remote location?
*Does the remote location use DHCP?
*Does each local site use the same IP address scheme?
*Do your users just travel or do the workstations (laptops) travel too?
*Are your users separated in OUs?
*Are your computers named with a convention that includes a location identifier?
*Have you configured any environmental variables that can identify location?

As you can see, there is a lot to think about.

So what are some ways to go about locating where a user is located? As stated there are a lot of variables. For instance, you could check the

user's IP address if you use different subnets at each location. This has a few drawbacks though. First off if the NIC has ever been changed in the

PC (while you might thin that is not likely for a laptop it happens a lot with PCMCIA NICs) there will be registry entries for the old NICs. This can be

a little confusing when you perform a WMI query unless you also check for active connection state. If the PC is configured with multiple NICs or

multiple IP addresses, then things get truly confusing.

You could create a local variable and use that in your script, but this requires that you go to each PC to set it and doesn't fix the problem of a user

moving from one location to another.

It is possible to query the registry for the DHCP server that has issued an IP address, but once again there are limitations; if a user is using a static

IP they won't have anything in the registry.

OK, so now you are saying to yourself, "This is all good information to consider but I'm used to markdmac posting tons of scripts so how about

some code to get me to do what I need to!"

OK, so here is my solution. The majority of my customers (and Tek-Tips posters) seem to have one thing in common. They have a server at the

location for login performance, the server is usually configured as a DC. So we will work with that.

It is an easy matter to determine which server has authenticated your login.

Code:
[green]
'==========================================================================
'
' NAME: GetLogonServer.vbs
'
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL: http://www.thespidersparlor.com
' DATE  : 6/3/2005
'
' COMMENT: <comment>
'
'==========================================================================[/green]
[blue]Set WSHShell = CreateObject("Wscript.Shell")[/blue]
Set WSHProcess = WSHShell.Environment("Process")
[green]'Determine logon server[/green]
DomainLogonServer = WSHProcess("LogonServer")
[green]'Note: Results below will be \\Server[/green]
WScript.Echo "Login server is:"& DomainLogonServer


Simple enough right? OK, so you now know what server has authenticated you. So let's say you have three locations, Los Angeles, Phoenix and

Dallas with server names LASVR, PHXSVR,DALSVR respectively. You can use my standard login script and add a section that checks for

the login server just the same as I check for group memberships. Then based on login location you can map your printers and drives etc.

So let's build on the code above:

Code:
[green]
'==========================================================================
'
' NAME: GetLogonServer.vbs
'
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL: http://www.thespidersparlor.com
' DATE  : 6/3/2005
'
' COMMENT: <comment>
'
'==========================================================================[/green]
[blue]Set WSHShell = CreateObject("Wscript.Shell")[/blue]
Set WSHProcess = WSHShell.Environment("Process")
[green]'Determine logon server[/green]
DomainLogonServer = WSHProcess("LogonServer")
[green]'Note: Results will be in format \\Server[/green]

[green]'Now check for the value and map a drive[/green]
Select Case DomainLogonServer
	Case "\\LASVR"
		WSHNetwork.MapNetworkDrive "X:", "\\LASVR\executables",True
	Case "\\PHXSVR"
		WSHNetwork.MapNetworkDrive "X:", "\\PHXSVR\executables",True
	Case "\\DALSVR"
		WSHNetwork.MapNetworkDrive "X:", "\\DALSVR\executables",True

End Select

That is all it takes! Hopefully you agree this is a much simpler way of determining where a user is. Of course if your remote locations don't have a

DC you will need to fall back on the other methods discussed above.

So let's say you DON'T have a DC locally but each of your locations does use a unique IP Address scheme.

Well, it is possible to grab the IP address that has been handed out via DHCP and based on that you could take action. Here is an example:

Code:
[green]
'==========================================================================
'
' NAME: GetDHCPIPaddress.vbs
'
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL: http://www.thespidersparlor.com
' DATE  : 5/4/2005
'
' COMMENT: Determines current DHCP IP Address of computer
'          Assumes that there is only ONE active NIC.  
'==========================================================================[/green]
On Error Resume Next

Const HKEY_LOCAL_MACHINE = &H80000002
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &_
".\root\default:StdRegProv")

[blue]Set WSHShell = CreateObject("Wscript.Shell")[/blue]
strKeyPath = "SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys

For Each subkey In arrSubKeys

	DHCPAddress = WSHShell.RegRead("HKLM\" & strKeyPath & subkey & "\DhcpIPAddress")
	If DHCPAddress <> "0.0.0.0" And Left(DHCPAddress,3) <> "169" Then
		ActiveDHCPIPAddress = DHCPAddress	
	End If
Next

[green]'Now that we have the DHCP Address let's do something with it
[green]'Grab the left 10 digits to determine subnet (example 192.168.1. or 192.168.2.)[/green]
[green]'Modify the length as needed for your available subnets.[/green]

Select Case Left(ActiveDHCPIPAddress,10)
	Case "192.168.1."
		WSHNetwork.MapNetworkDrive "X:", "\\LASVR\executables",True
	Case "192.168.2."
		WSHNetwork.MapNetworkDrive "X:", "\\PHXSVR\executables",True
	Case "192.168.3."
		WSHNetwork.MapNetworkDrive "X:", "\\DALSVR\executables",True

End Select

Still with me here? Great, so let's take a look at one more situation. Suppose you have established a naming convention for your workstations.

Something like this:

PhxAcct01 Accounting user in Phoenix
LosIT01 IT admin in Los Angeles
DalHR04 Human Resources in Dallas

As you can see, the first three letters of the machine name identify the location. Well, this is easy enough to work with.

Code:
[blue]
Set WSHNetwork = CreateObject("WScript.Network")
strComputer = WSHNetwork.ComputerName[/blue]

Select Case Left(strComputer,3)
	Case "Los"
		WSHNetwork.MapNetworkDrive "X:", "\\LASVR\executables",True
	Case "Phx"
		WSHNetwork.MapNetworkDrive "X:", "\\PHXSVR\executables",True
	Case "Dal"
		WSHNetwork.MapNetworkDrive "X:", "\\DALSVR\executables",True

End Select

That's it. Hopefully one of these three solutions will work for you in your environment.

Since originally posting this FAQ, I have had a lot of questions about determining the users OU.

Let me state first off that I don't like this as a way of determining what to process. First off because OU structures will vary from company to company and results might vary. Second because OU paths might become very long and I really don't want to get emails saying this code does not work because someone has mistyped a long LDAP path. I also don't like this as a solution because it assumes that I will take the same action for this user no matter where they are physically located and that to me does not really fit the bill for what this FAQ hopes to accomplish which is to allow for multiple locations and make it possible to make DECISIONS based on current location.

OK, with my objections out in the open, here is the code you need to determine a user's OU. Once you have an OU you can use a Select Case statement to take action based on the OU just like I demo selecting the Group Memberships in FAQ Implementing powerful and flexible login scripts! FAQ329-5798.

Note that the Function used to get the distinguished name is also used in my Speach API Add-On, so you might not need to add that code and could instead just add the few lines used to return the OU once you have the Distinguished Name.
Code:
[green]
'==========================================================================
'
' NAME: <FindUserOU.vbs>
'
' AUTHOR: Mark D. MacLachlan , The Spider's Parlor
' URL: http://www.thespidersparlor.com
' DATE  : 6/25/2005
'
' COMMENT: Thanks go out to Tek-Tips user K0b3 for the
'          SearchDistinguishedName function.
'
'==========================================================================
' Code assumes you have already grabbed the user login name as UserString

'First grab the DistinguishedName[/green]
UserDN = SearchDistinguishedName(UserString)
[green]'Now bind to the user object[/green]
Set UserObj = GetObject("LDAP://" & UserDN)
[green]'Find the Relative Distinguished Name (RDN)[/green]
UserRDN = UserObj.Name
[green]'Subtract the length of the RDN plus one more for the comma
'You now have the full path to the users OU[/green]
UserOU = Right(UserDN,Len(UserDN)-Len(UserRDN)-1)
WScript.Echo UserOU


Public Function SearchDistinguishedName(ByVal vSAN)
[green]    ' Function:     SearchDistinguishedName
    ' Description:  Searches the DistinguishedName for a given SamAccountName
    ' Parameters:   ByVal vSAN - The SamAccountName to search
    ' Returns:      The DistinguishedName Name[/green]
    Dim oRootDSE, oConnection, oCommand, oRecordSet

    Set oRootDSE = GetObject("LDAP://rootDSE")
    Set oConnection = CreateObject("ADODB.Connection")
    oConnection.Open "Provider=ADsDSOObject;"
    Set oCommand = CreateObject("ADODB.Command")
    oCommand.ActiveConnection = oConnection
    oCommand.CommandText = "<LDAP://" & oRootDSE.get("defaultNamingContext") & _
        ">;(&(objectCategory=User)(samAccountName=" & vSAN & "));distinguishedName;subtree"
    Set oRecordSet = oCommand.Execute
    On Error Resume Next
    SearchDistinguishedName = oRecordSet.Fields("DistinguishedName")
    On Error GoTo 0
    oConnection.Close
    Set oRecordSet = Nothing
    Set oCommand = Nothing
    Set oConnection = Nothing
    Set oRootDSE = Nothing
End Function




Happy scripting!
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top