vbscript problem removing and mapping network drive

  • Thread starter Thread starter Usenet
  • Start date Start date
U

Usenet

Guest
I'm hoping someone can help. I'm trying to move our logon scripts over
from a mix of batch files and kixtart to vbscript.

So far so good, except I have an issue with getting the script to map
network drives reliably.

In our environment let's say everyone has to have "r" drive mapped to
\\server\share.

Then depending which department a user is in they need a set of drives
mapping for that department.

So I have the following (not the whole script, modified to post the
relevant bits):

Dim objADSysInfo, WshShell, WshNetwork

Set objADSysInfo = CreateObject("ADSystemInfo")
Set WshShell = WScript.CreateObject("WScript.Shell")
Set WshNetwork = WScript.CreateObject("WScript.Network")

On Error Resume Next

FirstSub
SecondSub
ThirdSub
Mappings

Sub Mappings

WshNetwork.RemoveNetworkDrive "r:"
WshNetwork.MapNetworkDrive "r:", "\\server\share"

strUserPath = "LDAP://" & objADSysInfo.UserName
Set objUser = GetObject(strUserPath)

For Each strGroup in objUser.MemberOf
strGroupPath = "LDAP://" & strGroup
Set objGroup = GetObject(strGroupPath)
strGroupName = objGroup.CN

Select Case Left(strGroupName, 4)

Case "0001"
WshNetwork.RemoveNetworkDrive "x:"
WshNetwork.RemoveNetworkDrive "y:"
WshNetwork.RemoveNetworkDrive "z:"
WshNetwork.MapNetworkDrive "x:", "\\server\share"
WshNetwork.MapNetworkDrive "y:", "\\server\share"
WshNetwork.MapNetworkDrive "z:", "\\server\share"

Case "0002", "0003", "0004", "0005"
WshNetwork.RemoveNetworkDrive "x:"
WshNetwork.MapNetworkDrive "x:", "\\server\share"

End Select
Next
End Sub

AIUI this should remove each drive (in case it's already in use for
something else) and then map each drive.

The "On Error Resume Next" is there so that the script doesn't tank if
an attempt is made to remove a non-existent mapping, or if a server or
share is down at the time someone logs on etc. so AIUI I need it in
there.

The problem I'm seeing is that let's say I don't have an "r" drive, the
script above doesn't seem to map it *if* the line is there to unmap it
first. Same for the other drives.

If I remove the line to unmap the drives, and manually disconnect them
before running the script they map.

If I remove the "On Error Resume Next" line the script tanks the first
time a drive doesn't exist to be removed etc.

I'm slightly confused and would appreciate someone casting an eye and
telling me if I've done something really stupid or could do it
differently/better to be more robust etc.

Thanks in advance.
 
Re: vbscript problem removing and mapping network drive


"Usenet" <usenet@nospam.please> wrote in message
news:usenet-423F7D.20351719042008@softbank060082049208.bbtec.net...
> I'm hoping someone can help. I'm trying to move our logon scripts over
> from a mix of batch files and kixtart to vbscript.
>
> So far so good, except I have an issue with getting the script to map
> network drives reliably.
>
> In our environment let's say everyone has to have "r" drive mapped to
> \\server\share.
>
> Then depending which department a user is in they need a set of drives
> mapping for that department.
>
> So I have the following (not the whole script, modified to post the
> relevant bits):
>
> Dim objADSysInfo, WshShell, WshNetwork
>
> Set objADSysInfo = CreateObject("ADSystemInfo")
> Set WshShell = WScript.CreateObject("WScript.Shell")
> Set WshNetwork = WScript.CreateObject("WScript.Network")
>
> On Error Resume Next
>
> FirstSub
> SecondSub
> ThirdSub
> Mappings
>
> Sub Mappings
>
> WshNetwork.RemoveNetworkDrive "r:"
> WshNetwork.MapNetworkDrive "r:", "\\server\share"
>
> strUserPath = "LDAP://" & objADSysInfo.UserName
> Set objUser = GetObject(strUserPath)
>
> For Each strGroup in objUser.MemberOf
> strGroupPath = "LDAP://" & strGroup
> Set objGroup = GetObject(strGroupPath)
> strGroupName = objGroup.CN
>
> Select Case Left(strGroupName, 4)
>
> Case "0001"
> WshNetwork.RemoveNetworkDrive "x:"
> WshNetwork.RemoveNetworkDrive "y:"
> WshNetwork.RemoveNetworkDrive "z:"
> WshNetwork.MapNetworkDrive "x:", "\\server\share"
> WshNetwork.MapNetworkDrive "y:", "\\server\share"
> WshNetwork.MapNetworkDrive "z:", "\\server\share"
>
> Case "0002", "0003", "0004", "0005"
> WshNetwork.RemoveNetworkDrive "x:"
> WshNetwork.MapNetworkDrive "x:", "\\server\share"
>
> End Select
> Next
> End Sub
>
> AIUI this should remove each drive (in case it's already in use for
> something else) and then map each drive.
>
> The "On Error Resume Next" is there so that the script doesn't tank if
> an attempt is made to remove a non-existent mapping, or if a server or
> share is down at the time someone logs on etc. so AIUI I need it in
> there.
>
> The problem I'm seeing is that let's say I don't have an "r" drive, the
> script above doesn't seem to map it *if* the line is there to unmap it
> first. Same for the other drives.
>
> If I remove the line to unmap the drives, and manually disconnect them
> before running the script they map.
>
> If I remove the "On Error Resume Next" line the script tanks the first
> time a drive doesn't exist to be removed etc.
>
> I'm slightly confused and would appreciate someone casting an eye and
> telling me if I've done something really stupid or could do it
> differently/better to be more robust etc.
>
> Thanks in advance.


