VBScript MapNetworkDrive Error Handling

error handlingvbscript

I am attempting to write a small script in VBScript just purely for my home use, which is run prior to a scheduled backup in Macrium Reflect.

I am stuck on one seemingly small issue and that is error handling when the Network Drive is physically disconnected, i.e. the cable is not attached.

At the moment the script check to see if the Drive is already attached, if the drive is not attached then a message is displayed telling the user to connect the cable and press YES.

Now, all things being well the user would have connected the cable as asked and then pressed the YES button but I want to catch the times when YES was pressed before attaching the drive's cable.

Within the code there's an 'On Error Resume Next' which masks this eventuality, so I comment out this line & indeed I get an Error 'The Network Path Was Not Found' on line 40:

objNetwork.MapNetworkDrive strDriveLetter, strRemotePath, _

I want to use this caught error to display an alert to the user that the drive has not yet been connected, please connect and retry & KEEP RETRYING until the drive is actually connected.

My problem is I cannot seem to find where to add any error handling code to display this message.

Here's my code:

Option Explicit
Dim strDriveLetter, strRemotePath, strUser, strPassword, strProfile, strName, objNetwork, objShell, CheckDrive, AlreadyConnected, intDrive

' The section sets the variables. 
strDriveLetter = "X:" 
strRemotePath = "\\192.168.1.1\shared"
strUser = "user"
strPassword = "password"
strProfile = "true"
strName = "Backup Drive"

' This sections creates two objects:
' objShell and objNetwork and counts the drives
Set objShell = CreateObject("WScript.Shell") 
Set objNetwork = CreateObject("WScript.Network") 
Set CheckDrive = objNetwork.EnumNetworkDrives() 

' This section deals with a For ... Next loop
' See how it compares the enumerated drive letters
' with strDriveLetter
On Error Resume Next
AlreadyConnected = False 
For intDrive = 0 To CheckDrive.Count - 1 Step 2 
If CheckDrive.Item(intDrive) =strDriveLetter _
Then AlreadyConnected = True
Next 

If AlreadyConnected = False Then 

Dim result
result = MsgBox("A Backup Is Now Due But The Drive Is Not Connected." & vbNewLine & vbNewLine & "Please Connect The Drive & Press YES To Continue." & vbNewLine & vbNewLine & "If You Wish To Postpone Backup Then Press NO Now.", 4 + 32, "BACKUP DRIVE NOT CONNECTED")
If result = 7 Then
WScript.Quit
Else
Call MapDRV
End If

Sub MapDRV()
Set objNetwork = WScript.CreateObject("WScript.Network") 
objNetwork.MapNetworkDrive strDriveLetter, strRemotePath, _
strProfile, strUser, strPassword
Set objShell = CreateObject("Shell.Application")
objShell.NameSpace(strDriveLetter).Self.Name = strName
End Sub

WScript.Quit

The error handling code is something along these lines:

If Err.Number <> 0 Then
    'error handling:
    'ALERT USER HERE
Err.Clear
End If

Any help would be appreciated

Best Answer

Err Object (VBScript) reference does not give useful guide. You need to trap an error or success separate for every run-time error prone action.
Common rule (best practice): keep error handling disabled via On Error GoTo 0 and enable it only for suspected actions.

For instance, there could me more than one reason why MapNetworkDrive method could fail (server off-line, user blocked, wrong/changed password etc.):

Sub MapDRV
  Dim errResult
  Set objNetwork = WScript.CreateObject("WScript.Network")
  errResult = ""
  On Error Resume Next
  objNetwork.MapNetworkDrive strDriveLetter, strRemotePath _
                      , strProfile, strUser, strPassword
  If Err.Number = 0 Then
    On Error GoTo 0
    Set objShell = CreateObject("Shell.Application")
    objShell.NameSpace(strDriveLetter).Self.Name = strName
  Else
    errResult = Err.Number & " 0x" & Hex(Err.Number) & " " & Err.Source
    errResult = errResult & vbNewLine & Err.Description
    On Error GoTo 0
    MsgBox errResult, vbOKOnly + vbCritical, "Error occurred"
  End If
End Sub

The whole script then could look as follows:

Option Explicit
On Error GoTo 0

Dim strResult: strResult = Wscript.ScriptName

