Manage Network Drives with WSH Scripts
Use WshNetwork and FileSystemObject to list, map, and disconnect mapped drives
May 17, 2011
A Universal Naming Convention (UNC) path uniquely identifies a resource on a network. It describes the location of a volume, directory, or file, using the format \servervolumedirectoryfile. However, most people prefer using a mapped Windows drive letter instead of a UNC path because a mapped drive letter is easier to remember. Therefore, your scripts will likely have to deal with mapped drives and mapped resources from time to time. It's at these times that you'll want to use the WshNetwork and FileSystemObject objects.
The WshNetwork and FileSystemObject objects are a dynamic duo when you need to work with mapped drives in Windows Script Host (WSH) scripts. Besides providing the same capabilities as Windows Management Instrumentation’s (WMI’s) Win32_MappedLogicalDisk class, the WshNetwork object has additional methods for creating and removing drive mappings. The FileSystemObject object provides methods for retrieving information about system drives. With the WshNetwork and FileSystemObject objects, you can easily perform a variety of mapping tasks, as the following examples demonstrate.
Determining Whether a Share Is Mapped
The IsDriveMapped function in Listing 1 demonstrates how you can use the WshNetwork object to determine whether a share is mapped. Here’s how this function works. It first uses WshNetwork’s EnumNetworkDrives method to return a list of the mapped network drives on a computer as a collection. This collection contains a pair of items for each mapped network drive: the drive’s local name and its associated UNC path. The collection is zero-indexed so that the even-numbered items in the collection are the drive names and the odd-numbered items are the associated UNC paths. Therefore, the function iterates through every second item in the collection for comparison to the specified share. If there’s a match, the function’s return value is set to true. Otherwise, a value of Nothing is returned, which evaluates to false in Boolean comparisons.
You can download the IsDriveMapped function’s code (and the code in the other listings) by going to the top of this page and click the Download the Code Here button. To use the IsDriveMapped function in a script, you call it using code such as
If IsDriveMapped("\Svr1Electronic") Then' Do something.
or
If Not IsDriveMapped("W:") Then' Create a new drive mapping.
Finding the Next Available Drive
Typically, you don't want to map a resource or share to an arbitrary drive letter. It makes more sense to find the next available one. Although the WshNetwork’s object's EnumNetworkDrives method is great for listing mapped drives, it's not much help in finding available drives. A better approach is to use the FileSystemObject's Drives collection, as it contains information about both local and network drives in a system.
The GetNextDrive function in Listing 2 finds the next available drive. The function begins by enumerating the ASCII codes representing the possible drive letters. With this approach, the function’s loop counter can easily convert the ASCII codes into drive letters by applying the Chr() function and appending a colon (:). For example, the ASCII code of 65, which represents the uppercase letter A, is transformed into A:.
GetNextDrive transforms one ASCII code at a time. Once transformed, the function uses the FileSystemObject object’s DriveExists method to determine whether that drive already exists. The DriveExists method returns a value of true when the drive exists and a value of false when it doesn’t exist. If the drive doesn’t exist, the function’s return value is set to that drive letter.
To use the GetNextDrive function, you need to customize the starting and ending loop indexes in the line
Const A_DRIVE = 65, Z_DRIVE = 90
so that they correspond to the available drive letter range in your system. For example, if the A and B drives are reserved for removable devices and the C drive is reserved for the first hard disk partition, you’d change this line to
Const D_DRIVE = 68, Z_DRIVE = 90
so that the function starts from the D drive. You can find a list of the ASCII codes at ASCII Code.
You can use the GetNextDrive function in code such as
strDriveLetter = GetNextDrive()
If Not IsEmpty(strDriveLetter) Then
Set objNetwork = _
WScript.CreateObject("WScript.Network")
objNetwork.MapNetworkDrive _
strDriveLetter, "\Svr1Electronic"
This code uses the GetNextDrive function to find the next available drive, then maps that drive’s letter to the \Svr1Electronic share. To map the drive, the code uses the WshNetwork object’s MapNetworkDrive method, which I’ll discuss shortly.
Disconnecting a Mapped Drive
You can use the WshNetwork object’s RemoveNetworkDrive method to disconnect a mapped drive. This method has one mandatory and two optional arguments:
Name. You use this mandatory string argument to specify the name of the mapped drive you want to disconnect. It can be either a local name or a remote name, depending on how the drive is mapped.
Force. You use this optional Boolean argument to specify that you want the mapped drive disconnected, even if files are in use. When you specify the value of true, the mapping is removed whether or not the resource is in use. When you don’t include this argument or you specify the value of false, the mapping isn’t removed if the resource is in use.
UpdateProfile. You use this optional Boolean argument to specify that you want to remove the mapping from the current user's profile. This argument might be used if the RemoveNetworkDrive method is part of a logon script, for example. When you specify the value of true, the mapping is removed. When you don’t include this argument or you specify the value of false, the mapping isn’t removed.
For example, if you want to remove the Z drive mapping even if a resource is being accessed, you’d use the code
oNetwork.RemoveNetworkDrive("Z:", true)
Mapping a Network Drive
You can use the WshNetwork object’s MapNetworkDrive method to map a drive letter to a shared folder or any child folder under a shared folder. MapNetworkDrive has two mandatory and three optional arguments:
LocalName. You use this mandatory string argument to specify the drive you want to map. If the name is a drive letter, you need to include the colon (e.g., G:).
RemoteName. You use this mandatory string argument to specify the shared folder’s UNC name (e.g., \ServerNameShareName, \ServerNameShareNameFolderName).
UpdateProfile. You use this optional Boolean argument when you want to store the mapping information in the current user's profile. When you specify the value of true, the current user’s profile is updated with the mapping information. When you don’t include this argument or you specify the value of false, the current user’s profile isn’t updated.
UserName: You use this optional string argument when you want to map the network drive using the credentials of someone other than the current user.
Password: You use this optional string argument to specify the password for the user identified by the UserName argument.
Many times you can map a drive using only the mandatory arguments. In administrative scripts, though, it might be necessary to supply an alternative or elevated set of credentials to successfully connect to a share because you can't map a drive to a folder unless you have permission to access that folder. After the connection is established, the supplied credentials govern access to the network drive for the duration of the connection.
When using the MapNetworkDrive method, it’s important to include some error-handling code because there are a few conditions that can cause it to fail. Common causes are insufficient permissions, the local drive letter is already in use, and a persistent connection (one that reconnects after a reboot or logout). For example, the MapNetworkDrive.vbs script in Listing 3 handles two types of errors: the local drive letter is already in use and a persistent connection already exists. The latter error condition isn’t a fatal one, as you can still disconnect the drive for the current session using RemoveNetworkDrive.
To run MapNetworkDrive.vbs, follow the syntax
MapNetworkDrive.vbs LocalDrive RemoteShare
For example, if you want to map the D drive to the remote share \Svr1Electronic, you’d use the command
MapNetworkDrive.vbs D: \Svr1Electronic
By default, MapNetworkDrive.vbs doesn’t update the current user’s profile with the mapping information. If you want to update the current user’s profile, you can change the line in callout A to
objNetwork.MapNetworkDrive strLocalDrive, _strRemoteShare, True
Indispensible Tools
The WshNetwork and FileSystemObject objects are indispensable tools when you need to manage mapped drives and resources in WSH scripts. I’ve only covered a few examples of what you can do with them. You can explore other options in MSDN’s WshNetwork Object page and in MSDN’s FileSystemObject Object page.
Listing 1: IsDriveMapped Function
Function IsDriveMapped(strShare)Dim oNet, drv, i
Set oNet = CreateObject("WScript.Network")
Set drv = oNet.EnumNetworkDrives
For i = 0 To drv.Count - 1 Step 2
If StrComp(drv(i + 1), strShare, vbTextCompare) = 0 Then
IsDriveMapped = true
Exit For
End If
Next
End Function
Listing 2: GetNextDrive Function
Function GetNextDrive()Const A_DRIVE = 65, Z_DRIVE = 90
Dim FSO, letter, drv
Set FSO = CreateObject("Scripting.FileSystemObject")
For letter = A_DRIVE To Z_DRIVE
drv = Chr(letter) & ":"
If Not FSO.DriveExists(drv) Then
GetNextDrive = drv
Exit Function
End If
Next
End Function
Listing 3: MapNetworkDrive.vbs
Dim strLocalDrive, strRemoteShare, objNetwork strLocalDrive = UCase(Left(WScript.Arguments.Item(0), 2)) strRemoteShare = WScript.Arguments.Item(1) Set objNetwork = CreateObject("WScript.Network") On Error Resume Next objNetwork.MapNetworkDrive strLocalDrive, strRemoteShare, False ' Error traps If Err <> 0 Then Select Case Err.Number ' Persistent connection so try a second time. Case -2147023694 Err.Clear On Error Resume Next objNetwork.RemoveNetworkDrive strLocalDrive, True, True ' BEGIN CALLOUT A objNetwork.MapNetworkDrive strLocalDrive, strRemoteShare, False ' END CALLOUT A WScript.Echo "Second attempt to map drive " & _ strLocalDrive & " to " & strRemoteShare ' The local drive letter (aka local device name) is already in use. Case -2147024811 WScript.Echo "ERROR: Failed to map drive " & _ strLocalDrive & " to " & strRemoteShare & ". " & Err.Description Case Else WScript.Echo "ERROR: Failed to map drive " & _ strLocalDrive & " to " & strRemoteShare End Select End If
About the Author
You May Also Like