I haven't analysed your script detail but here is an overall observation.
Using "On Error Resume Next" to deal with the deletion of a mapped
drive letter is "not nice". It makes debugging of your script very difficult
(because you can no longer see any errors) and it is not necessary
anyway. How about using the DriveExists method of objFSO instead?

if objfso.DriveExists("R:") WshNetwork.RemoveNetworkDrive "r:"
 
Re: vbscript problem removing and mapping network drive

In article <ush2TYloIHA.1580@TK2MSFTNGP06.phx.gbl>,
"Pegasus \(MVP\)" <I.can@fly.com.oz> wrote:

> I haven't analysed your script detail but here is an overall observation.
> Using "On Error Resume Next" to deal with the deletion of a mapped
> drive letter is "not nice". It makes debugging of your script very difficult
> (because you can no longer see any errors) and it is not necessary
> anyway. How about using the DriveExists method of objFSO instead?
>
> if objfso.DriveExists("R:") WshNetwork.RemoveNetworkDrive "r:"


Thanks for the very quick reply.

I have to admit I'm totally new to vbscript and am not even vaguely the
programming type, so it's been a case of looking at examples on the MS
Script Library and using snippets until it works.

I agree it's "not nice", and having tried your method it seems to work
perfectly as well as being smart enough to only try and remove something
which exists, which seems sensible.

The only reason I left in the "On Error Resume Next" as a global in the
script was that if one of the utilities or application that is called by
the login script (wshShell.Run "\\server\share\audit.exe" for example)
wasn't there for whatever reason, I wanted the login script to continue.

I wasn't sure if there is a neater way of doing it?
 
Re: vbscript problem removing and mapping network drive


"Usenet" <usenet@nospam.please> wrote in message
news:usenet-E5C280.21161719042008@softbank060082049208.bbtec.net...
> In article <ush2TYloIHA.1580@TK2MSFTNGP06.phx.gbl>,
> "Pegasus \(MVP\)" <I.can@fly.com.oz> wrote:
>
>> I haven't analysed your script detail but here is an overall observation.
>> Using "On Error Resume Next" to deal with the deletion of a mapped
>> drive letter is "not nice". It makes debugging of your script very
>> difficult
>> (because you can no longer see any errors) and it is not necessary
>> anyway. How about using the DriveExists method of objFSO instead?
>>
>> if objfso.DriveExists("R:") WshNetwork.RemoveNetworkDrive "r:"

>
> Thanks for the very quick reply.
>
> I have to admit I'm totally new to vbscript and am not even vaguely the
> programming type, so it's been a case of looking at examples on the MS
> Script Library and using snippets until it works.
>
> I agree it's "not nice", and having tried your method it seems to work
> perfectly as well as being smart enough to only try and remove something
> which exists, which seems sensible.
>
> The only reason I left in the "On Error Resume Next" as a global in the
> script was that if one of the utilities or application that is called by
> the login script (wshShell.Run "\\server\share\audit.exe" for example)
> wasn't there for whatever reason, I wanted the login script to continue.
>
> I wasn't sure if there is a neater way of doing it?


