Thursday, August 30, 2012

Mapping Drives in Logon Scripts


It sure seems like there should be. Mapping drives for users has been a task IT has needed to do since the first network drive. Yet getting those drives correctly provisioned to users isn’t a task that’s come easily – even with today’s newer technologies like PowerShell and Group Policy Preferences. In fact, some of those newer technologies might even be more difficult than our old friend the net use command, depending on what you need to accomplish.
Considering how mapped drives exist in companies everywhere, you’d think a super-simple solution would exist right inside Windows itself. Without help from third-party solutions, you’ll be surprised to find that…well…there isn’t.
Let’s take a look, however, at what you can do. I’ll start by looking at some of the ways people have provisioned mapped drives to users in the past. I’ll bet the very first solution you found was inside each user’s object. Even back before Active Directory, each individual user could be assigned a single mapped drive as their “Home Directory” (now called “Home Folder”) in their user environment profile.
 
Figure 1: User profile.
You can see in Figure 1 how each user profile has a place to connect a single home drive. Home drives are great, and you probably use them for network storage of user data, but home drives aren’t enough when you’ve got additional network drives that need to get mapped. If you need to map two or more drives, you’ve got to look elsewhere for a solution.

Mapping the Drive

It’s for this reason why many people’s second approach to mapping drives is achieved through logon scripts. Logon scripts extended the single drive limitation of home drives frankly because they’re completely malleable. You can create a logon script to accomplish whatever tasks you want, as long as your scripting prowess can handle the task.
You’ve surely created or modified a logon script before. With batch scripting, creating a mapped drive requires just a single line:
net use S: \\server\shared\finance
VBScript requires only one additional line to accomplish the same thing:
Set objNetwork = CreateObject("WScript.Network")
objNetwork.MapNetworkDrive "S:" , "\\server\shared\finance"
PowerShell, everyone’s favorite new scripting language, brings us back to a single line, but oh what a line it is!
(New-Object -ComObject WScript.Network).MapNetworkDrive("S:", “\\Server\shared\finance”)
While each of these three languages indeed maps the drive you’re looking for, each has their own problems and limitations that limit how effective they really are.
Remember that in order to use any of these, you’ll first have to accomplish a few things. First, you’ll have to actually create that script you want to deploy. Your script will probably include additional configurations over and above any drive mappings. Maybe you’ll set a few environment variables or pop up a dialog box with an acceptable use statement. All of these extra things you’ll need to add into that script and test to your satisfaction before you can use it.

Installing the Logon Script

Once created, deploying the script to users most often happens as a function of Active Directory Group Policy. Because you want these scripts to run at Logon, you’ll typically need to configure them in the User Configuration | Policies | Windows Settings | Scripts (Logon/Logoff) | Logon section of whatever Organizational Unit you’re interested in. Figure 2 shows the console where you’ll add a non-PowerShell script.
 
Figure 2: Logon properties.
Adding your batch or .VBS file to this location only creates a pointer to your logon script. You’ve also got to upload the script itself into Active Directory’s replicated SYSVOL folder by clicking the Browse button after choosing to Edit the properties of the script.
You’ve absolutely got to be careful if you haven’t tooled around much with SYSVOL. Too much or the wrong kind of file manipulation in this location can have deleterious effects on your Active Directory. Even more challenging is the pathing that Active Directory uses to simply get you to the right location. My script needed to be uploaded to \\company.pri\SysVol\company.pri\Policies\{846E224F-25CF-4516-BAA0-57AA19533EC9}\User\Scripts\Logon. Your path will be similar, but with a different domain and another very different GUID in place of mine.
Once installed and replicated around your Active Directory, your users should start mapping their drives as soon as their computer picks up the new Group Policy Object.

Decisions in Mapping Drives – The “In the Script” Way

