Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I create a logon script that will open a user’s mapped drives?

-- KZ

SpacerHey, Scripting Guy! AnswerScript Center

Hey, KZ. You know, a lot of people think we decided to write this column because we wanted yet another way to tell people about scripting. That’s partially true; however, another reason there’s a Hey, Scripting Guy! column is because the Scripting Guy who writes the column has a habit of stumbling across little bits of trivia that he finds absolutely fascinating. The problem with that? No one else ever seems to be as fascinated as he is. And that’s really why he writes this column. In a face-to-face conversation people can sigh, roll their eyes, or spray him with Mace when he takes off on one of his boring tangents. In print, however, he can get away with boring people all he wants. (No; that’s true; haven’t you ever read anything by William Shakespeare?)

With that in mind, you probably know that, on the night that the Titanic sank, the band heroically played on, trying to calm and comfort the doomed passengers as best they could. But here’s something you might not have known. How did the White Star Line, owners of the Titanic, reward those musicians for their courage and their heroism? That’s right: by billing their surviving family members for the lost band uniforms! True story.

Did you hear that? It sounded like several thousand people sighing through the computer speakers. Weird.

Note. In case you’re wondering, no, Microsoft would never bill the Scripting Families for lost uniforms should the Scripting Guys be lost at sea. Granted we don’t actually wear uniforms, but they wouldn’t do that anyway.

Probably.

As a matter of fact, KZ, we do have plenty more anecdotes we could relate to you. But, on the off chance that someone has figured out a way to Mace daily columnists via the Internet, maybe we should take a moment to show you a script that can open a user’s mapped drives:

On Error Resume Next

strComputer = "."

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

Set colItems = objWMIService.ExecQuery("Select * From Win32_MappedLogicalDisk")

Set objShell = CreateObject("Wscript.Shell")

For Each objItem in colItems
    strDrive = objItem.DeviceID
    objShell.Run(strDrive)
Next

Let’s begin at the beginning. The very first line in the script is On Error Resume Next. Typically we don’t use any kind of error-handling in our sample scripts; that’s because we want to keep our scripts as short and sweet as possible (just like Greg). In this case, however, we decided to make an exception. We don’t know how it is in the rest of the world, but here at Microsoft networks occasionally go down, meaning that network resources (like mapped drives) aren’t always available. By using On Error Resume Next we keep the script from crashing should one of the user’s mapped drives not be available.

Good question: how do we even know which of the user’s drives are mapped drives? Let’s put it this way: if you’ve ever wondered what the WMI class Win32_MappedLogicalDisk is used for, well, now you know: this class returns a collection of all the mapped drives for the logged-on user. To get at this information all we have to do is connect to the WMI service on the local computer (because this is a logon script, we don’t care about connecting to remote computers) and then use this line of code to retrieve the collection of mapped drives:

Set colItems = objWMIService.ExecQuery("Select * From Win32_MappedLogicalDisk")

Pretty easy, huh?

Best of all, opening each of these drives is just as easy. What we’re going to do is open the drives exactly the same way we would open these drives from the Run dialog box. For example, to open drive Z: from the Run dialog box we’d simply type the following and then press ENTER:

Z:

We’re going to do the exact same thing here, only programmatically.

To do that, we first create an instance of the Wscript.Shell object; this is the scripting object that allows us to run executable files (like Explorer.exe) from within a script. We then set up a For Each loop that walks through the collection of mapped drives (we need to use a For Each loop regardless of whether the user has one mapped drive, 10 mapped drives, or even 0 mapped drives). Inside that loop we use this line of code to grab the DeviceID for each of these mapped drives; fortunately for us, the DeviceID just happens to be the drive letter for each mapped drive (e.g., Z:):

strDrive = objItem.DeviceID

Once we know the drive letter we can then use the Run method to open the mapped drive:

objShell.Run(strDrive)

That’s all we have to do. We then loop around and repeat the process with any other mapped drives in the collection.

Hmmm, that’s odd: the White Star Line just sent us a bill for that script, even though we were the ones who wrote the script.

Now here’s a bonus script for you, KZ. Depending on your setup, you might not want to open all the mapped drives associated with a user; instead, you might only want to open that user’s home drive (as configured in Active Directory). If that’s the case, here’s a script that will open just the home drive for the logged-on user:

On Error Resume Next

Set objShell = CreateObject("Wscript.Shell")

Set objSysInfo = CreateObject("ADSystemInfo")

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

strDrive =  objUser.homeDrive
objShell.Run(strDrive)

This time around we use the ADSystemInfo object, which provides basic information about the logged-on user and the computer he or she is logged on to. After we create the ADSystemInfo object we can then use this line of code to retrieve the user’s distinguished name (e.g., cn=Ken Myer, OU=Finance, dc=fabrikam, dc=com), a name we can get from the UserName property:

strUser = objSysInfo.UserName

With the distinguished name in hand we can then use the GetObject method to bind to the user account in question. At that point we simply need to retrieve the value of the homeDrive property and then, again, use the Run method to open the drive:

strDrive =  objUser.homeDrive
objShell.Run(strDrive)

And there you have it, KZ. Now, back to the amusing anecdotes. Although everyone has heard of Genghis Khan, most people aren’t aware that -

Oh; OK. Sorry, folks, but the White Star Line has said we’ve used up our quota of Web space for today. We’re afraid we won’t be able to tell you any more interesting little stories, at least not for now.

Note. Wow, a standing ovation; we didn’t know you could do that over the Internet. Thanks, guys! (Even if it was for the White Star Line and not us.)