You use the same method as the one I suggested before:

if objFSO.FileExists("\\server\share\audit.exe") then wshShell.Run
"\\server\share\audit.exe", 1, 1
 
Re: vbscript problem removing and mapping network drive

In article <e#Y5yxloIHA.4292@TK2MSFTNGP04.phx.gbl>,
"Pegasus \(MVP\)" <I.can@fly.com.oz> wrote:

> You use the same method as the one I suggested before:
>
> if objFSO.FileExists("\\server\share\audit.exe") then wshShell.Run
> "\\server\share\audit.exe", 1, 1


Doh! Thanks very much!

Just for my own sanity, if anyone has tried the code in my original post
or can tell me why it didn't seem to work consistently I'd be interested
to know the reasons.
 
Re: vbscript problem removing and mapping network drive


"Usenet" <usenet@nospam.please> wrote in message
news:usenet-9476A6.21421219042008@softbank060082049208.bbtec.net...
> In article <e#Y5yxloIHA.4292@TK2MSFTNGP04.phx.gbl>,
> "Pegasus \(MVP\)" <I.can@fly.com.oz> wrote:
>
>> You use the same method as the one I suggested before:
>>
>> if objFSO.FileExists("\\server\share\audit.exe") then wshShell.Run
>> "\\server\share\audit.exe", 1, 1

>
> Doh! Thanks very much!
>
> Just for my own sanity, if anyone has tried the code in my original post
> or can tell me why it didn't seem to work consistently I'd be interested
> to know the reasons.


Hard to say without being able to work in much the same
environment as you are. Once you turn off the "on error"
statement you should see on the screen what's going on.
If not then a step-by-step execution with an interactive development
tool would probably tell you straight away.
 
Re: vbscript problem removing and mapping network drive


"Usenet" <usenet@nospam.please> wrote in message
news:usenet-423F7D.20351719042008@softbank060082049208.bbtec.net...
> I'm hoping someone can help. I'm trying to move our logon scripts over
> from a mix of batch files and kixtart to vbscript.
>
> So far so good, except I have an issue with getting the script to map
> network drives reliably.
>
> In our environment let's say everyone has to have "r" drive mapped to
> \\server\share.
>
> Then depending which department a user is in they need a set of drives
> mapping for that department.
>
> So I have the following (not the whole script, modified to post the
> relevant bits):
>
> Dim objADSysInfo, WshShell, WshNetwork
>
> Set objADSysInfo = CreateObject("ADSystemInfo")
> Set WshShell = WScript.CreateObject("WScript.Shell")
> Set WshNetwork = WScript.CreateObject("WScript.Network")
>
> On Error Resume Next
>
> FirstSub
> SecondSub
> ThirdSub
> Mappings
>
> Sub Mappings
>
> WshNetwork.RemoveNetworkDrive "r:"
> WshNetwork.MapNetworkDrive "r:", "\\server\share"
>
> strUserPath = "LDAP://" & objADSysInfo.UserName
> Set objUser = GetObject(strUserPath)
>
> For Each strGroup in objUser.MemberOf
> strGroupPath = "LDAP://" & strGroup
> Set objGroup = GetObject(strGroupPath)
> strGroupName = objGroup.CN
>
> Select Case Left(strGroupName, 4)
>
> Case "0001"
> WshNetwork.RemoveNetworkDrive "x:"
> WshNetwork.RemoveNetworkDrive "y:"
> WshNetwork.RemoveNetworkDrive "z:"
> WshNetwork.MapNetworkDrive "x:", "\\server\share"
> WshNetwork.MapNetworkDrive "y:", "\\server\share"
> WshNetwork.MapNetworkDrive "z:", "\\server\share"
>
> Case "0002", "0003", "0004", "0005"
> WshNetwork.RemoveNetworkDrive "x:"
> WshNetwork.MapNetworkDrive "x:", "\\server\share"
>
> End Select
> Next
> End Sub
>
> AIUI this should remove each drive (in case it's already in use for
> something else) and then map each drive.
>
> The "On Error Resume Next" is there so that the script doesn't tank if
> an attempt is made to remove a non-existent mapping, or if a server or
> share is down at the time someone logs on etc. so AIUI I need it in
> there.
>
> The problem I'm seeing is that let's say I don't have an "r" drive, the
> script above doesn't seem to map it *if* the line is there to unmap it
> first. Same for the other drives.
>
> If I remove the line to unmap the drives, and manually disconnect them
> before running the script they map.
>
> If I remove the "On Error Resume Next" line the script tanks the first
> time a drive doesn't exist to be removed etc.
>
> I'm slightly confused and would appreciate someone casting an eye and
> telling me if I've done something really stupid or could do it
> differently/better to be more robust etc.
>
> Thanks in advance.