Dim strDriveLetter, strRemotePath, strUser, strPassword, strProfile , strName _
  , objNetwork, objShell, CheckDrive, AlreadyConnected, intDrive

' The section sets the variables. 
strDriveLetter = "X:" 
strRemotePath = "\\192.168.1.1\shared"
strUser = "user"
strPassword = "password"
strProfile = "true"
strName = "Backup Drive"

' This sections creates two objects:
' objShell and objNetwork and counts the drives
Set objShell = CreateObject("WScript.Shell") 
Set objNetwork = CreateObject("WScript.Network") 

' This section deals with a For ... Next loop
' See how it compares the enumerated drive letters with strDriveLetter
Dim result, toShare

AlreadyConnected = False
Do While AlreadyConnected = False
  strResult = strResult & vbNewLine & "--- new check"
  AlreadyConnected = False
  Set CheckDrive = objNetwork.EnumNetworkDrives() 
  For intDrive = 0 To CheckDrive.Count - 1 Step 2 
    If CheckDrive.Item(intDrive) = strDriveLetter Then
      AlreadyConnected = True
      toShare = CheckDrive.Item(intDrive + 1)
    End If
    strResult = strResult & vbNewLine & CheckDrive.Item(intDrive)
    strResult = strResult & vbTab & CheckDrive.Item(intDrive + 1)
  Next 
  If AlreadyConnected Then Exit Do
  result = MsgBox("A Backup Is Now Due But The Drive Is Not Connected." _
    & vbNewLine & vbNewLine & "If you wish to ..." _
    & vbNewLine & vbTab & "... postpone backup then press ABORT." _
    & vbNewLine & vbTab & "... backup to " & strRemotePath & " then press RETRY." _
    & vbNewLine & "Otherwise, please connect the drive & press IGNORE to continue." _
      , vbAbortRetryIgnore + vbQuestion, "BACKUP DRIVE NOT CONNECTED")
  Select Case result
  Case vbAbort
    Call scriptQuit
  Case vbRetry
    Call MapDRV
  Case Else
    ' The Case Else clause is not required
  End Select
Loop

  strResult = strResult & vbNewLine & "copy here to " & toShare 

Sub MapDRV
  ' no need to redefine: WshNetwork Object is already defined
  ' Set objNetwork = WScript.CreateObject("WScript.Network")
  Dim errResult
  On Error Resume Next
  objNetwork.MapNetworkDrive strDriveLetter, strRemotePath _
                      , strProfile, strUser, strPassword
  If Err.Number = 0 Then
    On Error GoTo 0
    Set objShell = CreateObject("Shell.Application")
    objShell.NameSpace(strDriveLetter).Self.Name = strName
  Else
    errResult = Err.Number & " 0x" & Hex(Err.Number) & " " & Err.Source
    errResult = errResult & vbNewLine & Err.Description
    On Error GoTo 0
    MsgBox errResult, vbOKOnly + vbCritical, "Error occurred"
    strResult = strResult & vbNewLine & vbNewLine & errResult
  End If
End Sub

Call scriptQuit

Sub scriptQuit
  Wscript.Echo strResult
  Wscript.Quit
End Sub

Please note that strResult variable is there merely for debugging purposes to see next output:

==> cscript D:\VB_scripts\SO\37776762.vbs
37776762.vbs
--- new check
Y:      \\S-PC\VB_scripts_help

-2147024843 0x80070035 WSHNetwork.MapNetworkDrive
The network path was not found.

--- new check
Y:      \\S-PC\VB_scripts_help

--- new check
Y:      \\S-PC\VB_scripts_help
X:      \\S-PC\test
copy here to \\S-PC\test

==>

Above output corresponds to next actions:

  • run script
  • 1st --- new check found Y: mapped disk; then invoked Retry action failed (network path was not found);
  • 2nd --- new check found Y: mapped disk again; then mapped disk X: manually and then invoked Ignore action;
  • 3rd --- new check found Y: and X: mapped disks;
  • Do While loop exited and script continues to next action.

For completeness, following output shows invoked Abort action:

==> net use x: /delete
x: was deleted successfully.

==> cscript D:\VB_scripts\SO\37776762.vbs
37776762.vbs
--- new check
Y:      \\S-PC\VB_scripts_help

==>
Related Topic