Solved

LDAP with VbScript: Add users to groups (CN)

Posted on 2004-09-22
13
993 Views
Last Modified: 2008-01-09
Hello,

I have to develop Windows script in VbScript that loops through MySql Database(table called Websencelog, this part shouldn't be complicated), finds the value in a field "Websencegrp" and add the user to a specified Websence group in LDAP.
There are some fields in MySql (user's OU, UID) that can be used to specify the user. UID is equal to a samAccountName.

The structure of the LDAP tree is something like this:
imp.corp.mycompany.ca
    OU = adtest
    CN = Builtin
    CN = computers
    ...
    OU = PrintingDiv
    OU = Services
    OU = WEBSENCE
        OU = Head Office
            OU = Head Office
                CN= 56_WS_Company_Head_Office
        OU = Informations Products
            OU = Books
                CN=15_WS_Management
                CN=16_WS_BestBook
                ...
        OU = Marketing
            OU = Direct Marketing
                CN=41_WS_Intranet Communications
                CN=42_WS_Bayweb
                ...
            OU=General Management
                CN=57_WS_Marketing Products
                ...
             OU = Retial
                 CN=20_WS_Management
             ...

The point is that for each record in a table websencelog, in a websencegrp field I find the name of a Websence group (such as: 56_WS_Company_Head_Office, or  16_WS_BestBook, etc.). By using OU and UID in the record, I have to add the user to a group (like 56_WS_Company_Head_Office).

Is it possible to do it?

Mike

P.S. I think that I have right to add the extra points. So, If the solution works, I am ready to give a total of 600 or 700 poins.
       
0
Comment
Question by:mjasic
  • 7
  • 6
13 Comments
 
LVL 76

Expert Comment

by:David Lee
ID: 12129214
If the question is, "is it possible to add a user to a group based on the OU they're in", then the answer is yes.    Here's a code sample that shows how to add users to various groups:

Dim objGroup, strUsername, strUserOU
For Each Record in SQLTable
  strUsername = SQLUserName
  strUserOU = SQLUserOU
  Select Case strUserOU

    Case "Books"
      Set objGroup = GetObject("LDAP://CN=15_WS_Management,OU=Books,OU=Information Products,OU=Websence,DC=Company,DC=com")
      objGroup.Add ("LDAP://CN=" & strUsername & ",OU=Books,OU=Information Products,OU=Websence,DC=Company,DC=com")

    Case "Retail"
      Set objGroup = GetObject("LDAP://CN=20_WS_Management,OU=Retail,OU=Websence,DC=Company,DC=com")
      objGroup.Add ("LDAP://CN=" & strUsername & ",OU=Retail,OU=Websence,DC=Company,DC=com")

    Case "..."

  End Select
Next
Set objGroup = Nothing
0
 
LVL 76

Expert Comment

by:David Lee
ID: 12129230
Oh, and here's a link to a Microsoft page that covers adding users to groups:  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/iadsgroup_add.asp
0
 
LVL 2

Author Comment

by:mjasic
ID: 12133514
Generaly, I know how to add a user to a group. My problem is that the application (somebody else has developed it and I just add some modules) cannot be modified each time somebody adds a new group.

Suppose a new group has been added:99_WS_MyDummyGrp, inside of MyDummyOU which is inside MyDummyFirstLevelOU and I want to add a user John Doe to this group.

In mySql table Websencelog I have the following fields:

UID: doejoh  (and not: John Doe which is CN)
User OU: OU=PrintingDiv, DC=imp, DC=Company, DC=com
Websencegrp: 99_WS_MyDummyOU

I should do something like this:
Set objGroup = GetObject("LDAP://CN=99_WS_MyDummyOU, OU=MyDummyFirstLevelOU, OU=Websence,DC=Company,DC=com")
objGroup.Add ("LDAP://CN=John Doe, OU=Users, OU=PrintingDiv,DC=imp,DC=Company,DC=com")

but the application doesn't know where this group is in Websence branch because in a table I have only group name and not the path.
Any idea how to resolve it?
0
 
LVL 76

Expert Comment

by:David Lee
ID: 12133563
Just to make sure I understand, the question is how to get the full LDAP path to a group when all you know is the group name.  Is that correct?
0
 
LVL 2

Author Comment

by:mjasic
ID: 12133995
Yes, that is correct.

All i know is 99_WS_MyDummyOU

(and I should find: OU=MyDummyFirstLevelOU, OU=Websence,DC=Company,DC=com)
0
 
LVL 76

Expert Comment

by:David Lee
ID: 12139533
Well, this may not be the most elegant solution, but it does work.  I don't know of a way to get a group object using LDAP without knowing the path to the object up front.  So, the solution I came up with is to build two parallel arrays, one holding the names of the groups and the other the ADSPath of the groups.  I populate the arrays by starting at the root of the domain and grabbing all of the OUs in that container.  I then search each OU found in the root looking for nested OUs.  Using this approach I traverse my way though the directory structure.  As I pass through each OU I search it for groups.  Each group I find gets added to the two arrays.  There is an advantage to this approach.  With all the groups loaded into the arrays I don't have to keep accessing AD over and over for each record.  That should make the code faster than having to access AD each time I need to search for a group.

Ok, now how do we use this?  Well, that's simple.  You read the group out of the database and then search the first array looking for a match.  If you find one, then the corresponding record in the second array will contain the ADSPath to the group.  All you have to do is use GetObject with that ADSPath and you'll have the group object you want.  To build the arrays you'll need to put the code at the begining of your script.  All you need to do is pass it the path to the root of your domain.  The For Next loop surrounding the Wscript.Echo is just for testing.  I had it in there while I tested this in my domain to ensure it worked.  You might want to try it once in your domain to satisfy yourself that it works.  It'll build the arrays and then print out the names of all the groups it found.

I hope this helps.  I tested the code in my domain and it worked fine.


----- Script: GetGroups.vbs

Dim arrGroupNames()
Dim arrGroupPaths()
Dim bolFirstPass

bolFirstPass = True
ProcessOU "LDAP://myserver.company.com/dc=company,dc=com"
For x = 0 To UBound(arrGroupNames)
    Wscript.Echo arrGroupNames(x)
Next
Wscript.Quit

Private Sub ProcessOU(strADSPath)
    Dim objAD
    Dim objOU
    Set objAD = GetObject(strADSPath)
    objAD.Filter = Array("OrganizationalUnit")
    For Each objOU In objAD
        ProcessOU objOU.ADsPath
    Next
    SearchForGroups objAD.ADsPath
End Sub

Private Sub SearchForGroups(strADSPath)
    Dim objOU
    Dim objGroup
    Set objOU = GetObject(strADSPath)
    objOU.Filter = Array("group")
    For Each objGroup In objOU
        If bolFirstPass Then
            bolFirstPass = False
            ReDim arrGroupNames(0)
            ReDim arrGroupPaths(0)
        Else
            ReDim Preserve arrGroupNames(UBound(arrGroupNames) + 1)
            ReDim Preserve arrGroupPaths(UBound(arrGroupPaths) + 1)
        End If
        arrGroupNames(UBound(arrGroupNames)) = Mid(objGroup.Name, 4)
        arrGroupPaths(UBound(arrGroupPaths)) = objGroup.ADsPath
    Next
End Sub

----- End Script
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 2

Author Comment

by:mjasic
ID: 12164779
I didn't have time to test it, so I'll do it probably tomorrow.
0
 
LVL 2

Author Comment

by:mjasic
ID: 12164900
Hello  BlueDevilFan,
OK, I'll show you what I started some time ago and I was blocked.
How can I use your functions to include the into this script (I'm quite newbie in LDAP, so the few things I know are these that I found on the internet)?


Here's the code:


Dim myconn
Dim myrs
Dim mySQL
Dim myrows
Dim Container
Dim Group
dim strOu
Dim strCN
Dim User
Dim strGroupPath)



on error resume next

set myconn=CreateObject("ADODB.connection")
if err<>0 then msgbox err.number & " - " & err.description & "(0)"

myconn.Open "DSN=transpass"
if err<>0 then msgbox err.number & " - " & err.description & "(1)"


set myrs=CreateObject("ADODB.Recordset")
mySQL = "SELECT * from websencelog"
myrs.Source = mySQL
if err<>0 then msgbox err.number & " - " & err.description & "(2)"

Set myrs.ActiveConnection = myconn
myrs.Open


'strGroupPath=

Do UNTIL myrs.eof
      strOU=myrs("ou")
      strCN=myrs("uid")
 

' I'd probably have to set your things here, but have no idea how

'      set Container = GetObject("LDAP://" & strOU)
'      set Group = GetObject("LDAP://CN=" & myrs("websencegrp") & "," & strGroupPath)
'      Group.Add ("LDAP"//CN=" & strcn & "," & strOU)

'      msgbox myrs("uid") & vbcrlf & myrs("websencegrp")
      myrs.movenext
LOOP


myrs.Close
myconn.Close

wscript.Quit (0)
0
 
LVL 76

Accepted Solution

by:
David Lee earned 500 total points
ID: 12185432
mjasic,

Sorry to be slow answering.  I've integrated my code into your code as best as I can.  The one problem I have is that I don't see where you're reading the group name from the database.  I used a placeholder, SomeGroupName, to show where you need to insert the group name read from the database.

Hope this helps.  Let me know if there's anything else I can do.


Dim myconn
Dim myrs
Dim mySQL
Dim myrows
Dim Container
Dim Group
dim strOu
Dim strCN
Dim User
Dim strGroupPath
Dim arrGroupNames()
Dim arrGroupPaths()
Dim bolFirstPass


on error resume next

set myconn=CreateObject("ADODB.connection")
if err<>0 then msgbox err.number & " - " & err.description & "(0)"

myconn.Open "DSN=transpass"
if err<>0 then msgbox err.number & " - " & err.description & "(1)"


set myrs=CreateObject("ADODB.Recordset")
mySQL = "SELECT * from websencelog"
myrs.Source = mySQL
if err<>0 then msgbox err.number & " - " & err.description & "(2)"

Set myrs.ActiveConnection = myconn
myrs.Open

'Search AD and load all the groups into the arrays
bolFirstPass = True
ProcessOU "LDAP://myserver.company.com/dc=company,dc=com"

'strGroupPath=

Do UNTIL myrs.eof
     strOU=myrs("ou")
     strCN=myrs("uid")
 
'The following loop searches the array of group names looking for a match.
' If it finds one, then it'll get the group object.
For x = 0 to (UBound(arrGroupNames) - 1)
    If UBound(x) = SomeGroupName Then
        Set objGroup = GetObject(arrGroupPaths(x))
        'Code to add the user to the group
        Exit For
    End If
Next

'     set Container = GetObject("LDAP://" & strOU)
'     set Group = GetObject("LDAP://CN=" & myrs("websencegrp") & "," & strGroupPath)
'     Group.Add ("LDAP"//CN=" & strcn & "," & strOU)

'     msgbox myrs("uid") & vbcrlf & myrs("websencegrp")
     myrs.movenext
LOOP


myrs.Close
myconn.Close

wscript.Quit (0)

Private Sub ProcessOU(strADSPath)
    Dim objAD
    Dim objOU
    Set objAD = GetObject(strADSPath)
    objAD.Filter = Array("OrganizationalUnit")
    For Each objOU In objAD
        ProcessOU objOU.ADsPath
    Next
    SearchForGroups objAD.ADsPath
End Sub

Private Sub SearchForGroups(strADSPath)
    Dim objOU
    Dim objGroup
    Set objOU = GetObject(strADSPath)
    objOU.Filter = Array("group")
    For Each objGroup In objOU
        If bolFirstPass Then
            bolFirstPass = False
            ReDim arrGroupNames(0)
            ReDim arrGroupPaths(0)
        Else
            ReDim Preserve arrGroupNames(UBound(arrGroupNames) + 1)
            ReDim Preserve arrGroupPaths(UBound(arrGroupPaths) + 1)
        End If
        arrGroupNames(UBound(arrGroupNames)) = Mid(objGroup.Name, 4)
        arrGroupPaths(UBound(arrGroupPaths)) = objGroup.ADsPath
    Next
End Sub

0
 
LVL 2

Author Comment

by:mjasic
ID: 12204497
Thanks a lot, it worked :)
I just had to change a piece of code:

Dim strWebsence
strWebsence = myrs("websencegrp")
...
For x = 0 to (UBound(arrGroupNames) - 1)
'    If UBound(x) = strWebsence Then   ' Replaced by the following line, because in DB I hawe only the name of the group (that was the cause of the trouble of adding to the group):
     If instr(arrGroupPaths(x), strWebsence) > 0 Then
        Set objGroup = GetObject(arrGroupPaths(x))
        'Code to add the user to the group
        objGroup.Add ("Ldap:/CN=" & strCN & "," & strOU
        Exit For
    End If
Next

Thanks again, you deserved every point I give you.
0
 
LVL 76

Expert Comment

by:David Lee
ID: 12204538
No problem.  Glad I could help.  Cheers.
0
 
LVL 2

Author Comment

by:mjasic
ID: 12205926
Hello BlueDevilFan,

It is not against the rules to give the extra points and I already did it in the past.

Mike
0
 
LVL 76

Expert Comment

by:David Lee
ID: 12206863
Ok.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now