September 15th, 2005

How Can I Use a Logon Script to Remove All Mapped Drives?

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I use a logon script to remove all mapped drives each time a user logs on?

— VS

SpacerHey, Scripting Guy! AnswerScript Center

Hey, VS. You know, we’re glad you specifically mentioned the term “logon script” in your question. Why? Well, one of the drawbacks to mapping and unmapping network drives is the fact that there are no WMI classes capable of performing these tasks; that means we have to rely on Windows Script Host to remove mapped network drives. WSH does the job just fine, but with one caveat: WSH can map and unmap drives only on the local computer. That can be a bit inconvenient, to say the least (there’s no straightforward way to run a script that unmaps drives on a remote machine), but in this case it doesn’t matter; that’s because logon scripts always run locally anyway.

So how do you remove all the mapped network drives on a computer? Here’s one way:

On Error Resume Next

Set objNetwork = CreateObject(“Wscript.Network”)

Set colDrives = objNetwork.EnumNetworkDrives

For i = 0 to colDrives.Count-1 Step 2 objNetwork.RemoveNetworkDrive colDrives.Item(i) Next

Yes, this is odd-looking code, but we’ll explain why it looks that way. First, though, let’s point out that the script starts off by creating an instance of the Wscript.Network object; we then call the EnumNetworkDrives method to return a collection of all the mapped network drives on a computer.

This is where the quirkiness of WSH’s mapped network drives collection manifests itself. Suppose you have three mapped drives on your computer (drives X, Y, and Z). The collection returned by EnumNetworkDrives will look something like this:

X:
\\atl-fs-01\share1
Y:
\\atl-fs-01\share2
Z:
\\atl-fs-01\share3

As you can see, each mapped drive actually has two entries in the collection. Take drive X, for example. The first item in the collection (item 0) is the drive letter for drive X: X:. The second item in the collection (item 1) is the UNC path to the shared folder on drive X: \\atl-fs-01\share1. One drive, but two entries in the mapped network drive collection. Each of the other drives also has two items in the collection, meaning our three mapped drives will result in a six-item collection, with items alternating between drive letter and UNC path.

That’s why we can’t use a simple For Each loop to loop through the items in the collection. In order to remove a network drive, we need to call the RemoveNetworkDrive method, passing the method the drive letter for the drive to be removed. If we looped through all the items in the collection, the first time through the loop we’d pass RemoveNetworkDrive the value X:. So far so good; we’d remove drive X. However, the second time through the loop we’d pass RemoveNetworkDrive the value \\atl-fs-01-share1. That’s not so good: there aren’t going to be any drives with a drive letter \\atl-fs-01-share1. Which, of course, means that you’re script is going to fail.

Which also means we need to figure out a way around this issue. To that end, we use a For Next loop, looping from 0 (the first item in a collection is always item 0) to the number of drives in the collection minus 1. (Why “minus 1? Well, in a three-item collection item numbers would be 0, 1, and 2. Because the first item is item 0, the last item will always be the total number of items minus 1; in this case, 3-1, or 2. If you have 100 items in the collection the last item will have an index number of 99, or 100-1.)

On top of that, we also need to skip every other item; instead of hitting items 0, 1, 2, 3, 4, 5, we want to hit only items 0, 2, and 4 (the items that contain drive letters). That’s what the Step 2 does; it tells VBScript to only hit every other item. (Step 1, the default value for a For Next loop, hits every item.) Setting the Step value to 2 ensures that we’ll pass only drive letters to the RemoveNetworkDrive method.

Now that we have a way of grabbing just the drive letters (bypassing the UNC paths), the rest is easy: to remove a network drive we simply use this line of code, with colDrives.Item(i) representing the drive letter for the current item in the collection:

objNetwork.RemoveNetworkDrive colDrives.Item(i)

With any luck (although we’re talking computers here; who needs luck when working with computers?) any and all of the mapped drives found on this machine will be removed.

Author

0 comments

Discussion are closed.