VB Login Script will not work

Hi All,

I have a VB Login script that sits in the netlogon folder to run at logon. I need to edit it as I have just implemented access based enumeration.

Basically I wanted to edit the map drive part of it to so that if a user is a member of the Domain users group then, it maps a drive - code below

If (IsMember(objUser, "Domain Users") = True) Then
    MapDrive "N:", "\\Server1\Network Drives"
End If


That script does not work though. If I create a group in AD called LoginTest and put my user accout in it, and change the code to;

If (IsMember(objUser, "LoginTest") = True) Then
    MapDrive "N:", "\\Server1\Network Drives"
End If

It works immediately.

Does anybody know why this happens? What is wrong with using the domain users group in this VB Script?

Thanks
Mark
MFAFCAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ste5anSenior DeveloperCommented:
hmm, sure that this group (Domain Users) exists?
0
MFAFCAuthor Commented:
Of course it does. It's a standard AD group.
0
ste5anSenior DeveloperCommented:
How does your IsMember() function looks like. It seems that the default group is not listed by the default enumeration methods...
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

MFAFCAuthor Commented:
Hi Stefan,

This isn't a script that I have written. I'm not really sure what the IsMember() function should look like to check for the domain users group. Here is the script;

Option Explicit
On Error Resume Next

Dim objNetwork, objSysInfo, strUserDN, colDrives, i
Dim objGroupList, objUser, objFSO
Dim strComputerDN, objComputer

Set objNetwork = CreateObject("Wscript.Network")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objSysInfo = CreateObject("ADSystemInfo")
Set colDrives = objNetwork.EnumNetworkDrives
strUserDN = objSysInfo.userName
strComputerDN = objSysInfo.computerName

' Escape any forward slash characters, "/", with the backslash
' escape character. All other characters that should be escaped are.
strUserDN = Replace(strUserDN, "/", "\/")
strComputerDN = Replace(strComputerDN, "/", "\/")

' Bind to the user and computer objects with the LDAP provider.
Set objUser = GetObject("LDAP://" & strUserDN)
Set objComputer = GetObject("LDAP://" & strComputerDN)

'Remove All Existing Drive Mappings
For i = 0 to colDrives.Count-1 Step 2
    objNetwork.RemoveNetworkDrive colDrives.Item(i), True, True
Next

'Reconnect Login Drive if Disconnected by previous step.
objNetwork.MapNetworkDrive objUser.HomeDrive , objUser.HomeDirectory

' Map a network drive if the user is a member of the group.
' Alert the user if the drive cannot be mapped.

If (IsMember(objUser, "Domain Users") = True) Then
    MapDrive "N:", "\\Server1\Network Drives"
End If

' Add the papercut print queues is a member of the papercut group.
If (IsMember(objUser, "Papercut-Users") = True) Then
    objNetwork.AddWindowsPrinterConnection "\\PR01\Printing Colour"
    objNetwork.AddWindowsPrinterConnection "\\PR01\Printing Black and White"
    objNetwork.SetDefaultPrinter "\\PR01\Printing Black and White"
End If


' Clean up.
Set objNetwork = Nothing
Set objFSO = Nothing
Set objSysInfo = Nothing
Set objGroupList = Nothing
Set objUser = Nothing
Set objComputer = Nothing

