Johny Clelland

Active Directory Scripts

290 posts in this topic

#1 ·  Posted (edited)

I converted some of the standard VBS scripts in AutoIT format and put them together in an AU library. Haven't neatened up the names of the functions, but perhaps they will be useful anyway. If anyone has any suggestions of other AD Functions they would like to see, or that they would like to share, then let me know.

; Active Directory Function Library. Include this to allow access to Active Directory Functions

adfunctions.zip

; CreateUser : Creates a user in a particular OU

; CreateGroup : Creates a group in a particular OU

; AddUserToGroup : Adds a user to a group (if the user is not already a member of the group)

; RemoveUserFromGroup : Removes a user from a group

; ObjectExists : Returns 1 if the given object (SamAccountName) exists in the local AD Tree

; ModifyAttribute : Sets the attribute of the given object to the value specified

; IsMemberOf : Returns 1 if the user is a member of the group

; GetUserGroups : Returns an array (byreference) containing the groups that the user is a member of

; HasFullRights : Returns 1 if the given user has full rights over the given group

; GroupMailEnable : Mail enables a group

; UserCreateMailbox : Creates a mailbox for a user

; UserDeleteMailbox : Deletes the mailbox for a user

Edit: Added function library to first post.

Edited by big_daddy

Share this post


Link to post
Share on other sites



I converted some of the standard VBS scripts in AutoIT format and put them together in an AU library. Haven't neatened up the names of the functions, but perhaps they will be useful anyway. If anyone has any suggestions of other AD Functions they would like to see, or that they would like to share, then let me know.

Great, I could really use this. :lmao:

A request: get a list of members from a group. ;)

Share this post


Link to post
Share on other sites

Great, I could really use this. :D

A request: get a list of members from a group. :P

; GetGroupMembers

; Arguments,

; $members - Array that the result will be stored in

; $group - Group to retrieve members from

; $sort - optional, default 0 : Set to 1 to sort the array

; Returns an array to $members where $members[0] will be the number of users in the group and

; $members[1] to $members[$members[0]] are the distinguished names of the users

Func GetGroupMembers(ByRef $members, $group, $sort = 0)

If ObjectExists($group) = 0 Then Return 0

Dim $objConnection, $oUsr, $objCommand

Local $groups

$objConnection = ObjCreate("ADODB.Connection") ; Create COM object to AD

$objCommand = ObjCreate("ADODB.Command")

$objConnection.Provider = "ADsDSOObject"

$objConnection.Open ("Active Directory Provider") ; Open connection to AD

$objCommand.ActiveConnection = $objConnection

$objCommand.Properties ("Searchscope") = 2

$objRootDSE = ObjGet("LDAP://RootDSE")

Global $strDNSDomain = $objRootDSE.Get ("defaultNamingContext") ; Retrieve the current AD domain name

$strCmdText = "<LDAP://" & $strDNSDomain & ">;(sAMAccountName=" & $group & ");distinguishedname;Subtree"

$objCommand.CommandText = $strCmdText

$objRecordSet = $objCommand.Execute

$ObjGroup = ObjGet("LDAP://" & $objRecordSet.fields ("DistinguishedName").Value)

Dim $members[1]

$i = 0

While 1

$rangemodifier = $i * 1000

$range = "Range=" & $rangemodifier & "-" & $rangemodifier + 999

$strCmdText = "<LDAP://" & $objGroup.distinguishedname & ">;;member;" & $range & ";base"

$objCommand.CommandText = $strCmdText

$objRecordSet = $objCommand.Execute

$membersadd = $objRecordSet.fields (0).Value

If $membersadd = 0 Then ExitLoop

For $j = 0 To 999

_ArrayAdd($members, $membersadd[$j])

Next

$i += 1

$objRecordSet.Close

WEnd

$rangemodifier = $i * 1000

$range = "Range=" & $rangemodifier & "-*"

$strCmdText = "<LDAP://" & $objGroup.distinguishedname & ">;;member;" & $range & ";base"

$objCommand.CommandText = $strCmdText

$objRecordSet = $objCommand.Execute

$membersadd = $objRecordSet.fields (0).Value

For $j = 0 To UBound($membersadd) - 1

_ArrayAdd($members, $membersadd[$j])

Next

$objRecordSet.Close

$members[0] = UBound($members) - 1

If $sort = 1 Then

_ArraySort($members, 0, 1)

EndIf

Return 1

EndFunc ;==>GetGroupMembers

Share this post


Link to post
Share on other sites

CreateComputer would also be nice

Full new version. Includes some updates to previous functions to make them work faster. Note that some functions may have changed their parameters (I may have added options to the end of some, e.g. the ability to sort within a function).

Comments/questions most welcome.

CreateComputer added along with a few other functions;

; GetObjectsInOU -- Retrieves Data on items in an OU. Can return anything defined by a LDAP filter query

; DNToSamAccountName -- Returns a SamAccountName (pre-windows 2000 account name) from a FQDN

; DNToDisplayName -- Returns a Display Name from a FQDN

