.

Объекты WshNetwork и FileSystemObject образуют надежный тандем при работе с сетевыми дисками в сценариях Windows Script Host (WSH). Помимо возможностей, аналогичных классу Win32_MappedLogicalDisk из набора Windows Management Instrumentation (WMI), объект WshNetwork предусматривает методы для создания и удаления дисковых подключений. Объект FileSystemObject располагает методами для получения информации о системных дисках. Как видно из приведенных ниже примеров, с помощью объектов WshNetwork и FileSystemObject вы легко сможете решать различные задачи, связанные с подключением дисков.

Подключена ли общая папка

Функция IsDriveMapped в листинге 1 показывает, как можно использовать объект WshNetwork, чтобы определить, подключена ли общая папка. Вот как работает эта функция. Сначала она использует метод EnumNetworkDrives из объекта WshNetwork для получения списка подключенных сетевых дисков на компьютере в виде коллекции. Эта коллекция содержит по паре элементов для каждого подключенного сетевого диска: локальное имя диска и соответствующий путь UNC. Нумерация элементов коллекции начитается с нуля, следовательно, четные элементы в коллекции являются именами дисков, а нечетные — соответствующими UNC путями. Таким образом, функция обрабатывает в цикле каждый второй элемент в коллекции, сравнивая его с указанной общей папкой. Если соответствие найдено, функция вернет значение true. Иначе возвращается значение Nothing, которое преобразуется в логическое значение false.

Для применения функции IsDriveMapped в сценарии нужно вызвать ее, используя код, аналогичный приведенному ниже:

If IsDriveMapped ("\\Svr1\Electronic\") Then
   ‘ сделать что-нибудь

или

If Not IsDriveMapped ("W:") Then
   ‘ создать новое имя диска.

Находим следующую доступную букву

В большинстве случаев нежелательно, чтобы подключенный ресурс или общая папка получали случайную букву диска. Таким образом, имеет смысл определить следующую свободную букву. Хотя метод EnumNetworkDrives объекта WshNetwork вполне подходит для получения списка подключенных дисков, он не помогает найти свободные буквы диска. Лучше всего использовать коллекцию Drives из объекта FileSystemObject, так как в ней содержится информация и о локальных, и о сетевых дисках в системе.

Функция GetNextDrive в листинге 2 находит следующий свободный диск. Функция начинается с присвоения номеров кодам ASCII, которые представляют собой возможные буквы диска. При таком подходе счетчик цикла функции легко сможет конвертировать коды ASCII в буквы диска, применяя функцию Chr () и добавляя двоеточие. Например, код ASCII со значением 65, который представляет собой заглавную А, будет преобразован в А:.

Функция GetNextDrive преобразует один код ASCII за один раз. Как только происходит преобразование, функция задействует метод DriveExists из объекта FileSystemObject, чтобы определить, существует ли такой диск. Метод DriveExists возвращает значение true, если диск уже существует, и значение false, если не существует. Если диска не существует, то функция возвращает значение, которым будет текущая буква диска.

Чтобы использовать функцию GetNextDrive, необходимо настроить начальные и конечные значения для цикла в строке

Const a_Drive = 65, Z_Drive = 90

так, чтобы они соответствовали диапазону свободных букв дисков в вашей системе. Например, если диски А и В заняты съемными устройствами, а диск С занят первым разделом жесткого диска, следует поменять эту строку на

Const D_Drive = 68, Z_Drive = 90

чтобы функция начинала отсчет от диска D. Список кодов ASCII можно увидеть на сайте www.ascii-code.com.

Можно использовать функцию GetNextDrive в коде, аналогичном приведенному ниже:

strDriveLetter = GetNextDrive ()
If Not IsEmpty (strDriveLetter) Then
   Set objNetwork = _
      WScript.CreateObject_
         ("WScript.Network")
   objNetwork.MapNetworkDrive _
      strDriveLetter,_
         "\\svr1\electronic\"

Этот код использует функцию GetNextDrive, чтобы найти следующую свободную букву, затем назначает эту букву сетевой папке \\Svr1\Electronic\. Для подключения диска данный код использует метод MapNetworkDrive из объекта WshNetwork, о котором я расскажу чуть позже.

Отключение сетевого диска

Для отключения сетевого диска можно применить метод RemoveNetworkDrive из объекта WshNetwork. Этот метод имеет один обязательный и два дополнительных аргумента.

  • Name. Используйте этот обязательный аргумент типа string для указания имени сетевого диска, который хотите отключить. Имя может быть локальным или удаленным, в зависимости от способа подключения диска.
  • Force. Задействуйте этот дополнительный аргумент типа boolean, если хотите отключить сетевой диск, даже когда используются файлы. Значения true и false.
  • UpdateProfile. Используйте этот дополнительный аргумент типа boolean, если хотите, чтобы диск был удален из профиля данного пользователя. Этот аргумент может применяться, например, в случае, если метод RemoveNetworkDrive используется в сценарии входа в систему.

Например, если вы хотите удалить диск Z, даже в случаях, когда ресурс используется, вам нужно ввести код

objNetwork.RemoveNetworkDrive ("Z:", true)

Подключение сетевого диска

Можно использовать метод MapNetworkDrive из объекта Wsh

Network, чтобы назначить букву диска общей папке или любой ее дочерней папке. Функция MapNetworkDrive имеет два обязательных и три дополнительных аргумента.

  • LocalName. Используйте этот обязательный аргумент типа string, чтобы указать диск, который хотите подключить. Если именем является буква диска, нужно добавить двоеточие (например, G:).
  • RemoteName. Используйте этот обязательный аргумент типа string, чтобы указать UNC путь для общей папки (например, \\ServerName\ShareName,\\ServerName\ShareName\FolderName).
  • UpdateProfile. Используйте этот дополнительный аргумент типа boolean, когда вам нужно сохранить информацию о подключении в данном профиле пользователя. Значения true и false.
  • UserName. Задействуйте этот дополнительный аргумент типа string, когда вам необходимо подключить сетевой диск, используя учетные данные кого-то другого, а не данного пользователя.
  • Password. Используйте этот дополнительный аргумент типа string, чтобы указать пароль для идентификации пользователя, заданного аргументом UserName.

В большинстве случаев будет достаточно применять только обязательные аргументы, чтобы подключить диск. Хотя в сценариях администратора, возможно, придется указывать альтернативные учетные данные или учетные данные с более высокими правами для подключения к общей папке, потому что вы не сможете подключить папку в качестве сетевого диска, пока у вас не будет доступа к ней. Когда соединение установлено, предоставленные учетные данные открывают доступ к сетевому диску на время соединения.

При использовании метода MapNetworkDrive важно добавить в сценарий код обработки ошибок, так как есть несколько условий, при которых данный метод не сработает. Обычные причины: недостаточный уровень доступа, попытка использования занятой локальной буквы диска и наличие постоянного подключения (которое восстанавливается после перезагрузки или выхода из системы). Например, сценарий MapNetworkDrive.vbs в листинге 3 обрабатывает два вида ошибок: локальная буква диска уже используется и постоянное соединение существует. Последняя ошибка не фатальна, так как вы все равно можете отключить диск в рамках данной сессии, используя метод RemoveNetworkDrive.

Чтобы подключить диск D к удаленной общей папке \\Svr1\Electronic\, следует применить сценарий:

MapNetworkDrive.vbs
   D:\\Svr1\Electronic\

По умолчанию MapNetworkDrive.vbs не обновляет информацию о подключении в профиле данного пользователя. Если вы хотите обновить профиль данного пользователя, вы можете изменить строку в сноске А на

objNetwork.MapNetworkDrive _
   strLocalDrive, _
   strRemoteShare, True

Незаменимые инструменты

Объекты WshNetwork и FileSystemObject становятся незаменимыми инструментами в случаях, когда вам необходимо управлять сетевыми дисками и ресурсами через сценарии WSH. Я всего лишь показал несколько примеров использования данных объектов. Вы можете изучить другие возможности объектов на страницах MSDN WshNetwork Object (msdn.microsoft.com/en-us/library/s6wt333f(v=VS.85).aspx) и MSDN FileSystemObject(msdn.microsoft.com/en-us/library/6kxy1a51(v=VS.85).aspx).

Листинг 1. Функция IsDriveMapped

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

Листинг 2. Функция GetNextDrive

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

Листинг 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

Роб Грейвилл — основатель компании GravelleConsulting.com, Канада. Разрабатывает системы для организаций, занимающихся обработкой данных, например Canada Border Services