You’re probably having a minor “a-ha!” moment at this point. “Yes, Greg,” you might be thinking, “mapping a drive or two still isn’t that difficult a procedure, but my needs are more complex than just a simple mapped drive. I have some users who need some drives some of the time. I also have other users who need other drives, but only in certain circumstances. Mapping drives for me isn’t an all-or-nothing situation!”
Here’s where you’ll find the true challenges in scripting solutions for mapping drives. Indeed batch, VBScript, PowerShell, and even the non-Microsoft languages like KIX and others have built-in capabilities for creating conditional statements. But what if the entire concept of a conditional statement sends shivers up your spine. How are you to make decisions in your logon scripts if your decisions are more complex than are your abilities in scripting?
Let me help you out with some of those complex script routines that might scare you. It’s this kind of complexity that keeps many administrators in fear of scripting itself. That said, with what I show you, it is possible to make at least some decisions in your drive mapping logon scripts.
One of the easiest ways to get users to unique drives is by naming the drives after their username. This is easy because the variable %username% automatically maps to a user at the time of their logon. This means that with batch scripting you could potentially map a unique drive with:
net use S: \\server\shared\finance\%username%
This is great if you’re looking for mapped drives that relate to usernames. Also, any environment variable that’s native or otherwise present at the user’s desktop could be used to map a drive. %username% is always available, but as you can imagine it’s of limited use.
I’ll bet that what you’re looking for is somewhat different. Many admins instead want to assign drive mappings based on group membership. That’s a task that requires a bit more scripting. You can accomplish this in VBScript with a few additional lines:
Set objNetwork = CreateObject("WScript.Network")
Set objUser = CreateObject("ADSystemInfo")
Set objCurrentUser = GetObject("LDAP://" & objUser.UserName)
strGroup = LCase(Join(objCurrentUser.MemberOf))
If InStr(strGroup, lcase("Finance")) Then
objNetwork.MapNetworkDrive "R:", "\\server\shared\finance"
End If
At the point of logon, the script above takes a look through all the groups in which the user is a member. If that user is in the Finance group, then the script will map the R: drive to the \\server\shared\finance share. You can add additional mapped drives by adding more If-Then statements. This script checks for finance, accounting, and IT group membership, then maps the corresponding R:, S:, or T: drive.
Set objNetwork = CreateObject("WScript.Network")
Set objUser = CreateObject("ADSystemInfo")
Set objCurrentUser = GetObject("LDAP://" & objUser.UserName)
strGroup = LCase(Join(objCurrentUser.MemberOf))
If InStr(strGroup, lcase("Finance")) Then
objNetwork.MapNetworkDrive "R:", "\\server\shared\finance"
End If
If InStr(strGroup, lcase("Accounting")) Then
objNetwork.MapNetworkDrive "S:", "\\server\shared\accounting"
End If
If InStr(strGroup, lcase("IT")) Then
objNetwork.MapNetworkDrive "T:", "\\server\shared\IT"
End If
Both of these are neat little scripts, but they’re also not terribly scalable. If you’ve got only two or three different groups in your Active Directory that require attention, you can probably replicate this code a few times and accomplish what you need. But if you’ve got more than a few (and who doesn’t), you can imagine the level of complexity that scales as the size of the script grows. More importantly, as your number of mapped drives grows in number you can see how drives might begin conflicting with each other.

Decisions in Mapping Drives – The “How It’s Applied” Way

To combat these conflicting problems some scripters take a different tactic. Rather than adding the logic into the script directly, they create separate scripts that get applied based on the rules of Active Directory. This alternate way I’ll call the “how it’s applied” method rather than the “in the script” method.
Remember that any logon script can be applied based on the Organizational Unit of either the user or the computer. In the case of users, logon scripts are applied based on where in Active Directory a user’s account is located. If the user’s account is part of the Finance OU, you’ll assign their logon script to the Finance OU and know that they’ll get their assignments.
Scripts can also be assigned to OUs full of computers, even though such scripts are Startup and Shutdown scripts rather than Logon and Logoff scripts. In a perfect world, adding a startup script would allow drives to be mapped based on which computer the user is logging in. However, be aware that startup scripts don’t operate that way. A startup script runs as the computer “starts up”, before any user has attempted to login. Thus, you can’t easily use a startup script to map drives in this way, although other startup activities that aren’t user-centric are possible.
As you can imagine, this combination of users, computers, logons, and startups can immediately create a complex web of conditional statements. A user who is a member of multiple groups could have an overlap of drive letters. Different users logging into the same computer won’t get the same mapped drives. Chaos ensues!
 
Figure 3: Group Policy Preferences Item Level Targeting
By itself Active Directory deploys scripts based on that user’s or computer’s OU membership. You’ve got options based on user, or computer, but not necessarily both at the same time. Active Directory Group Policy Preferences get around some of these limitations through their use of Item Level Targeting, seen in Figure 3. There a Group Policy Preference that’s been targeted to a specific OU won’t actually be invocated unless the items resolve as true. In Figure 3, the drive mapping won’t be applied unless the user is a member of the Finance Users group. Remember that even Item Level Targeting is constrained by the OU where your configurations are located.

No comments:

Post a Comment