Two things in your script can raise errors. Most likely an error will be
raised when you attempt to remove the network drives. Also, if the user is
not a direct member of at least 2 groups (not counting the "primary" group
of the user), an error is raised when you attempt to enumerate the memberOf
attribute of the user. The "For Each" statement expects an array, but
objUser.memberOf is Empty if there are no groups, String if there is one,
and only a variant array if there is more than one group.

Since you bind to each group (which slows things a bit), you might as well
use the Groups method of the user object, which returns an array of group
object references. Enumerating the Groups collection never raises an error,
even if the user has no groups.

You can use the cn (Common Name) attribute if you like, but I prefer to use
sAMAccountName, the NetBIOS (or NT) name of the group. Technically cn does
not uniquely identify the group. There could be many groups in your domain
with the same cn, but sAMAccountName must be unique in the domain. In your
case cn and sAMAccountName may match.

I would suggest using a function to map drives. The function can trap the
error if the mapping fails, then attempt to remove the mapping and try
again. The script below demonstrates an example. I like using a boolean
function because I can display a message to the user if the mapping failed.
I would suggest code similar to:
===============
Option Explicit

Dim objFSO, objNetwork, objSysInfo, objShell
Dim strUserDN, objUser, objGroup, strGroup

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objNetwork = CreateObject("Wscript.Network")
Set objSysInfo= CreateObject("ADSystemInfo")
Set objShell = CreateObject("Wscript.Shell")

strUserDN = objSysInfo.UserName
Set objUser = GetObject("LDAP://" & strUserDN)

For Each objGroup in objUser.Groups
strGroup = objGroup.sAMAccountName
Select Case Left(strGroup, 4)
Case "0001"
If (MapDrive("X:", "\\Server\Share") = False) Then
Call MsgBox("Unable to map drive X:")
End If
If (MapDrive("Y:", "\\Server\Share") = False) Then
Call MsgBox("Unable to map drive Y:")
End If
If (MapDrive("Z:", "\\Server\Share") = False) Then
Call MsgBox("Unable to map drive Z:")
End If
Case "0002", "0003", "0004", "0005"
If (MapDrive("X:", "\\Server\Share") = False) Then
Call MsgBox("Unable to map drive X:")
End If
End Select
Next

Function MapDrive(ByVal strDrive, ByVal strShare)
' Function to map network share to a drive letter.
' If the drive letter specified is already in use, the function
' attempts to remove the network connection.
' objFSO is the File System Object, with global scope.
' objNetwork is the Network object, with global scope.
' Returns True if drive mapped, False otherwise.

Dim objDrive

On Error Resume Next
If (objFSO.DriveExists(strDrive) = True) Then
Set objDrive = objFSO.GetDrive(strDrive)
If (Err.Number <> 0) Then
On Error GoTo 0
MapDrive = False
Exit Function
End If
If (objDrive.DriveType = 3) Then
objNetwork.RemoveNetworkDrive strDrive, True, True
Else
MapDrive = False
Exit Function
End If
Set objDrive = Nothing
End If
objNetwork.MapNetworkDrive strDrive, strShare
If (Err.Number = 0) Then
MapDrive = True
Else
Err.Clear
MapDrive = False
End If
On Error GoTo 0
End Function
======
Note if the drive is not a network drive (DriveType = 3), the function
returns False because the drive letter cannot be used on this computer. When
a network drive is removed I use two parameters (both True) that remove the
mapping even if it is in use and make the removal persistent (if the mapping
was persistent, it should no longer be).
--
Richard Mueller
Microsoft MVP Scripting and ADSI
Hilltop Lab - http://www.rlmueller.net
--
 
Re: vbscript problem removing and mapping network drive

In article <#4AcfjnoIHA.5916@TK2MSFTNGP04.phx.gbl>,
"Richard Mueller [MVP]" <rlmueller-nospam@ameritech.nospam.net> wrote:

> I would suggest using a function to map drives. The function can trap the
> error if the mapping fails, then attempt to remove the mapping and try
> again. The script below demonstrates an example. I like using a boolean
> function because I can display a message to the user if the mapping failed.
> I would suggest code similar to:


Thanks Richard and Pegasus. I have to be honest and say that whilst I
don't understand the syntax I can follow it through and get my head
around what is going on in all the examples you've listed.

There is one thing that leaps to mind that would be nice to have, and
search as I might I've not seen an example that seems to cover it:

We have hundreds of PCs and there may well be drives mapped on each one
that point to resources that no longer exist, or where it's a PC that
isn't always switched on etc. and these can slow the PCs down whilst
they timeout in Explorer.

Is there any function I could use to enumerate the network drives but
ONLY remove ones that aren't accessible when the script is run?

I've found scripts that just enumerate and disconnect all network drives
but I think this would be a step too far as we do have lots of manual
drive mappings.

cheers again!

oh and p.s is there any sort of script debugger built into Vista that
will let me step through a script to run it line by line and check out
the logic etc. as running from a command prompt doesn't help me much
other than knowing "it works" or "it doesn't work"
 
Re: vbscript problem removing and mapping network drive

Why do people always make scripting sound so mega complicated!!!!

Function MapDrive(strDL,strNP)

Dim objNetwork,strDL,strNP
Set objNetwork = CreateObject("WScript.Network")

' The Function takes in a drive letter and a UNC path.
' The Function will over-write and existing mapping
' attached to the drive letter.
On Error Resume Next
objNetwork.MapNetworkDrive strDL, strNP
If Err.Number <> 0 Then
objNetwork.RemoveNetworkDrive strDL, True, True
objNetwork.MapNetworkDrive strDL, strNP
End If
On Error GoTo 0
End Function
 
Re: vbscript problem removing and mapping network drive


"VJay" <VJayMeyer@gmail.com> wrote in message
news:2ce5b162-dee1-4efe-8d48-a90bfd816585@k13g2000hse.googlegroups.com...
> Why do people always make scripting sound so mega complicated!!!!
>
> Function MapDrive(strDL,strNP)
>
> Dim objNetwork,strDL,strNP
> Set objNetwork = CreateObject("WScript.Network")
>
> ' The Function takes in a drive letter and a UNC path.
> ' The Function will over-write and existing mapping
> ' attached to the drive letter.
> On Error Resume Next
> objNetwork.MapNetworkDrive strDL, strNP
> If Err.Number <> 0 Then
> objNetwork.RemoveNetworkDrive strDL, True, True
> objNetwork.MapNetworkDrive strDL, strNP
> End If
> On Error GoTo 0
> End Function


If simplicity is your aim then you can condense your seven
lines of code down to two lines, plus avoid the frowned
upon "On Error" statement:

if objfso.DriveExists("R:") then WshNetwork.RemoveNetworkDrive "r:"
objNetwork.MapNetworkDrive strDL, strNP
 
Re: vbscript problem removing and mapping network drive


"Pegasus (MVP)" <I.can@fly.com.oz> wrote in message
news:euO6H4voIHA.548@TK2MSFTNGP06.phx.gbl...
>
> "VJay" <VJayMeyer@gmail.com> wrote in message
> news:2ce5b162-dee1-4efe-8d48-a90bfd816585@k13g2000hse.googlegroups.com...
>> Why do people always make scripting sound so mega complicated!!!!
>>
>> Function MapDrive(strDL,strNP)
>>
>> Dim objNetwork,strDL,strNP
>> Set objNetwork = CreateObject("WScript.Network")
>>
>> ' The Function takes in a drive letter and a UNC path.
>> ' The Function will over-write and existing mapping
>> ' attached to the drive letter.
>> On Error Resume Next
>> objNetwork.MapNetworkDrive strDL, strNP
>> If Err.Number <> 0 Then
>> objNetwork.RemoveNetworkDrive strDL, True, True
>> objNetwork.MapNetworkDrive strDL, strNP
>> End If
>> On Error GoTo 0
>> End Function

>
> If simplicity is your aim then you can condense your seven
> lines of code down to two lines, plus avoid the frowned
> upon "On Error" statement:
>
> if objfso.DriveExists("R:") then WshNetwork.RemoveNetworkDrive "r:"
> objNetwork.MapNetworkDrive strDL, strNP
>


I agree that "On Error Resume Next" is generally a bad idea, but for logon
scripts it is a good idea. Most admins don't want the entire script to
abort just because one server (strNP) is down or not reachable. It's best
to comment it out while testing the logon script, but then uncomment it for
production.
 
Back
Top