Learn about Windows PowerShell
Hey, Scripting Guy! How can I use a logon script to remove all mapped drives each time a user logs on?-- VS
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
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:
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:
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.
If a user connects to a network path and provides credentials there will be a mapping without a letter - causing the script to fail. The for/next loop should be modified as follows:
For i = 0 to colDrives.Count-1 Step 2
if colDrives.Item(i)>"" Then
objNetwork.RemoveNetworkDrive colDrives.Item(i) 'unmap by letter if it exists
objNetwork.RemoveNetworkDrive colDrives.Item(i+1) 'otherwise unmap by UNC
Thanks SO much for this script! You just saved me a ton of head scratching. It works great!