; Active Directory Function Library. Include this to allow access to Active Directory Functions ; Author : Jonthan Clelland ; Email : jclelland@statestreet.com ; Version : 3.0 ; _ADDoError : Error event handler for COM errors. This is global so will pick up errors from your program if you include this library ; _ADCreateUser : Creates a user in a particular OU ; _ADCreateGroup : Creates a group in a particular OU ; _ADAddUserToGroup : Adds a user to a group (if the user is not already a member of the group) ; _ADRemoveUserFromGroup : Removes a user from a group ; _ADObjectExists : Returns 1 if the given object (SamAccountName) exists in the local AD Tree ; _ADModifyAttribute : Sets the attribute of the given object to the value specified ; _ADIsMemberOf : Returns 1 if the user is a member of the group ; _ADGetUserGroups : Returns an array (byreference) containing the groups that the user is a member of ; _ADRecursiveGetMemberOf : Returns a recursed list of group membership for a group or user ; _ADGetGroupMembers : Returns an array of the group members ; _ADGetGroupMemberOf : Returns a simple list of group membership for a group ; _ADHasFullRights : Returns 1 if the given user has full rights over the given group ; _ADGroupMailEnable : Mail enables a group ; _ADUserCreateMailbox : Creates a mailbox for a user ; _ADUserDeleteMailbox : Deletes the mailbox for a user ; _ADGetObjectsInOU : Returns a filtered list of objects and attributes in a given OU ; _ADDNToSamAccountName : Returns the SamAccountName of an FQDN ; _ADSamAccountNameToFQDN : Returns a FQDN from a SamAccountName ; _ADDNToDisplayName :Returns the Display Name of an FQDN ; _ADCreateObject : Creates an object of a specified type ; _ADCreateComputer : Creates a computer and assigns permissions for a user/group to add the computer ; _ADDeleteObject : Deletes an object ; _ADGetObjectClass : Returns the class of an object ; _ADGetObjectClassFromFQDN : Returns the class of an object from it's FQDN ; _ADGetObjectAttribute : Returns a (single-value) attribute of an object ; _ADListDomainControllers : Returns a list of Domain Controllers for the current domain ; _ADOUObjectNames : Returns display names of filtered objects within an OU ; _ADGroupManagerCanModify : Returns 1 if the manager of the group can modify the member list, 0 if not, -1 if there is no manager assigned ; _ADAddAccountToMailboxRights : Adds useraccount to mailbox with full rights and send as permissions. ; NOTES : Please use the following command to store the local user's groups for the function 'HasFullRights'. This is to allow cross-domain ; permission checks. $loggedonusergroups is a global variable declared in the 'Define AD Constants' region. If you are using this command ; in this library, move the command below the declaration of the variable and remove the comment charcater. ; _ADRecursiveGetMemberOf ($loggedonusergroups, _ADSamAccountNameToFQDN (@UserName)) ; include array functions (we use _arraysearch in some functions) #include #region ; Define AD Constants Global Const $ADS_GROUP_TYPE_GLOBAL_GROUP = 0x2 Global Const $ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 0x4 Global Const $ADS_GROUP_TYPE_UNIVERSAL_GROUP = 0x8 Global Const $ADS_GROUP_TYPE_SECURITY_ENABLED = 0x80000000 Global Const $ADS_GROUP_TYPE_GLOBAL_SECURITY = BitOR($ADS_GROUP_TYPE_GLOBAL_GROUP, $ADS_GROUP_TYPE_SECURITY_ENABLED) Global Const $ADS_GROUP_TYPE_UNIVERSAL_SECURITY = BitOR($ADS_GROUP_TYPE_UNIVERSAL_GROUP, $ADS_GROUP_TYPE_SECURITY_ENABLED) Global Const $ADS_GROUP_TYPE_DOMAIN_LOCAL_SECURITY = BitOR($ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP, $ADS_GROUP_TYPE_SECURITY_ENABLED) Global Const $ADS_UF_PASSWD_NOTREQD = 0x0020 Global Const $ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x1000 Global Const $ADS_ACETYPE_ACCESS_ALLOWED = 0x0 Global Const $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = 0x5 Global Const $ADS_FLAG_OBJECT_TYPE_PRESENT = 0x1 Global Const $ADS_RIGHT_GENERIC_READ = 0x80000000 Global Const $ADS_RIGHT_DS_SELF = 0x8 Global Const $ADS_RIGHT_DS_WRITE_PROP = 0x20 Global Const $ADS_RIGHT_DS_CONTROL_ACCESS = 0x100 Global Const $ADS_UF_ACCOUNTDISABLE = 2 Global Const $ADS_OPTION_SECURITY_MASK = 3 Global Const $ADS_SECURITY_INFO_DACL = 4 Global Const $ALLOWED_TO_AUTHENTICATE = "{68B1D179-0D15-4d4f-AB71-46152E79A7BC}" Global Const $RECEIVE_AS = "{AB721A56-1E2f-11D0-9819-00AA0040529B}" Global Const $SEND_AS = "{AB721A54-1E2f-11D0-9819-00AA0040529B}" Global Const $USER_CHANGE_PASSWORD = "{AB721A53-1E2f-11D0-9819-00AA0040529b}" Global Const $USER_FORCE_CHANGE_PASSWORD = "{00299570-246D-11D0-A768-00AA006E0529}" Global Const $USER_ACCOUNT_RESTRICTIONS = "{4C164200-20C0-11D0-A768-00AA006E0529}" Global Const $VALIDATED_DNS_HOST_NAME = "{72E39547-7B18-11D1-ADEF-00C04FD8D5CD}" Global Const $VALIDATED_SPN = "{F3A64788-5306-11D1-A9C5-0000F80367C1}" Const $Member_SchemaIDGuid = "{BF9679C0-0DE6-11D0-A285-00AA003049E2}" Global $objConnection = ObjCreate("ADODB.Connection") ; Create COM object to AD $objConnection.ConnectionString = "Provider=ADsDSOObject" $objConnection.Open ("Active Directory Provider") ; Open connection to AD Global $objRootDSE = ObjGet("LDAP://RootDSE") Global $strDNSDomain = $objRootDSE.Get ("defaultNamingContext") ; Retrieve the current AD domain name Global $strHostServer = $objRootDSE.Get ("dnsHostName") ; Retrieve the name of the connected DC Global $strConfiguration = $objRootDSE.Get ("ConfigurationNamingContext") ; Retrieve the Configuration naming context Global $loggedonusergroups ; populate this with the logged on user groups in your own app #endregion $oMyError = ObjEvent("AutoIt.Error", "_ADDoError") ; Install a custom error handler ; MyErrFunc Func _ADDoError() $HexNumber = Hex($oMyError.number, 8) If $HexNumber = 80020009 Then SetError(3) Return EndIf If $HexNumber = "8007203A" Then SetError(4) Return EndIf MsgBox(262144, "", "We intercepted a COM Error !" & @CRLF & _ "Number is: " & $HexNumber & @CRLF & _ "Windescription is: " & $oMyError.windescription & @CRLF & _ "Script Line number is: " & $oMyError.scriptline) Select Case $oMyError.windescription = "Access is denied." $objConnection.Close ("Active Directory Provider") $objConnection.Open ("Active Directory Provider") SetError(2) Case 1 SetError(1) EndSelect EndFunc ;==>_ADDoError ; _ADCreateUser ; $userou = OU to create the group in. Form is "sampleou=ou, sampleparent=ou, sampledomain1=dc, sampledomain2=dc, sampledomain3=dc" ; $user = Username, form is SamAccountName without leading 'CN=' ; $fname = First Name ; $lname = Last Name ; $description = optional - Description Func _ADCreateUser($userou, $user, $fname, $lname, $description = "User") If _ADObjectExists($user) Then Return 0 $ObjOU = ObjGet("LDAP://" & $strHostServer & "/" & $userou) If $fname = "" Then $cnname = "CN=" & $lname Else $cnname = "CN=" & $lname & "\, " & $fname EndIf $ObjUser = $ObjOU.Create ("User", $cnname) $ObjUser.Put ("sAMAccountName", $user) $ObjUser.Put ("description", $description) $ObjUser.SetInfo Return 1 EndFunc ;==>_ADCreateUser ; _ADCreateGroup ; $gruopou = OU to create the group in. Form is "sampleou=ou, sampleparent=ou, sampledomain1=dc, sampledomain2=dc, sampledomain3=dc" ; $group = groupname, form is SamAccountName without leading 'CN=' ; $type = Group type. Defaults to Global Security. See the global constands for other types. NOTE Global security must be 'BitOr'ed with a scope. Func _ADCreateGroup($groupou, $group, $type = -2147483646) If _ADObjectExists($group) Then Return 0 If StringLeft($group, 3) <> "CN=" Then $groupcn = "CN=" & $group Else $groupcn = $group EndIf $groupcn = StringReplace($groupcn,"#","\#") $groupcn = StringReplace($groupcn,",","\,") $groupcn = StringReplace($groupcn, "/","\/") $ObjOU = ObjGet("LDAP://" & $strHostServer & "/" & $groupou) $ObjGroup = $ObjOU.Create ("Group", $groupcn) $groupsam = StringReplace($group, ",", " ") $groupsam = StringReplace($groupsam, "#", " ") $groupsam = StringReplace($groupsam, "/", " ") $ObjGroup.Put ("sAMAccountName", $groupsam) $ObjGroup.Put ("grouptype", $type) $ObjGroup.SetInfo Return 1 EndFunc ;==>_ADCreateGroup ; _ADAddUserToGroup ; Takes the group (SamAccountName without leading 'CN=') and the user (SamAccountName without leading 'CN=') ; Adds the user to the group ; Returns 0 if the user is already a member of the group, ; Returns 1 if the user was added to the group ; Returns -1 if there was an error Func _ADAddUserToGroup($group, $user) If _ADIsMemberOf($group, $user) Then Return 0 $oUsr = ObjGet("LDAP://" & $strHostServer & "/" & $user) ; Retrieve the COM Object for the user $oGroup = ObjGet("LDAP://" & $strHostServer & "/" & $group) ; Retrieve the COM Object for the group $OGroup.Add ($oUsr.AdsPath) $OGroup.SetInfo $oGroup = 0 $oUser = 0 Return _ADIsMemberOf($group, $user) EndFunc ;==>_ADAddUserToGroup ; _ADRemoveUserFromGroup ; Takes the group (SamAccountName without leading 'CN=') and the user (SamAccountName without leading 'CN=') ; Removes the user from the group (if the user is a member of the group) ; Returns 0 if the user isn't a member of the group, 1 if the user was removed from the group ; Returns -1 if the removal failed. Func _ADRemoveUserFromGroup($group, $user) If _ADIsMemberOf($group, $user) = 0 Then Return 0 $oUsr = ObjGet("LDAP://" & $strHostServer & "/" & $user) ; Retrieve the COM Object for the user $oGroup = ObjGet("LDAP://" & $strHostServer & "/" & $group) ; Retrieve the COM Object for the group $oGroup.Remove ($oUsr.AdsPath) $OGroup.SetInfo $oGroup = 0 $oUser = 0 If _ADIsMemberOf($group, $user) Then Return -1 Else Return 1 EndIf EndFunc ;==>_ADRemoveUserFromGroup ; _ADObjectExists ; Takes an object name (SamAccountName without leading 'CN=') ; Returns 1 if the object exists in the tree, 0 otherwise Func _ADObjectExists($object) $strQuery = ";(sAMAccountName=" & $object & ");ADsPath;subtree" $objRecordSet = $ObjConnection.Execute ($strQuery) ; Retrieve the FQDN for the group, if it exists If $objRecordSet.RecordCount = 1 Then $objRecordSet = 0 Return 1 Else $objRecordSet = 0 Return 0 EndIf EndFunc ;==>_ADObjectExists ; _ADModifyAttribute ; $object = Object to modify (samAccountName) ; $attribute = Attribute to modify ; $value = value to set attribute to, use a blank string "" to delete an attribute Func _ADModifyAttribute($object, $attribute, $value, $attrtype) $strQuery = ";(sAMAccountName=" & $object & ");ADsPath;subtree" $objRecordSet = $ObjConnection.Execute ($strQuery) ; Retrieve the FQDN for the object $ldap_entry = $objRecordSet.fields (0).value $oObject = ObjGet($ldap_entry) ; Retrieve the COM Object for the object $oObject.GetInfo If $value = "" Then $oObject.PutEx (1, $attribute, 0) Else $oObject.Put ($attribute, $value) EndIf $oObject.SetInfo $oObject.PurgePropertyList $oObject = 0 Return 1 EndFunc ;==>_ADModifyAttribute ; _ADIsMemberOf ; Takes samAccountNames for a group and a user ; Returns 1 if the the user is a member of the group, 0 otherwise Func _ADIsMemberOf($group, $user) $ObjGroup = ObjGet("LDAP://" & $strHostServer & "/" & $group) $ismember = $objGroup.IsMember ("LDAP://" & $strHostServer & "/" & $user) $ObjGroup = 0 Return -$ismember EndFunc ;==>_ADIsMemberOf ; _ADGetUserGroups ; the currently logged on user is a member of. Returns an array of Full DNs of the Group names that the user is immediately a member of ; with element 0 containing the number of groups. ; $user - optional -- SamAccountName of a user, defaults to locally logged on user Func _ADGetUserGroups(ByRef $usergroups, $user = @UserName) Local $oUsr $strQuery = ";(sAMAccountName=" & $user & ");ADsPath;subtree" $objRecordSet = $objConnection.Execute ($strQuery) ; Retrieve the FQDN for the logged on user $ldap_entry = $objRecordSet.fields (0).value $oUsr = ObjGet($ldap_entry) ; Retrieve the COM Object for the logged on user $usergroups = $oUsr.GetEx ("memberof") $oUsr = 0 $count = UBound($usergroups) _ArrayInsert($usergroups, 0, $count) EndFunc ;==>_ADGetUserGroups ; _ADRecursiveGetMemberOf ; Takes a Full DN of a group or user and returns a recursively searched list of groups the object is a member of to the array ; This will traverse through groups that the object is immediately a member of and check their group membership as well. ; The return values are full DNs. For groups that are inherited, the return is the DN of the group, and the DN of the first group ; it was inherited from, seperated by '|'. Func _ADRecursiveGetMemberOf(ByRef $memberof, $fqdn) Local $objItem, $tempmemberof, $i = 0 $objItem = ObjGet("LDAP://" & $strHostServer & "/" & $fqdn) ; Retrieve the COM Object for the logged on user $memberof = $objItem.GetEx ("memberof") $objItem = 0 If $memberof = 0 Then Dim $memberof[1] = [0] Return 0 EndIf Do If StringInStr($memberof[$i], "|") Then $currgroup = StringLeft($memberof[$i], StringInStr($memberof[$i], "|") - 1) Else $currgroup = $memberof[$i] EndIf $currgroup = StringReplace($currgroup, "/", "\/") _ADGetGroupMemberOf($tempmemberof, $currgroup) For $j = 1 To $tempmemberof[0] $exists = 0 $k = UBound($memberof) Do $k -= 1 If StringInStr($memberof[$k], $tempmemberof[$j]) Then $exists = 1 Until $exists = 1 Or $k = 0 If $exists = 0 Then _ArrayAdd($memberof, $tempmemberof[$j] & "|" & $currgroup) Next $i += 1 Until $i = UBound($memberof) $count = UBound($memberof) _ArrayInsert($memberof, 0, $count) Return 1 EndFunc ;==>_ADRecursiveGetMemberOf ; _ADRecursiveGetGroupMembers ; Takes a Full DN of a group and returns a recursively searched list of members of that group (and groups that are members of the group) ; The return values are full DNs. For groups that are inherited, the return is the DN of the group, and the DN of the first group ; it was inherited from, seperated by '|'. Func _ADRecursiveGetGroupMembers(ByRef $members, $fqdn) Local $objItem, $tempmembers, $i = 1 ;$objItem = ObjGet("LDAP://" & $strHostServer & "/" & $fqdn) ; Retrieve the COM Object for the logged on user _ADGetGroupMembers($members, $fqdn) If $members[0] = 0 Then Return 0 EndIf Do If StringInStr($members[$i], "|") Then $currgroup = StringLeft($members[$i], StringInStr($members[$i], "|") - 1) Else $currgroup = $members[$i] EndIf $currgroup = StringReplace($currgroup, "/", "\/") If _ADGetObjectClassFromFQDN($currgroup) = "group" Then _ADGetGroupMembers($tempmembers, $currgroup) For $j = 1 To $tempmembers[0] $exists = 0 $k = UBound($members) Do $k -= 1 If StringInStr($members[$k], $tempmembers[$j]) Then $exists = 1 Until $exists = 1 Or $k = 0 If $exists = 0 Then _ArrayAdd($members, $tempmembers[$j] & "|" & $currgroup) Next EndIf $i += 1 Until $i = UBound($members) $count = UBound($members) ;_ArrayInsert($members, 0, $count) $members[0] = $count - 1 Return 1 EndFunc ;==>_ADRecursiveGetGroupMembers ; _ADGetGroupMembers ; 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 _ADGetGroupMembers(ByRef $members, $groupdn, $sort = 0) ;If _ADObjectExists($group) = 0 Then Return 0 Local $oUsr, $objCommand, $groups $objCommand = ObjCreate("ADODB.Command") $objCommand.ActiveConnection = $objConnection $objCommand.Properties ("Searchscope") = 2 Dim $members[1] $i = 0 While 1 $rangemodifier = $i * 1000 $range = "Range=" & $rangemodifier & "-" & $rangemodifier + 999 $strCmdText = ";;member;" & $range & ";base" $objCommand.CommandText = $strCmdText $objRecordSet = $objCommand.Execute $membersadd = $objRecordSet.fields (0).Value If $membersadd = 0 Then ExitLoop ReDim $members[UBound($members) + 1000] For $j = $rangemodifier + 1 To $rangemodifier + 1000 $members[$j] = $membersadd[$j - $rangemodifier - 1] Next $i += 1 $objRecordSet.Close WEnd $rangemodifier = $i * 1000 $range = "Range=" & $rangemodifier & "-*" $strCmdText = ";;member;" & $range & ";base" $objCommand.CommandText = $strCmdText $objRecordSet = $objCommand.Execute $membersadd = $objRecordSet.fields (0).Value ReDim $members[UBound($members) + UBound($membersadd) ] For $j = $rangemodifier + 1 To $rangemodifier + UBound($membersadd) $members[$j] = $membersadd[$j - $rangemodifier - 1] Next $objRecordSet.Close $objCommand = 0 $objRecordSet = 0 $members[0] = UBound($members) - 1 If $sort = 1 Then _ArraySort($members, 0, 1) EndIf Return 1 EndFunc ;==>_ADGetGroupMembers ; _ADGetGroupMemberOf Func _ADGetGroupMemberOf(ByRef $memberof, $groupdn, $sort = 0) Local $oUsr, $objCommand, $groups $objCommand = ObjCreate("ADODB.Command") $objCommand.ActiveConnection = $objConnection $objCommand.Properties ("Searchscope") = 2 Dim $memberof[1] $i = 0 While 1 $rangemodifier = $i * 1000 $range = "Range=" & $rangemodifier & "-" & $rangemodifier + 999 $strCmdText = ";;memberof;" & $range & ";base" $objCommand.CommandText = $strCmdText $objRecordSet = $objCommand.Execute $membersadd = $objRecordSet.fields (0).Value If $membersadd = 0 Then ExitLoop ReDim $memberof[UBound($memberof) + 1000] For $j = $rangemodifier + 1 To $rangemodifier + 1000 $memberof[$j] = $membersadd[$j - $rangemodifier - 1] Next $i += 1 $objRecordSet.Close WEnd $rangemodifier = $i * 1000 $range = "Range=" & $rangemodifier & "-*" $strCmdText = ";;memberof;" & $range & ";base" $objCommand.CommandText = $strCmdText $objRecordSet = $objCommand.Execute $membersadd = $objRecordSet.fields (0).Value ReDim $memberof[UBound($memberof) + UBound($membersadd) ] For $j = $rangemodifier + 1 To $rangemodifier + UBound($membersadd) $memberof[$j] = $membersadd[$j - $rangemodifier - 1] Next $objRecordSet.Close $objCommand = 0 $objRecordSet = 0 $memberof[0] = UBound($memberof) - 1 If $sort = 1 Then _ArraySort($memberof, 0, 1) EndIf Return $memberof[0] EndFunc ;==>_ADGetGroupMemberOf ; _ADHasFullRights ; Take an object's SamAccountName, a user's SamAccountName ; Returns 1 if User has full rights on the object ; Returns 0 otherwise Func _ADHasFullRights($object, $user = @UserName) Dim $hfr_groups If $user = @UserName Then $hfr_groups = $loggedonusergroups Else _ADGetUserGroups($hfr_groups, $user) EndIf $oObject = ObjGet("LDAP://" & $strHostServer & "/" & $object) If IsObj($oObject) Then $security = $oObject.Get ("ntSecurityDescriptor") $dacl = $security.DiscretionaryAcl For $ace In $dacl $trusteearray = StringSplit($ace.Trustee, "\") $trusteegroup = $trusteearray[$trusteearray[0]] For $i = 0 To UBound($hfr_groups) - 1 If StringInStr($hfr_groups[$i], "CN=" & $trusteegroup) And $ace.AccessMask = 983551 Then Return 1 Next Next EndIf $oObject = 0 $security = 0 $dacl = 0 Return 0 EndFunc ;==>_ADHasFullRights ; _ADGroupMailEnable ; Takes a group and enables mail on that group Func _ADGroupMailEnable($group) If _ADObjectExists($group) = 0 Then Return 0 $strQuery = ";(sAMAccountName=" & $group & ");ADsPath;subtree" $objRecordSet = $ObjConnection.Execute ($strQuery) ; Retrieve the FQDN for the group, if it exists $ldap_entry = $objRecordSet.fields (0).value $oGroup = ObjGet($ldap_entry) ; Retrieve the COM Object for the object $oGroup.Put ("grouptype", $ADS_GROUP_TYPE_UNIVERSAL_SECURITY) $oGroup.MailEnable $OGroup.SetInfo $oGroup = 0 Return 1 EndFunc ;==>_ADGroupMailEnable ; _ADUserCreateMailbox ; $user - User to add mailbox to ; $mdbstore - Mailbox storename ; $store - Information store ; $server - Email server ; $admingroup - Administrative group in Exchange ; $domain - Domain name Func _ADUserCreateMailbox($user, $mdbstore, $store, $server, $admingroup, $domain) If _ADObjectExists($user) = 0 Then Return 0 $strQuery = ";(sAMAccountName=" & $user & ");ADsPath;subtree" $objRecordSet = $ObjConnection.Execute ($strQuery) ; Retrieve the FQDN for the group, if it exists $ldap_entry = $objRecordSet.fields (0).value $oUser = ObjGet($ldap_entry) ; Retrieve the COM Object for the object If $oUser.HomeMDB <> "" Then Return 0 $mailboxpath = "LDAP://CN=" $mailboxpath = $mailboxpath & $mdbstore $mailboxpath = $mailboxpath & ",CN=" $mailboxpath = $mailboxpath & $store $mailboxpath = $mailboxpath & ",CN=InformationStore" $mailboxpath = $mailboxpath & ",CN=" $mailboxpath = $mailboxpath & $server $mailboxpath = $mailboxpath & ",CN=Servers,CN=" $mailboxpath = $mailboxpath & $admingroup $mailboxpath = $mailboxpath & ",CN=Administrative Groups,CN=State Street,CN=Microsoft Exchange,CN=Services,CN=Configuration," $mailboxpath = $mailboxpath & $domain $oUser.CreateMailbox ($mailboxpath) $oUser.SetInfo $oUser = 0 Return 1 EndFunc ;==>_ADUserCreateMailbox ; _ADUserDeleteMailbox ; Deletes a user's mailbox Func _ADUserDeleteMailbox($user) If _ADObjectExists($user) = 0 Then Return 0 $strQuery = ";(sAMAccountName=" & $user & ");ADsPath;subtree" $objRecordSet = $ObjConnection.Execute ($strQuery) ; Retrieve the FQDN for the group, if it exists $ldap_entry = $objRecordSet.fields (0).value $oUser = ObjGet($ldap_entry) ; Retrieve the COM Object for the object If $oUser.HomeMDB = "" Then Return 0 $oUser.DeleteMailbox $oUser.SetInfo $oUser = 0 Return 1 EndFunc ;==>_ADUserDeleteMailbox ; _ADGetObjectsInOU ; Returns an array of the objects in an OU ; $ou : The OU to retrieve from ; $filter : optional, default "name'*'". An additional LDAP filter if required. ; $searchscope : optional, default 2. 0 = base, 1 = one-level, 2 = sub-tree ; $datatoretrieve : optional, default "Name". A comma-seperated list of values to retrieve. More than one value will create ; a 2-dimensional array, array[0][0] will contain the number of items returned, which start at array[1][0] Func _ADGetObjectsInOU(ByRef $ObjectArray, $ou, $filter = "name='*'", $searchscope = 2, $datatoretrieve = "sAMAccountName", $sortby = "sAMAccountName") Local $objRecordSet $objCommand = ObjCreate("ADODB.Command") $objCommand.ActiveConnection = $objConnection $objCommand.Properties ("Page Size") = 256 $objCommand.Properties ("Searchscope") = $searchscope $objCommand.Properties ("TimeOut") = 20 $strCmdText = ";" & $filter & ";" & $datatoretrieve & ";subtree" $objCommand.CommandText = $strCmdText $objRecordSet = $objCommand.Execute $recordcount = $objRecordSet.RecordCount If $recordcount = 0 Then $objCommand = 0 $objRecordSet = 0 Return 0 EndIf If StringInStr($datatoretrieve, ",") Then $dtrArray = StringSplit($datatoretrieve, ",") Dim $ObjectArray[$recordcount + 1][$dtrArray[0]] $ObjectArray[0][0] = $recordcount $ObjectArray[0][1] = $dtrArray[0] $count = 1 $objRecordSet.MoveFirst Do For $i = 1 To $dtrArray[0] $ObjectArray[$count][$i - 1] = $objRecordSet.Fields ($dtrArray[$i]).Value Next $objRecordSet.MoveNext $count += 1 Until $objRecordSet.EOF Else Dim $ObjectArray[$recordcount + 1] $ObjectArray[0] = UBound($ObjectArray) - 1 If $ObjectArray[0] = 0 Then $ObjectArray = 0 Return 0 Else $count = 1 $objRecordSet.MoveFirst Do $ObjectArray[$count] = $objRecordSet.Fields ($datatoretrieve).Value $objRecordSet.MoveNext $count += 1 Until $objRecordSet.EOF EndIf EndIf $objCommand = 0 $objRecordSet = 0 Return 1 EndFunc ;==>_ADGetObjectsInOU ; _ADDNToSamAccountName ; Takes a FQDN and returns the SamID of the account Func _ADDNToSamAccountName($fqdn) $obj = ObjGet("LDAP://" & $strHostServer & "/" & $fqdn) If $obj = 0 Then MsgBox(262144, "", "Failed to retrieve AD object") Return 0 EndIf $samname = $obj.sAMAccountName $obj = 0 Return $samname EndFunc ;==>_ADDNToSamAccountName ; _ADSamAccountNameToFQDN ; Takes a SamID and returns the FQDN of the account Func _ADSamAccountNameToFQDN($samname) $strQuery = ";(sAMAccountName=" & $samname & ");distinguishedName;subtree" $objRecordSet = $objConnection.Execute ($strQuery) If $objRecordSet.RecordCount = 1 Then $fqdn = $objRecordSet.fields (0).value $objRecordSet = 0 Return StringReplace($fqdn, "/", "\/") Else $objRecordSet = 0 Return "" EndIf EndFunc ;==>_ADSamAccountNameToFQDN ; _ADDNToDisplayName ; Returns the Display Name of an FQDN Func _ADDNToDisplayName($fqdn) $objItem = ObjGet("LDAP://" & $strHostServer & "/" & $fqdn) $name = $objItem.name $objItem = 0 Return $name EndFunc ;==>_ADDNToDisplayName ; _ADCreateObject ; $objectou = OU to create the group in. Form is "sampleou=ou, sampleparent=ou, sampledomain1=dc, sampledomain2=dc, sampledomain3=dc" ; $object = Object name, form is SamAccountName without leading 'CN=' ; $type = Type of object to create Func _ADCreateObject($objectou, $object, $type) If _ADObjectExists($object) Then Return 0 If StringLeft($object, 3) <> "CN=" Then $object = "CN=" & $object EndIf $ObjOU = ObjGet("LDAP://" & $strHostServer & "/" & $objectou) $ObjADObj = $ObjOU.Create ($type, $object) $ObjADObj.Put ("sAMAccountName", StringTrimLeft($object, 3)) If $type = "Computer" Then $ObjADObj.Put ("UserAccountControl", BitOR(0x0020, 0x1000)) EndIf $ObjADobj.SetInfo $ObjADObj = 0 Return 1 EndFunc ;==>_ADCreateObject ; _ADCreateComputer ; $strComputer = Name of the computer object to create ; $computerOU = Full DN of the OU to create the computer in ; $strComputerUser = User or group that will be allowed to add the computer to the domain (SamAccountName) Func _ADCreateComputer($strComputer, $computerOU, $strComputerUser) $objContainer = ObjGet("LDAP://" & $strHostServer & "/" & $computerOU) $objComputer = $objContainer.Create ("Computer", "cn=" & $strComputer) $objComputer.Put ("sAMAccountName", $strComputer & "$") $objComputer.Put ("userAccountControl", BitOR($ADS_UF_PASSWD_NOTREQD, $ADS_UF_WORKSTATION_TRUST_ACCOUNT)) $objComputer.SetInfo $objSecurityDescriptor = $objComputer.Get ("ntSecurityDescriptor") $objDACL = $objSecurityDescriptor.DiscretionaryAcl $objACE1 = ObjCreate("AccessControlEntry") $objACE1.Trustee = $strComputerUser $objACE1.AccessMask = $ADS_RIGHT_GENERIC_READ $objACE1.AceFlags = 0 $objACE1.AceType = $ADS_ACETYPE_ACCESS_ALLOWED $objACE2 = ObjCreate("AccessControlEntry") $objACE2.Trustee = $strComputerUser $objACE2.AccessMask = $ADS_RIGHT_DS_CONTROL_ACCESS $objACE2.AceFlags = 0 $objACE2.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE2.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE2.ObjectType = $ALLOWED_TO_AUTHENTICATE $objACE3 = ObjCreate("AccessControlEntry") $objACE3.Trustee = $strComputerUser $objACE3.AccessMask = $ADS_RIGHT_DS_CONTROL_ACCESS $objACE3.AceFlags = 0 $objACE3.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE3.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE3.ObjectType = $RECEIVE_AS $objACE4 = ObjCreate("AccessControlEntry") $objACE4.Trustee = $strComputerUser $objACE4.AccessMask = $ADS_RIGHT_DS_CONTROL_ACCESS $objACE4.AceFlags = 0 $objACE4.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE4.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE4.ObjectType = $SEND_AS $objACE5 = ObjCreate("AccessControlEntry") $objACE5.Trustee = $strComputerUser $objACE5.AccessMask = $ADS_RIGHT_DS_CONTROL_ACCESS $objACE5.AceFlags = 0 $objACE5.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE5.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE5.ObjectType = $USER_CHANGE_PASSWORD $objACE6 = ObjCreate("AccessControlEntry") $objACE6.Trustee = $strComputerUser $objACE6.AccessMask = $ADS_RIGHT_DS_CONTROL_ACCESS $objACE6.AceFlags = 0 $objACE6.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE6.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE6.ObjectType = $USER_FORCE_CHANGE_PASSWORD $objACE7 = ObjCreate("AccessControlEntry") $objACE7.Trustee = $strComputerUser $objACE7.AccessMask = $ADS_RIGHT_DS_WRITE_PROP $objACE7.AceFlags = 0 $objACE7.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE7.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE7.ObjectType = $USER_ACCOUNT_RESTRICTIONS $objACE8 = ObjCreate("AccessControlEntry") $objACE8.Trustee = $strComputerUser $objACE8.AccessMask = $ADS_RIGHT_DS_SELF $objACE8.AceFlags = 0 $objACE8.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE8.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE8.ObjectType = $VALIDATED_DNS_HOST_NAME $objACE9 = ObjCreate("AccessControlEntry") $objACE9.Trustee = $strComputerUser $objACE9.AccessMask = $ADS_RIGHT_DS_SELF $objACE9.AceFlags = 0 $objACE9.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE9.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objACE9.ObjectType = $VALIDATED_SPN $objDACL.AddAce ($objACE1) $objDACL.AddAce ($objACE2) $objDACL.AddAce ($objACE3) $objDACL.AddAce ($objACE4) $objDACL.AddAce ($objACE5) $objDACL.AddAce ($objACE6) $objDACL.AddAce ($objACE7) $objDACL.AddAce ($objACE8) $objDACL.AddAce ($objACE9) $objSecurityDescriptor.DiscretionaryAcl = $objDACL $objComputer.Put ("ntSecurityDescriptor", $objSecurityDescriptor) $objComputer.SetInfo EndFunc ;==>_ADCreateComputer ; _ADDeleteObject ; $object = DisplayName of object to delete. $type="user" or "group". Func _ADDeleteObject($ou, $object, $type) If StringLeft($object, 3) <> "CN=" Then $object = "CN=" & StringReplace($object, ",", "\,") EndIf $ObjOU = ObjGet("LDAP://" & $strHostServer & "/" & $ou) $objOU.Delete ($type, $object) $ObjOU = 0 Return 1 EndFunc ;==>_ADDeleteObject ; _ADGetObjectClass ; Returns the Class of an object. Returns 0 if the object does not exist. Func _ADGetObjectClass($object) If _ADObjectExists($object) = 0 Then Return 0 $strQuery = ";(sAMAccountName=" & $object & ");ADsPath;subtree" $objRecordSet = $objConnection.Execute ($strQuery) ; Retrieve the FQDN for the object $ldap_entry = $objRecordSet.fields (0).value $oObject = ObjGet($ldap_entry) ; Retrieve the COM Object for the object $class = $oObject.Class $oObject = 0 Return $class EndFunc ;==>_ADGetObjectClass ; _ADGetObjectClassFromFQDN ; Returns the Class of an objectfrom an objects FQDN. Returns 0 if the object does not exist. Func _ADGetObjectClassFromFQDN($object) $oObject = ObjGet("LDAP://" & $strHostServer & "/" & $object) ; Retrieve the COM Object for the object If IsObj($oObject) = 0 Then Return 0 $class = $oObject.Class $oObject = 0 Return $class EndFunc ;==>_ADGetObjectClassFromFQDN ; _ADGetObjectAttribute ; Retrieves the specified (single-value) attribute for the given SamAccountName ; Returns 0 if the object does not exist, the attribute does not exist for that ; object or if the value is multi-string. ; Otherwise returns the result Func _ADGetObjectAttribute($object, $attribute) If _ADObjectExists($object) = 0 Then Return 0 $strQuery = ";(sAMAccountName=" & $object & ");ADsPath;subtree" $objRecordSet = $objConnection.Execute ($strQuery) ; Retrieve the FQDN for the object $ldap_entry = $objRecordSet.fields (0).value $oObject = ObjGet($ldap_entry) ; Retrieve the COM Object for the object $result = $oObject.Get ($attribute) $oObject.PurgePropertyList $oObject = 0 If $result = "" Then Return "" Else Return $result EndIf EndFunc ;==>_ADGetObjectAttribute ; _ADListDomainControllers ; Retrieves the names of all domain controllers in the current Domain Func _ADListDomainControllers(ByRef $DCList) $objCommand = ObjCreate("ADODB.Command") $objCommand.ActiveConnection = $objConnection $objCommand.Properties ("Page Size") = 1000 $objCommand.Properties ("Searchscope") = 2 $objCommand.CommandText = "Select distinguishedName FROM 'LDAP://" & $strHostServer & "/ou=Domain Controllers," & $strDNSDomain & "' WHERE objectclass='computer'" $objRecordSet = $objCommand.Execute Dim $DCList[$objRecordSet.RecordCount + 1] $objRecordSet.MoveFirst Do $DCList[0] += 1 $objCommand.CommandText = ";;serverReferenceBL;Range=0-*;base" $objRecSet2 = $objCommand.Execute $objRecSet2.MoveFirst Do $temparray = $objRecSet2.Fields (0).Value $DCList[$DCList[0]] = $temparray[0] $objRecSet2.MoveNext Until $objRecSet2.EOF $objRecordSet.MoveNext Until $objRecordSet.EOF $objCommand = 0 $objRecordSet = 0 Return EndFunc ;==>_ADListDomainControllers ; _ADOUObjectNames ; A faster call for returning the Display Name of objects in a given OU Func _ADOUObjectNames(ByRef $objects, $ou, $filter = 0) Local $i $ObjOU = ObjGet("LDAP://" & $strHostServer & "/" & $ou) If $filter <> 0 Then $objOU.Filter = $filter Dim $tempobjects[100000] $i = 0 For $object In $ObjOU $tempobjects[$i] = $object.name $i += 1 Next If $i = 0 Then $objects = 0 $ObjOU = 0 Return EndIf Dim $objects[$i + 1] $objects[0] = $i For $j = 1 To $i $tempstr = $tempobjects[$j - 1] $tempstr = StringTrimLeft($tempstr, 3) $objects[$j] = StringReplace($tempstr, "\,", ",") Next $ObjOU = 0 EndFunc ;==>_ADOUObjectNames ; _ADGroupManagerCanModify : ; Returns 1 if the manager of the group can modify the member list, 0 if not, -1 if there is no manager assigned ; Takes full DNs to the group and user Func _ADGroupManagerCanModify($groupdn) $ObjGroup = ObjGet("LDAP://" & $strHostServer & "/" & $groupdn) $managedBy = $objGroup.Get ("managedBy") If $managedBy = "" Then Return -1 $ObjUser = ObjGet("LDAP://" & $strHostServer & "/" & $managedBy) $arrUserDN = StringSplit($managedBy, "DC=", 1) $strDomain = StringTrimRight($arrUserDN[2], 1) $strSamAccountName = $objUser.Get ("sAMAccountName") $objNTSecurityDescriptor = $objGroup.Get ("ntSecurityDescriptor") $objDiscretionaryAcl = $objNtSecurityDescriptor.DiscretionaryAcl $blnMatch = False For $objAce In $objDiscretionaryAcl If StringLower($objAce.Trustee) = StringLower($strDomain & "\" & $strSamAccountName) And _ $objAce.ObjectType = $Member_SchemaIDGuid And _ $objAce.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT And _ BitAND($objAce.AccessMask, $ADS_RIGHT_DS_WRITE_PROP) = $ADS_RIGHT_DS_WRITE_PROP Then $blnMatch = True Next $ObjGroup = 0 $ObjUser = 0 $objNTSecurityDescriptor = 0 $objDiscretionaryAcl = 0 If $blnMatch Then Return 1 Else Return 0 EndIf EndFunc ;==>_ADGroupManagerCanModify ; _ADSetGroupManagerCanModify - Sets the Group manager to be able to modify the member list ; Takes a group DN ; Returns ; -1 if no manager is assigned ; 0 if the manager can already modify the list ; 1 if successful Func _ADSetGroupManagerCanModify($groupdn) If _ADGroupManagerCanModify($groupdn) = 1 Then Return 0 $ObjGroup = ObjGet("LDAP://" & $strHostServer & "/" & $groupdn) $managedBy = $objGroup.Get ("managedBy") If $managedBy = "" Then Return -1 $ObjUser = ObjGet("LDAP://" & $strHostServer & "/" & $managedBy) $arrUserDN = StringSplit($managedBy, "DC=", 1) $strDomain = StringTrimRight($arrUserDN[2], 1) $strSamAccountName = $objUser.Get ("sAMAccountName") $objNTSecurityDescriptor = $objGroup.Get ("ntSecurityDescriptor") $objNtSecurityDescriptor.Owner = $strDomain & "\" & @UserName $objDiscretionaryAcl = $objNtSecurityDescriptor.DiscretionaryAcl $objAce = ObjCreate("AccessControlEntry") $objAce.Trustee = $strDomain & "\" & $strSamAccountName $objAce.AccessMask = $ADS_RIGHT_DS_WRITE_PROP $objACE.AceFlags = 0 $objAce.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $objACE.Flags = $ADS_FLAG_OBJECT_TYPE_PRESENT $objAce.ObjectType = $Member_SchemaIDGuid $objDiscretionaryAcl.AddAce ($objAce) $objNtSecurityDescriptor.DiscretionaryAcl = $objDiscretionaryAcl $objGroup.Put ("ntSecurityDescriptor", $objNTSecurityDescriptor) $ObjGroup.SetInfo If @error = 3 Then MsgBox(262144, "Error", "An error occurred assigning permissions on the group.") $objGroup = 0 $objDiscretionaryAcl = 0 $objNtSecurityDescriptor = 0 $objAce = 0 Return 0 EndIf $objGroup = 0 $objDiscretionaryAcl = 0 $objNtSecurityDescriptor = 0 $objAce = 0 Return 1 EndFunc ;==>_ADSetGroupManagerCanModify ; _ADGroupAssignManager ; Takes a group DN and a User DN, assigns the user as the manager of the group Func _ADGroupAssignManager($groupdn, $userdn) $ObjGroup = ObjGet("LDAP://" & $strHostServer & "/" & $groupdn) $objGroup.Put ("managedBy", $userdn) $ObjGroup.SetInfo $objGroup = 0 Return 1 EndFunc ;==>_ADGroupAssignManager ; _ADGroupRemoveManager ; Takes a group DN and deletes the group's manager ; arg $option -- 0 (default) removes the manager; 1 only removes manager's modify permission Func _ADGroupRemoveManager($groupdn, $option = 0) $ObjGroup = ObjGet("LDAP://" & $strHostServer & "/" & $groupdn) $managedBy = $objGroup.Get ("managedBy") If $managedBy = "" Then Return -1 $ObjUser = ObjGet("LDAP://" & $strHostServer & "/" & $managedBy) $arrUserDN = StringSplit($managedBy, "DC=", 1) $strDomain = StringTrimRight($arrUserDN[2], 1) $strSamAccountName = $objUser.Get ("sAMAccountName") $objNTSecurityDescriptor = $objGroup.Get ("ntSecurityDescriptor") $objNtSecurityDescriptor.Owner = $strDomain & "\" & @UserName $objDiscretionaryAcl = $objNtSecurityDescriptor.DiscretionaryAcl $objTempAcl = ObjCreate("AccessControlList") $blnMatch = False For $objAce In $objDiscretionaryAcl If StringLower($objAce.Trustee) = StringLower($strDomain & "\" & $strSamAccountName) And _ $objAce.ObjectType = $Member_SchemaIDGuid And _ $objAce.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT And _ $objAce.AccessMask = $ADS_RIGHT_DS_WRITE_PROP Then _ $objDiscretionaryAcl.RemoveAce ($objAce) Next $objNtSecurityDescriptor.DiscretionaryAcl = $objDiscretionaryAcl $objGroup.Put ("ntSecurityDescriptor", $objNTSecurityDescriptor) If Not $option Then $objGroup.PutEx (1, "managedBy", 0) $ObjGroup.SetInfo $ObjGroup = 0 $ObjUser = 0 $objNTSecurityDescriptor = 0 $objDiscretionaryAcl = 0 EndFunc ;==>_ADGroupRemoveManager ; _ADEnableAccount ; Takes a DN of an object and enables it if the user has permissions ; Returns 1 if successful, @error otherwise Func _ADEnableAccount($fqdn) $objAccount = ObjGet("LDAP://" & $strHostServer & "/" & $fqdn) $objAccount.AccountDisabled = False $objAccount.SetInfo $loc_error = @error $objAccount = 0 If $loc_error = 0 Then Return 1 Else Return $loc_error EndIf EndFunc ;==>_ADEnableAccount ; _ADDisableAccount ; Takes a DN of an object and disables it if the user has permissions ; Returns 1 if successful, @error otherwise Func _ADDisableAccount($fqdn) $objAccount = ObjGet("LDAP://" & $strHostServer & "/" & $fqdn) $intUAC = $objAccount.Get ("userAccountControl") $objAccount.Put ("userAccountControl", BitOR($intUAC, $ADS_UF_ACCOUNTDISABLE)) $objAccount.SetInfo $loc_error = @error $objAccount = 0 If $loc_error = 0 Then Return 1 Else Return $loc_error EndIf EndFunc ;==>_ADDisableAccount ; _ADGetLastLoginDate ; Takes a SamAccountName of a user account and returns the .lastlogin information for the current DC Func _ADGetLastLoginDate($user) If _ADObjectExists($user) = 0 Then Return 0 $strQuery = ";(sAMAccountName=" & $user & ");ADsPath;subtree" $objRecordSet = $objConnection.Execute ($strQuery) ; Retrieve the FQDN for the object $ldap_entry = $objRecordSet.fields (0).value $oObject = ObjGet($ldap_entry) ; Retrieve the COM Object for the object $result = $oObject.LastLogin $oObject.PurgePropertyList If $result = "" Then Return "" Else Return $result EndIf EndFunc ;==>_ADGetLastLoginDate ; _ADAddAccountToMailboxRights ; Takes $mailbox as FQDN and $accountsam as "domain\username" ; Adds Full mailbox rights and 'send as' permission for $accountsam on $mailbox. ; Returns 2 if account already has rights, otherwise returns @error (should be 0 for success, 1 for failure) Func _ADAddAccountToMailboxRights($mailbox, $accountsam) $obj_mailbox = ObjGet("LDAP://" & $strhostserver & "/" & $mailbox) If Not IsObj($obj_mailbox) Then ;MsgBox(0, "Error", "Mailbox was not a FQDN or was not found.") SetError(3) Return EndIf $obj_mailboxsecurity = $obj_mailbox.MailboxRights $mailbox_dacl = $obj_mailboxsecurity.DiscretionaryAcl For $ace In $mailbox_dacl If $ace.trustee = $accountsam Then ;MsgBox(0, "", "User already has full rights to mailbox") SetError(2) Return @error EndIf Next $obj_ace1 = ObjCreate("AccessControlEntry") $obj_ace1.Trustee = $accountsam $obj_ace1.AccessMask = 1 $obj_ace1.AceType = 0 $obj_ace1.AceFlags = 2 $obj_ace1.ObjectType = 0 $obj_ace1.InheritedObjectType = 0 $obj_ace1.Flags = 0 $mailbox_dacl.AddAce ($obj_ace1) $obj_mailboxsecurity.DiscretionaryAcl = $mailbox_dacl $obj_mailbox.MailboxRights = $obj_mailboxsecurity $obj_ntsecurity = $obj_mailbox.Get ("ntSecurityDescriptor") $ntsecurity_dacl = $obj_ntsecurity.DiscretionaryAcl $obj_ace2 = ObjCreate("AccessControlEntry") $obj_ace2.Trustee = $accountsam $obj_ace2.AccessMask = $ADS_RIGHT_DS_CONTROL_ACCESS $obj_ace2.AceFlags = 0 $obj_ace2.AceType = $ADS_ACETYPE_ACCESS_ALLOWED_OBJECT $obj_ace2.Flags = 1 ;$ADS_FLAG_OBJECT_TYPE_PRESENT $obj_ace2.ObjectType = $SEND_AS $ntsecurity_dacl.AddAce ($obj_ace2) $obj_ntsecurity.DiscretionaryAcl = $ntsecurity_dacl $obj_mailbox.Put ("ntSecurityDescriptor", $obj_ntsecurity) $obj_mailbox.SetOption ($ADS_OPTION_SECURITY_MASK, $ADS_SECURITY_INFO_DACL) $obj_mailbox.SetInfo Return @error EndFunc ;==>_ADAddAccountToMailboxRights Func _ADRemoveMailboxRights($mailbox, $accountsam) $obj_mailbox = ObjGet("LDAP://" & $strhostserver & "/" & $mailbox) If Not IsObj($obj_mailbox) Then ;MsgBox(0, "Error", "Mailbox was not a FQDN or was not found.") SetError(3) Return EndIf $obj_mailboxsecurity = $obj_mailbox.MailboxRights $mailbox_dacl = $obj_mailboxsecurity.DiscretionaryAcl For $ace In $mailbox_dacl If $ace.trustee = $accountsam Then $mailbox_dacl.RemoveAce ($ace) EndIf Next $obj_mailboxsecurity.DiscretionaryAcl = $mailbox_dacl $obj_mailbox.MailboxRights = $obj_mailboxsecurity $obj_ntsecurity = $obj_mailbox.Get ("ntSecurityDescriptor") $ntsecurity_dacl = $obj_ntsecurity.DiscretionaryAcl For $ace In $ntsecurity_dacl If $ace.trustee = $accountsam Then $ntsecurity_dacl.RemoveAce ($ace) EndIf Next $obj_ntsecurity.DiscretionaryAcl = $ntsecurity_dacl $obj_mailbox.Put ("ntSecurityDescriptor", $obj_ntsecurity) $obj_mailbox.SetOption ($ADS_OPTION_SECURITY_MASK, $ADS_SECURITY_INFO_DACL) $obj_mailbox.SetInfo Return @error EndFunc ; _ADGetMailboxPerms ; Takes a mailbox and an array. ; Returns all SamIDs for non-inherited ACEs on the mailbox (stored in the specified array as SamIds) ; Can be filtered on an accessmask value (default = 1, full permissions) Func _ADGetMailboxPerms($mailbox, ByRef $outputarray, $filter = 1) $obj_mailbox = ObjGet("LDAP://" & $strhostserver & "/" & $mailbox) If Not IsObj($obj_mailbox) Then ;MsgBox(0, "Error", "Mailbox was not a FQDN or was not found.") SetError(3) Return EndIf $obj_mailboxsecurity = $obj_mailbox.MailboxRights $mailbox_dacl = $obj_mailboxsecurity.DiscretionaryAcl For $ace In $mailbox_dacl If $ace.AceFlags = 2 Then If BitAND($ace.AccessMask, 1) = 1 And $ace.AceType = 0 Then _ArrayAdd($outputarray, $ace.Trustee) EndIf EndIf Next EndFunc