Function IsMember(ByVal objADObject, ByVal strGroup)
    ' Function to test for group membership.
    ' objGroupList is a dictionary object with global scope.

    If (IsEmpty(objGroupList) = True) Then
        Set objGroupList = CreateObject("Scripting.Dictionary")
    End If
    If (objGroupList.Exists(objADObject.sAMAccountName & "\") = False) Then
        Call LoadGroups(objADObject, objADObject)
        objGroupList.Add objADObject.sAMAccountName & "\", True
    End If
    IsMember = objGroupList.Exists(objADObject.sAMAccountName & "\" _
        & strGroup)
End Function

Sub LoadGroups(ByVal objPriObject, ByVal objADSubObject)
    ' Recursive subroutine to populate dictionary object objGroupList.

    Dim colstrGroups, objGroup, j

    objGroupList.CompareMode = vbTextCompare
    colstrGroups = objADSubObject.memberOf
    If (IsEmpty(colstrGroups) = True) Then
        Exit Sub
    End If
    If (TypeName(colstrGroups) = "String") Then
        ' Escape any forward slash characters, "/", with the backslash
        ' escape character. All other characters that should be escaped are.
        colstrGroups = Replace(colstrGroups, "/", "\/")
        Set objGroup = GetObject("LDAP://" & colstrGroups)
        If (objGroupList.Exists(objPriObject.sAMAccountName & "\" _
                & objGroup.sAMAccountName) = False) Then
            objGroupList.Add objPriObject.sAMAccountName & "\" _
                & objGroup.sAMAccountName, True
            Call LoadGroups(objPriObject, objGroup)
        End If
        Set objGroup = Nothing
        Exit Sub
    End If
    For j = 0 To UBound(colstrGroups)
        ' Escape any forward slash characters, "/", with the backslash
        ' escape character. All other characters that should be escaped are.
        colstrGroups(j) = Replace(colstrGroups(j), "/", "\/")
        Set objGroup = GetObject("LDAP://" & colstrGroups(j))
        If (objGroupList.Exists(objPriObject.sAMAccountName & "\" _
                & objGroup.sAMAccountName) = False) Then
            objGroupList.Add objPriObject.sAMAccountName & "\" _
                & objGroup.sAMAccountName, True
            Call LoadGroups(objPriObject, objGroup)
        End If
    Next
    Set objGroup = Nothing
End Sub

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

Function GetDN(UserName)
  Const ADS_NAME_INITTYPE_GC = 3
  Const ADS_NAME_TYPE_1779   = 1
  Const ADS_NAME_TYPE_NT4    = 3

  Dim NameTranslate, Result

  ' CALLOUT A
  Set NameTranslate = CreateObject("NameTranslate")
  NameTranslate.Init ADS_NAME_INITTYPE_GC, ""
  ' END CALLOUT A

  ' CALLOUT B
  ' If a domain name is not specified, use the current domain.
  If InStr(UserName, "\") = 0 Then
    UserName = CreateObject("WScript.Network").UserDomain _
      & "\" & UserName
  End If
  ' END CALLOUT B

  ' CALLOUT C
  On Error Resume Next
  NameTranslate.Set ADS_NAME_TYPE_NT4, UserName
  If Err.Number = 0 Then
    Result = NameTranslate.Get(ADS_NAME_TYPE_1779)
  Else
    Result = ""
  End If
  ' END CALLOUT C

  GetDN = Result
End Function
0
ste5anSenior DeveloperCommented:
Well, the problem ADSystemInfo not returning the default group.

This works for me:

Option Explicit

WScript.Echo "Testing.."
Rem The group "Domain Users" is localized. 
Rem I for example need to look for "Domänen-Benutzer" (de-DE).
WScript.Echo IsMember("Domain Users")
WScript.Echo "Done."

Function IsMember(AGroupName)

  Dim Domain
  Dim Group
  Dim Network
  Dim User
  Dim WinNT 
  
  IsMember = False
  Set Network = CreateObject("WScript.Network")
  Domain = Network.UserDomain
  User = Network.UserName
  Set Network = Nothing
  WScript.Echo "Current Principal: " & Domain & "\" & User
  Set WinNT = GetObject("WinNT://" & Domain & "/" & User & ",user")	
  For Each Group In WinNT.Groups
    WScript.Echo "Group: " & Group.Name
	IsMember = (UCase(Group.Name) = UCase(AGroupName))
    If IsMember Then
  	  Exit For
    End If
  Next
	
  Set Group = Nothing
  Set WinNT = Nothing
  
End Function

Open in new window

0
MFAFCAuthor Commented:
Hi,

Thanks for the reply. I do appreciate you taking the time to reply.

I'm not going to lie, I have absolutely no idea about VB, so reading your code above, although very helpful, doesn't mean much to me.  I was hoping that it would be a much simpler solution.

So I don't break anything, rather than trying to use the domain users group, I think I should just create a new group and populate it with my accounts and let the current script do it's job.
0
ste5anSenior DeveloperCommented:
Well, just a thought: Do you have any user account who is not in Domain Users? I would think they all are..
0
MFAFCAuthor Commented:
Exactly - all user accounts are in domain users by default which is why I wanted to use that group to map the drive.

The problem is that I don't understand enough about VB to be able to start making too many changes.
0
ste5anSenior DeveloperCommented:
When all users are domain users, then you don't need this condition at all. Cause it's a tautology and would - when the function would work correctly - return always true (1).

So I would consider removing this clause at all.
0
MFAFCAuthor Commented:
I don't follow.

I want to be able to say;

"If the user is a member of Domain users then map this drive." -  It would always return true so the drive should map, no?

In the same way the current script works;

"If the user is a member of LoginTest then map this drive." If that returns true then the drive maps.

To me, there is no difference in those statements, apart from the group name.
0
ste5anSenior DeveloperCommented:
You said: "Exactly - all user accounts are in domain users by default[..]"

When all user are, why testing for a property, which is always true?
0
MFAFCAuthor Commented:
Because if it is true, then I want it to map the drive!!
0
ste5anSenior DeveloperCommented:
OMG: It is always true, according to your description. This is a tautology.

Why testing, whether it is true, when it is always true per definition?
0
MFAFCAuthor Commented:
It is a tautology - so it should map the drive!!  The domain users group is essentially the same as any other group that gets substituted in the script. If a user is a member of domain users = true, then map the drive!! As previously stated, if I setup a test group, add myself in it, change the script, it works. It's no different trying to use the domain users group as it is with a different group. If the statement returns true, then map the drive.

Whether it's my ignorance of VB or the fact that you don't understand what I'm trying to achieve, I think it's best we close the topic as we don't seem to be getting anywhere.

Thank you for your offer of assistance anyway.
0
ste5anSenior DeveloperCommented:
It is a tautology - so it should map the drive!!  This simply means no test necessary. As script:

Rem If (IsMember(objUser, "Domain Users") = True) Then
Rem Cause this condition is always true, we don't need to run that test at all.
     MapDrive "N:", "\\Server1\Network Drives"
Rem  If

Open in new window

0
MFAFCAuthor Commented:
Yes and I am saying that it doesn't work!!! I don't want to rem it out because I want it to map. The drive does not map!
I simply want the drive to map if a user is a member of the domain users group - because everybody is, it should map for everybody! It doesn't and I don't know why.

It does map if I use a different group in the script.
0
ste5anSenior DeveloperCommented:
Cause your function IsMember() cannot test for default groups.. This is a error in this function. This function cannot return true, due to this error.

Cause it is a default group, all users are member of this group. So the call IsMember(objUser, "Domain Users")  should return always true. (1)

Cause it should returm true always, we can apply logic evaluation to the code:

If IsMember(objUser, "Domain Users") = True Then DoSomething

apply (1)

If True = True Then DoSomething

And this is equivalent to

DoSomething
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MFAFCAuthor Commented:
OK, that make sense.

Thanks again for your help, much appreciated.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.