; CreateObject -- Creates an object in the given OU with the type specified (you would probably need to use ModifyAttribute after creation to set details).

; CreateComputer -- Creates a computer account in an OU and assigns an account (user or group) with permission to add the computer

; GetGroupMembers -- Returns an array of the DNs of members in a group

Share this post


Link to post
Share on other sites

Johny... this is really great stuff... specially with only having 4 posts here at the forums...

Just as a note, it is normally better to update the first post with your added functions or version updates. that way the best stuff is in the first post

maybe you could use version releases

8)


NEWHeader1.png

Share this post


Link to post
Share on other sites

erf, i always wanted to make it for community, but too lazy :/

btw, i can add AD search advanced function to yours

and some function to manage users

just say me what functions you want more, and i will do it


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

Johny,

This is very useful.

Not a big deal, but you might want to consider requesting a mod to move this to the Example Scripts forum, as this is normally where functional code is posted.

VW

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Wow this is awesome, so useful.

Has anyone got an example of some usage?

arcker - That would be awesome!

Somewhere , there is a conflict in these statements...

I doubt if there will be much use for you unless you are running a Mickeysoft AD environment ... :P

Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Johny... this is really great stuff... specially with only having 4 posts here at the forums...

Just as a note, it is normally better to update the first post with your added functions or version updates. that way the best stuff is in the first post

maybe you could use version releases

8)

I can't Edit my post for some reason, otherwise I would update it properly. Perhaps a mod can help me? Or perhaps, as someone else suggested, this could be moved to the Example Scripts forum. Anyway, here's the latest version (with version number 2.0) and a sample AD Tool that includes some extra functions for displaying an AD tree in a treeview control.

NOTE -- The biggest change is that I've re-named all the functions to _ADxxx to conform to the standard UDF format The functions available are listed in the file.

The ADTool is very much a work-in-progress, but it demonstrates some of the capabilities of the library quite well (currently the only functions that work are the Display group members/membership and the add/remove user-to-group buttons, the create/delete group buttons don't do anything yet).

Comments/suggestions always welcome.

Johny.

Edited by Johny Clelland

Share this post


Link to post
Share on other sites

I can't Edit my post for some reason, otherwise I would update it properly. Perhaps a mod can help me? Or perhaps, as someone else suggested, this could be moved to the Example Scripts forum. Anyway, here's the latest version (with version number 2.0) and a sample AD Tool that includes some extra functions for displaying an AD tree in a treeview control.

NOTE -- The biggest change is that I've re-named all the functions to _ADxxx to conform to the standard UDF format The functions available are listed in the file.

The ADTool is very much a work-in-progress, but it demonstrates some of the capabilities of the library quite well (currently the only functions that work are the Display group members/membership and the add/remove user-to-group buttons, the create/delete group buttons don't do anything yet).

Comments/suggestions always welcome.

Johny.

nothing to say, i've looked your function, and they are perfect because simple, line mines

maybe one thing => the ad object exists

good one the use of recordcount, but i'm not using it anymore, because a little bit lnger than do

if $objrecordset.EOF then
return 0 ;object doesn't exists
endif
oÝ÷ Ù»­nÜ"¶Ç̨ºIè·°zYZuû§rبÊ"Â)e¶¼­¢²¢æ¬²'jÊh²Èëh~)Ú+&⫨µ§Z׫«^iÙ¢+-­«b¢{h¢Z®¢ÜºÇ¢¶)è¹÷â®f ¢Zaz»axºÚ"µÍÌÍÛÓØXÝ]
    ÌÍØ]X]K  ÌÍÝ[YJB

you just have to do $object.attributename = something, but i know that in your function, you use $attribute as a variable,

but it's just to precise for users that .put is not the only way

ouffffff

here you go, welcome to the autoit community


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

to prove that i'm not a lier ^^

here is my "secret" memberof test

it only use ldap query to return is the member is or not memberof

; _ADIsMemberOf
; Takes the groupname (SamAccountName with or without the leading 'CN=', and the SamAccountName of the user
; Returns 1 if the the user is a member of the group, 0 otherwise
; Alternate test by Arcker, uses only AD search
; really fast

Func _ADIsMemberOf($group, $user)
    If StringLeft($group, 3) <> "CN=" Then
        $group = "CN=" & $group
    EndIf
    Dim $usergroups[1], $i = 1

    Dim $objConnection, $oUsr,$groupdn
    
    
    $objConnection = ObjCreate("ADODB.Connection")  ; Create COM object to AD
    $objConnection.Provider = "ADsDSOObject"
    $objConnection.Open ("Active Directory Provider")  ; Open connection to AD
    $objRootDSE = ObjGet("LDAP://RootDSE")
    Global $strDNSDomain = $objRootDSE.Get ("defaultNamingContext")  ; Retrieve the current AD domain name

    $strQuery = "<LDAP://" & $strDNSDomain & ">;(" &$group& ");distinguishedName;subtree"
    $objRecordSet = $objConnection.Execute ($strQuery)  ; Retrieve the FQDN for the logged on user
    if $objRecordSet.eof then
        SetError(2)
        Return 0 ;group non found
    Else
        $groupdn=$objRecordSet.fields(0).value
    EndIf   
    $strQuery = "<LDAP://" & $strDNSDomain & ">;((sAMAccountName=" & $user & ")(memberof="&$groupdn&"));ADsPath;subtree"
    $objRecordSet = $objConnection.Execute ($strQuery)  ; Retrieve the FQDN for the logged on user
    if $objRecordSet.eof then
        SetError(1)
        Return 0
    Else
        return 1
    EndIf   
    
EndFunc   ;==>_ADIsMemberOf

-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

$strQuery = "<LDAP://" & $strDNSDomain & ">;((sAMAccountName=" & $user & ")(memberof="&$groupdn&"));ADsPath;subtree"

$objRecordSet = $objConnection.Execute ($strQuery) ; Retrieve the FQDN for the logged on user

if $objRecordSet.eof then

SetError(1)

Return 0

Else

return 1

EndIf

EndFunc ;==>_ADIsMemberOf

[/autoit]

arcker -- I like the use of the LDAP query structure to do this. I didn't know enough about the LDAP filter to write this when I wrote IsMemberOf (have learnt a lot since, but clearly still have some way to go). If it's OK with you I'll put this in the ADFunction library.

Also noticed that you've included some extra error checking and error returns. When I start writing this it was intended that the controlling program would handle the error checking (and never provide something like a group that doesn't exist), but I can understand the need to have this in the library. If I can find the time I will go through the library and set up a proper seterror structure for the functions, and possibly some extra errorchecking.

Perhaps there are other queries that would benefit from a better understanding of the LDAP filter structure.

Thanks,

Johny.

Edited by Johny Clelland

Share this post


Link to post
Share on other sites

arcker -- I like the use of the LDAP query structure to do this. I didn't know enough about the LDAP filter to write this when I wrote IsMemberOf (have learnt a lot since, but clearly still have some way to go). If it's OK with you I'll put this in the ADFunction library.

no problem,

i've discovered this function alone, and it took me about 1 month, because i really need something more powerful than go in a table etc...

you can retrieve all the member of a group with this method too

ofr the errors, i never use seterror, i prefer to use the objevent to catch the com error, because the descriptions are really clear (like "object already exists" and more)

if you need more help, pm me


-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

Projects :

[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]

Share this post


Link to post
Share on other sites

Great tool, am using it a lot.

One thing I noticed with the _ADGetObjectAttribute

If there are multible values for the attribute it returns empty string.

It would be great to get all the results in array.

Have been trying to do this but not understanding the com stuff.

Here is a example for what I am trying to do in vbs

Set MyUser = GetObject ("LDAP://CN=Administrator,CN=Users,DC=domainname,DC=local")

Secondary = ""

For each email in MyUser.proxyAddresses

If Left (email,5) = "SMTP:" Then

WScript.Echo "Primary e-mail address: " & Mid (email,6)

ElseIf Left (email,5) = "smtp:" Then

Secondary = Secondary & "," & Mid (email,6)

End If

Next

If Secondary <> "" Then WScript.Echo "Other e-mail addresses: " & Mid (Secondary,2)

Share this post


Link to post
Share on other sites

; GetGroupMembers

; Arguments,

; $members - Array that the result will be stored in

; $group - Group to retrieve members from

......

Thanx a lot.

I am trying to make a custom toolbox for myself to do some AD stuff. I use DSADD, DSGET and so on, but I was planning on using VB in the future. Only I can't figure it out, zero knowledge of VB, but I think I'll manage with you scripts. :P

Share this post


Link to post
Share on other sites

Johny,

could you add a function that creates a user based on a user template?

Your scripts are what I'm looking for. Thank you very much!!

In one of your posts you write about version 2.0 and a sample application. Could you point me to the download location ? I cannot find it.

--egonle

Share this post


Link to post
Share on other sites

Ok,

I managed to find the downloads :P .

I played around with differnet functions. Unfortunately I cannot get delete a group object using function _ADDeleteObject(<groupname>). How can I find the error itself? Looking at other ADSI scripts and e.g. adsi scriptomatic they use code like this:

strContainer = ""
strName = "EzAdGroup"

'***********************************************
'*       Connect to a container           *
'***********************************************
Set objRootDSE = GetObject("LDAP://rootDSE")
If strContainer = "" Then
  Set objContainer = GetObject("LDAP://" & _
    objRootDSE.Get("defaultNamingContext"))
Else
  Set objContainer = GetObject("LDAP://" & strContainer & "," & _
    objRootDSE.Get("defaultNamingContext"))
End If
'***********************************************
'*     End connect to a container           *
'***********************************************

objContainer.Delete "group", "cn=" & strName

Especially .Delete has two options. Is that a required difference compared to adfunctions.au3 code?

Thanks

---egonle

PS: Would you add a function to copy users from templates?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now