Jump to content
Sign in to follow this  
water

Active Directory UDF - Looking for Testers of rewritten function _AD_ModifyAttribute

Recommended Posts

Hello all!

As I have just read access to my companies Active Directory I need some users willing to test the rewritten _AD_ModifyAttribute function.
My goal is to have the function handle single and multi value attributes the same way and support CLEAR, UPDATE, APPEND and DELETE for the attributes.

First step is to test how the function handles single value attributes:

Please modify the following script to specify the object (I suggest a dummy user in your test AD environment - the function might still be buggy).
Then please run the script and post the restults!

If everything works as expected we will test multi value attributes. AD attributes: http://www.rlmueller.net/UserAttributes.htm

#include <AD.au3>

_AD_Open()
$sObject = "user-to-modify" ; <== NEEDS TO BE CHANGED BY YOU!
$sAttribute = "Description"

; CLEAR - single value attribute
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
If @error Then Exit MsgBox(0, "Single value - Error!", "CLEAR: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, "", 1)
If @error Then Exit MsgBox(0, "Single value - Error!", "CLEAR returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then Exit MsgBox(0, "Single value - Error!", "CLEAR: Query new value returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after CLEAR: " & $sReturnValue & @CRLF & "Expected value: ''")

; UPDATE - single value attribute
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
If @error Then Exit MsgBox(0, "Single value - Error!", "UPDATE: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, "UPDATE", 2)
If @error Then Exit MsgBox(0, "Single value - Error!", "UPDATE returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then Exit MsgBox(0, "Single value - Error!", "UPDATE: Query new value returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after UPDATE: " & $sReturnValue & @CRLF & "Expected value: 'UPDATE'")

; APPEND - single value attribute - APPEND should work the same way as UPDATE
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
_AD_ModifyAttributeEX($sObject, $sAttribute, "APPEND", 3)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then Exit MsgBox(0, "Single value - Error!", "APPEND returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after APPEND: " & $sReturnValue & @CRLF & "Expected value: 'APPEND'")

; DELETE - single value attribute - DELETE should work the same way as CLEAR
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
_AD_ModifyAttributeEX($sObject, $sAttribute, "DELETE", 4)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then Exit MsgBox(0, "Single value - Error!", "DELETE returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after DELETE: " & $sReturnValue & @CRLF & "Expected value: ''")

_AD_Close()
Exit

; #FUNCTION# ====================================================================================================================
; Name...........: _AD_ModifyAttribute
; Description ...: Modifies an attribute of the given object to the value specified.
; Syntax.........: _AD_ModifyAttribute($sObject, $sAttribute[, $vValue = ""[, $iOption = 1]])
; Parameters ....: $sObject - Object (user, group ...) to add/delete/modify an attribute (sAMAccountName or FQDN)
;                  $sAttribute - Attribute to add/delete/modify
;                  $vValue - Optional: Value(s) to modify the attribute with. Use a blank string ("") to remove all values (default).
;                  +$vValue can be a single value (as a string) or a multi-value (as a zero-based one-dimensional array)
;                  $iOption - Optional: Indicates the mode of modification: Clear, Update, Append, Delete.
;                  |1 - CLEAR: remove all value(s) from the attribute (default when $vValue = "" or Default)
;                  |2 - UPDATE: replace the current value(s) with the specified value(s)
;                  |3 - APPEND: append the specified value(s) to the existing values(s)
;                  |4 - DELETE: delete the specified value(s) from the object
; Return values .: Success - 1
;                  Failure - 0, sets @error to:
;                  |1 - $sObject does not exist
;                  |2 - Parameter $iOption is invalid. needs to be in the range1 to 4.
;                  |x - Error returned by SetInfo method (Missing permission etc.)
; Author ........: Jonathan Clelland
; Modified.......: water
; Remarks .......:
; Related .......: _AD_GetObjectAttribute, _AD_GetObjectProperties, _AD_AddEmailAddress
; Link ..........: http://msdn.microsoft.com/en-us/library/aa746353(VS.85).aspx (ADS_PROPERTY_OPERATION_ENUM Enumeration)
; Example .......: Yes
; ===============================================================================================================================
Func _AD_ModifyAttributeEX($sObject, $sAttribute, $vValue = "", $iOption = 1)

    Local $aValue[1]
    If $vValue = Default Then $vValue = ""
    If IsArray($vValue) Then
        $aValue = $vValue
    Else
        ; Move the string value to the array
        $aValue[0] = $vValue
    EndIf
    If $iOption = Default Then $iOption = 1
    If $iOption < 1 Or $iOption > 4 Then Return SetError(2, 0, 0)
    If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0)
    Local $sProperty = "sAMAccountName"
    If StringMid($sObject, 3, 1) = "=" Then $sProperty = "distinguishedName" ; FQDN provided
    $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sProperty & "=" & $sObject & ");ADsPath;subtree"
    Local $oRecordSet = $__oAD_Command.Execute ; Retrieve the ADsPath for the object
    Local $sLDAPEntry = $oRecordSet.fields(0).Value
    Local $oObject = __AD_ObjGet($sLDAPEntry) ; Retrieve the COM Object for the object
    $oObject.GetInfo
    Switch $iOption
        Case 1
            $oObject.PutEx(1, $sAttribute, 0) ; CLEAR: remove all the property value(s) from the object
        Case 2
            $oObject.PutEx(2, $sAttribute, $aValue) ; UPDATE: replace the current value(s) with the specified value(s)
        Case 3
            $oObject.PutEx(3, $sAttribute, $aValue) ; APPEND: append the specified value(s) to the existing values(s)
        Case 4
            $oObject.PutEx(4, $sAttribute, $aValue) ; DELETE: delete the specified value(s) from the object
    EndSwitch
    $oObject.SetInfo
    If @error Then Return SetError(@error, 0, 0)
    Return 1

EndFunc   ;==>_AD_ModifyAttributeEX

 

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

So it seems that a property with no values gets deleted from the property cache. Looks good.

I will post a similar script for multi value properties quite soon :)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

I'm not sure I understand.  The two test accounts that I've tested with both had a value for the Description attribute.  When I ran your script above I received that error but it did clear(delete) the Description for both users.

 

image.png.8ae9b75683cf9099f3cbf24cb8180186.png

Share this post


Link to post
Share on other sites

_AD_ModifyAttributeEX clears the description and it seems that a property without value gets removed from the property cache. That's why _AD_GetPbjectAttribute doesn't find the property in the cache and hence returns @error = 2.

Could you please run the modified version of the script so it doesn't exit on first error?

#include <AD.au3>

_AD_Open()
$sObject = "user-to-modify" ; <== NEEDS TO BE CHANGED BY YOU!
$sAttribute = "Description"

; CLEAR - single value attribute
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
If @error Then MsgBox(0, "Single value - Error!", "CLEAR: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, "", 1)
If @error Then MsgBox(0, "Single value - Error!", "CLEAR returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Single value - Error!", "CLEAR: Query new value returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after CLEAR: " & $sReturnValue & @CRLF & "Expected value: ''")

; UPDATE - single value attribute
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
If @error Then MsgBox(0, "Single value - Error!", "UPDATE: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, "UPDATE", 2)
If @error Then MsgBox(0, "Single value - Error!", "UPDATE returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Single value - Error!", "UPDATE: Query new value returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after UPDATE: " & $sReturnValue & @CRLF & "Expected value: 'UPDATE'")

; APPEND - single value attribute - APPEND should work the same way as UPDATE
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
If @error Then MsgBox(0, "Single value - Error!", "APPEND: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, "APPEND", 3)
If @error Then MsgBox(0, "Single value - Error!", "APPEND returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Single value - Error!", "APPEND: Query new value returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after APPEND: " & $sReturnValue & @CRLF & "Expected value: 'APPEND'")

; DELETE - single value attribute - DELETE should work the same way as CLEAR
_AD_ModifyAttribute($sObject, $sAttribute, "Original value", 2)  ; Set the original value
If @error Then MsgBox(0, "Single value - Error!", "DELETE: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, "DELETE", 4)
If @error Then MsgBox(0, "Single value - Error!", "DELETE returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Single value - Error!", "DELETE: Query new value returned @error = " & @error & ", @extended = " & @extended)
MsgBox(0, "Success!", "Value after DELETE: " & $sReturnValue & @CRLF & "Expected value: ''")

_AD_Close()
Exit

; #FUNCTION# ====================================================================================================================
; Name...........: _AD_ModifyAttribute
; Description ...: Modifies an attribute of the given object to the value specified.
; Syntax.........: _AD_ModifyAttribute($sObject, $sAttribute[, $vValue = ""[, $iOption = 1]])
; Parameters ....: $sObject - Object (user, group ...) to add/delete/modify an attribute (sAMAccountName or FQDN)
;                  $sAttribute - Attribute to add/delete/modify
;                  $vValue - Optional: Value(s) to modify the attribute with. Use a blank string ("") to remove all values (default).
;                  +$vValue can be a single value (as a string) or a multi-value (as a zero-based one-dimensional array)
;                  $iOption - Optional: Indicates the mode of modification: Clear, Update, Append, Delete.
;                  |1 - CLEAR: remove all value(s) from the attribute (default when $vValue = "" or Default)
;                  |2 - UPDATE: replace the current value(s) with the specified value(s)
;                  |3 - APPEND: append the specified value(s) to the existing values(s)
;                  |4 - DELETE: delete the specified value(s) from the object
; Return values .: Success - 1
;                  Failure - 0, sets @error to:
;                  |1 - $sObject does not exist
;                  |2 - Parameter $iOption is invalid. needs to be in the range1 to 4.
;                  |x - Error returned by SetInfo method (Missing permission etc.)
; Author ........: Jonathan Clelland
; Modified.......: water
; Remarks .......:
; Related .......: _AD_GetObjectAttribute, _AD_GetObjectProperties, _AD_AddEmailAddress
; Link ..........: http://msdn.microsoft.com/en-us/library/aa746353(VS.85).aspx (ADS_PROPERTY_OPERATION_ENUM Enumeration)
; Example .......: Yes
; ===============================================================================================================================
Func _AD_ModifyAttributeEX($sObject, $sAttribute, $vValue = "", $iOption = 1)

    Local $aValue[1]
    If $vValue = Default Then $vValue = ""
    If IsArray($vValue) Then
        $aValue = $vValue
    Else
        ; Move the string value to the array
        $aValue[0] = $vValue
    EndIf
    If $iOption = Default Then $iOption = 1
    If $iOption < 1 Or $iOption > 4 Then Return SetError(2, 0, 0)
    If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0)
    Local $sProperty = "sAMAccountName"
    If StringMid($sObject, 3, 1) = "=" Then $sProperty = "distinguishedName" ; FQDN provided
    $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sProperty & "=" & $sObject & ");ADsPath;subtree"
    Local $oRecordSet = $__oAD_Command.Execute ; Retrieve the ADsPath for the object
    Local $sLDAPEntry = $oRecordSet.fields(0).Value
    Local $oObject = __AD_ObjGet($sLDAPEntry) ; Retrieve the COM Object for the object
    $oObject.GetInfo
    Switch $iOption
        Case 1
            $oObject.PutEx(1, $sAttribute, 0) ; CLEAR: remove all the property value(s) from the object
        Case 2
            $oObject.PutEx(2, $sAttribute, $aValue) ; UPDATE: replace the current value(s) with the specified value(s)
        Case 3
            $oObject.PutEx(3, $sAttribute, $aValue) ; APPEND: append the specified value(s) to the existing values(s)
        Case 4
            $oObject.PutEx(4, $sAttribute, $aValue) ; DELETE: delete the specified value(s) from the object
    EndSwitch
    $oObject.SetInfo
    If @error Then Return SetError(@error, 0, 0)
    Return 1

EndFunc   ;==>_AD_ModifyAttributeEX

 

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Thanks for your reply!

The next version will only support CLEAR and UPDATE for single value attributes. Seems APPEND and DELETE do not make much sense in this case.

Will soon post some examples to test multi value attributes :)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Test version for multi value attributes. Hope there are not too many bugs ;)

#include <AD.au3>

; The ADS_PROPERTY_OPERATION_ENUM enumeration specifies ways to update a named property in the cache
; https://docs.microsoft.com/en-us/windows/desktop/api/iads/ne-iads-__midl___midl_itf_ads_0000_0000_0027
Global Const $ADS_PROPERTY_CLEAR = 1
Global Const $ADS_PROPERTY_UPDATE = 2
Global Const $ADS_PROPERTY_APPEND = 3
Global Const $ADS_PROPERTY_DELETE = 4

_AD_Open()
Global $sObject = "user-to-modify" ; <== NEEDS TO BE CHANGED BY YOU!

Global $sAttribute = "postalAddress"
Global $aAttributeValues[] = ["address 1", "address 2", "address 3", "address 4"]
Global $aNewValues[] = ["address 5", "address 6"]
Global $aDeleteValues[] = ["address 2", "address 5"]

; CLEAR - Multi value attribute
_AD_ModifyAttribute($sObject, $sAttribute, $aAttributeValues, 2) ; Set the original value
If @error Then MsgBox(0, "Multi value - Error!", "CLEAR: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, "", $ADS_PROPERTY_CLEAR)
If @error Then MsgBox(0, "Multi value - Error!", "CLEAR returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Multi value - Error!", "CLEAR: Query new value returned @error = " & @error & ", @extended = " & @extended)
If IsString($sReturnValue) Then
    MsgBox(0, "Success!", "Value after CLEAR: " & $sReturnValue & @CRLF & "Expected value: ''")
Else
    _ArrayDisplay($sReturnValue, "Value after CLEAR. Should be ''")
EndIf

; UPDATE - Multi value attribute
_AD_ModifyAttribute($sObject, $sAttribute, $aAttributeValues, 2) ; Set the original value
If @error Then MsgBox(0, "Multi value - Error!", "UPDATE: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, $aNewValues, $ADS_PROPERTY_UPDATE)
If @error Then MsgBox(0, "Multi value - Error!", "UPDATE returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Multi value - Error!", "UPDATE: Query new value returned @error = " & @error & ", @extended = " & @extended)
If IsString($sReturnValue) Then
    MsgBox(0, "Success!", "Value after UPDATE: " & $sReturnValue & @CRLF & "Expected value: ''")
Else
    _ArrayDisplay($sReturnValue, "Value after UPDATE should be address 5 and address 6")
EndIf

; APPEND - Multi value attribute
_AD_ModifyAttribute($sObject, $sAttribute, $aAttributeValues, 2) ; Set the original value
If @error Then MsgBox(0, "Multi value - Error!", "APPEND: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, $aNewValues, 3)
If @error Then MsgBox(0, "Multi value - Error!", "APPEND returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Multi value - Error!", "APPEND: Query new value returned @error = " & @error & ", @extended = " & @extended)
If IsString($sReturnValue) Then
    MsgBox(0, "Success!", "Value after APPEND: " & $sReturnValue & @CRLF & "Expected value: ''")
Else
    _ArrayDisplay($sReturnValue, "Value after APPEND should be address 1 to 6")
EndIf

; DELETE - Multi value attribute
_AD_ModifyAttribute($sObject, $sAttribute, $aAttributeValues, 2) ; Set the original value
If @error Then MsgBox(0, "Multi value - Error!", "DELETE: Set original value returned @error = " & @error & ", @extended = " & @extended)
_AD_ModifyAttributeEX($sObject, $sAttribute, $aDeleteValues, 4)
If @error Then MsgBox(0, "Multi value - Error!", "DELETE returned @error = " & @error & ", @extended = " & @extended)
$sReturnValue = _AD_GetObjectAttribute($sObject, $sAttribute)
If @error Then MsgBox(0, "Multi value - Error!", "DELETE: Query new value returned @error = " & @error & ", @extended = " & @extended)
If IsString($sReturnValue) Then
    MsgBox(0, "Success!", "Value after DELETE: " & $sReturnValue & @CRLF & "Expected value: ''")
Else
    _ArrayDisplay($sReturnValue, "Value after DELETE should be address 1, 3, 4, 6")
EndIf

_AD_Close()
Exit

; #FUNCTION# ====================================================================================================================
; Name...........: _AD_ModifyAttribute
; Description ...: Modifies an attribute of the given object to the value specified.
; Syntax.........: _AD_ModifyAttribute($sObject, $sAttribute[, $vValue = ""[, $iOption = 1]])
; Parameters ....: $sObject - Object (user, group ...) to add/delete/modify an attribute (sAMAccountName or FQDN)
;                  $sAttribute - Attribute to add/delete/modify
;                  $vValue - Optional: Value(s) to modify the attribute with. Use a blank string ("") to remove all values (default).
;                  +$vValue can be a string for a single value attribute (e.g. description) or
;                  +a zero-based one-dimensional array for a multi value attribute (e.g. PostalAdresses).
;                  $iOption - Optional: Indicates the mode of modification: Clear, Update, Append, Delete.
;                  |1 - CLEAR: remove all value(s) from the attribute (default when $vValue = "" or Default)
;                  |2 - UPDATE: replace the current value(s) with the specified value(s)
;                  |3 - APPEND: append the specified value(s) to the existing values(s)
;                  |4 - DELETE: delete the specified value(s) from the object
; Return values .: Success - 1
;                  Failure - 0, sets @error to:
;                  |1 - $sObject does not exist
;                  |2 - Parameter $iOption is invalid. Needs to be in the range1 to 4.
;                  |3 - Parameter $iOption is invalid for a single value attribute. Needs to be 1 or 2.
;                  |x - Error returned by SetInfo method (Missing permission etc.)
; Author ........: Jonathan Clelland
; Modified.......: water
; Remarks .......: For a single value attribute the function only supports $iOption 1 and 2.
; Related .......: _AD_GetObjectAttribute, _AD_GetObjectProperties, _AD_AddEmailAddress
; Link ..........: https://support.microsoft.com/en-us/help/260251/how-to-use-adsi-to-set-ldap-directory-attributes
; Example .......: Yes
; ===============================================================================================================================
Func _AD_ModifyAttributeEX($sObject, $sAttribute, $vValue = "", $iOption = 1)

    Local $aValue[1]
    If $vValue = Default Then $vValue = ""
    If $iOption = Default Then $iOption = 1
    If $iOption < 1 Or $iOption > 4 Then Return SetError(2, 0, 0)
    If IsArray($vValue) Then
        $aValue = $vValue
    Else ; Move the string value to the array
        If $iOption > 2 Then SetError(3, 0, 0)
        $aValue[0] = $vValue
    EndIf
    If Not _AD_ObjectExists($sObject) Then Return SetError(1, 0, 0)
    Local $sProperty = "sAMAccountName"
    If StringMid($sObject, 3, 1) = "=" Then $sProperty = "distinguishedName" ; FQDN provided
    $__oAD_Command.CommandText = "<LDAP://" & $sAD_HostServer & "/" & $sAD_DNSDomain & ">;(" & $sProperty & "=" & $sObject & ");ADsPath;subtree"
    Local $oRecordSet = $__oAD_Command.Execute ; Retrieve the ADsPath for the object
    Local $sLDAPEntry = $oRecordSet.fields(0).Value
    Local $oObject = __AD_ObjGet($sLDAPEntry) ; Retrieve the COM Object for the object
    $oObject.GetInfo
    Switch $iOption
        Case 1
            $oObject.PutEx($ADS_PROPERTY_CLEAR, $sAttribute, 0) ; CLEAR: remove all the property value(s) from the object
        Case 2
            $oObject.PutEx($ADS_PROPERTY_UPDATE, $sAttribute, $aValue) ; UPDATE: replace the current value(s) with the specified value(s)
        Case 3
            $oObject.PutEx($ADS_PROPERTY_APPEND, $sAttribute, $aValue) ; APPEND: append the specified value(s) to the existing values(s)
        Case 4
            $oObject.PutEx($ADS_PROPERTY_DELETE, $sAttribute, $aValue) ; DELETE: delete the specified value(s) from the object
    EndSwitch
    $oObject.SetInfo
    If @error Then Return SetError(@error, 0, 0)
    Return 1

EndFunc   ;==>_AD_ModifyAttributeEX

 

Edited by water

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Seems we need to do some investigation why _AD_ModifyAttribute does not set the starting value.
Will come back with some debugging code.


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

Think I used the wrong name for the attribute. Should be "postalAddress" not "PostalAddresses".
I modified my script above.
Could you please retry?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2019-10-24 - Version 1.4.14.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2019-11-30 - Version 1.4.0.0) - Download - General Help & Support - Example Scripts - Wiki
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (NEW 2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki

 

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
Sign in to follow this  

  • Similar Content

    • By water
      Extensive library to control and manipulate Microsoft Active Directory.

      Threads: Development - General Help & Support - Example Scripts - Wiki
      Previous downloads: 30467
       
      Known Bugs: (last changed: 2019-08-19)
      None
        Things to come: (last changed: 2019-08-19)
      None
      BTW: If you like this UDF please click the "I like this" button. This tells me where to next put my development effort
    • By AdamUL
      Below are some functions that I created when I needed to get some Group Policy information via script.  The quickest way I found to get this information was using the Group Policy Module for PowerShell.  This is not a full UDF for the Group Policy Module.  There are a lot more options available with the cmdlets, and this only touches on a few.  To use the functions below, for a Windows client, you will need to install Remote Server Administration Tools (RSAT).  For Windows Server 2012 or later, you will need to install the Group Policy Management Console.  
      Remote Server Administration Tools (RSAT)
      Installing the Group Policy Management Console via PowerShell for Windows Server 2012 or later.  Run in an Admin PowerShell prompt.
      Install-WindowsFeature –Name GPMC PowerShell Group Policy Module Documentation
      For the example below, the AD UDF is only required to query GPO names, but is not required to use the functions.  
      #include <AD.au3> #include <WinAPIFiles.au3> Global $sLDAPFilter = "(name=*)" Global $sExcludeFilter = "" Global $sIncludeFilter = "" Global $sBaseDN = "DC=ad,DC=university,DC=edu" Global $sDataToRetrieve = "sAMAccountName" $sIncludeFilter = "(&(displayName=LIBS-*))" ;GPO Names. $sLDAPFilter = "(&(objectClass=groupPolicyContainer)" & $sExcludeFilter & $sIncludeFilter & ")" $sDataToRetrieve = "displayName,name" _AD_Open() Global $aGPONames = _AD_GetObjectsInOU($sBaseDN, $sLDAPFilter, 2, $sDataToRetrieve) If @error Then MsgBox(64, "Active Directory Functions", "No objects found") Exit _AD_Close() EndIf _AD_Close() ;Add column headers to the output array. Global $aDataToRetrieve = StringSplit($sDataToRetrieve, ",", 2) For $i = 0 To UBound($aGPONames, 2) - 1 Step 1 $aGPONames[0][$i] = $aDataToRetrieve[$i] Next _ArraySort($aGPONames) _ArrayDisplay($aGPONames, "LIBS GPOs") ;For Testing. Global $aGPOPermissions = _AD_GetGPOPermissionsPS($aGPONames[1][0]) If @error Then Exit 1 _ArrayDisplay($aGPOPermissions, $aGPONames[1][0]) Global $sOU = "OU=libs,OU=active,DC=ad,DC=university,DC=edu" Global $aGPOLinks = _AD_GetGPOLinksPS($sOU) If @error Then Exit 2 _ArrayDisplay($aGPOLinks, $sOU) Global $aGPOInheritedLinks = _AD_GetGPOInheritedLinksPS($sOU) If @error Then Exit 2 _ArrayDisplay($aGPOInheritedLinks, $sOU) Global $aGPOs = _AD_GetAllGPOsPS() If @error Then Exit 3 _ArraySort($aGPOs) _ArrayDisplay($aGPOs, "GPOs") Global $aGPOName = _AD_GetGPOByNamePS($aGPONames[1][0]) If @error Then Exit 4 _ArrayDisplay($aGPOName, $aGPONames[1][0]) Global $aGPOGuid = _AD_GetGPOByGuidPS($aGPONames[1][1]) If @error Then Exit 5 _ArrayDisplay($aGPOGuid, $aGPONames[1][1]) Global $sReportName = "C:\Users\adamul\Desktop\Group Policy Object (GPO) PowerShell\Reports\" & $aGPONames[1][0] & ".html" _AD_GetGPOReportByNamePS($aGPONames[1][0], $sReportName) If @error Then Exit 6 Global $sReportGUID = "C:\Users\adamul\Desktop\Group Policy Object (GPO) PowerShell\Reports\" & $aGPONames[1][1] & ".html" _AD_GetGPOReportByGuidPS($aGPONames[1][1], $sReportGUID) If @error Then Exit 6 Func _AD_GetGPOPermissionsPS($sGPOName) ;An array of permission level for one or more security principals on a specified GPO. Local $sGPOCmd = 'powershell "Import-Module GroupPolicy; Get-GPPermissions -Name ''' & $sGPOName & ''' -All"' ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. Local $iGPOCmdOutputSS = StringInStr($sGPOCmdOutput, @CRLF & @CRLF) If $iGPOCmdOutputSS = 0 Then Return SetError(1, 0, 0) Local $sGPOCmdOutputSS = StringMid($sGPOCmdOutput, 1, $iGPOCmdOutputSS) ;~ ConsoleWrite(@CRLF & @CRLF & $sGPOCmdOutputSS & @CRLF) Local $sRegEx = "([^:\r\n]*):.*" Local $aProperties = StringRegExp($sGPOCmdOutputSS, $sRegEx, 3) ;~ _ArrayDisplay($aProperties) ;For testing. If StringInStr($sGPOCmdOutput, "ArgumentException") Then Return SetError(2, 0, 0) ;Get data on multiple lines to a single line. $sGPOCmdOutput = StringRegExpReplace($sGPOCmdOutput, "(\r\n\h{2,})", "") Local $aGPOCmdOutput = StringSplit($sGPOCmdOutput, @CRLF & @CRLF, 1) ;~ _ArrayDisplay($aGPOCmdOutput) ;For testing. ;Convert from a list output to a 2D array. Local $aGPOCmdOutput2D[$aGPOCmdOutput[0]][UBound($aProperties)] Local $aTemp For $i = 1 To $aGPOCmdOutput[0] Step 1 $aTemp = StringSplit($aGPOCmdOutput[$i], @CRLF, 1) For $j = 1 To $aTemp[0] Step 1 For $k = 0 To UBound($aProperties) - 1 Step 1 If StringInStr($aTemp[$j], $aProperties[$k]) Then $aGPOCmdOutput2D[$i - 1][$k] = StringStripWS(StringReplace($aTemp[$j], $aProperties[$k] & ":", ""), 3) EndIf Next Next Next ;~ _ArrayDisplay($aGPOCmdOutput2D) ;For testing. For $i = 0 To UBound($aProperties) - 1 Step 1 $aProperties[$i] = StringStripWS($aProperties[$i], 3) Next _ArrayTranspose($aProperties) _ArrayConcatenate($aProperties, $aGPOCmdOutput2D) Return $aProperties EndFunc ;==>_AD_GetGPOPermissionsPS Func _AD_GetGPOLinksPS($sOUName) ;An array of GPOs that are linked directly to the location. Local $sGPOCmd = 'powershell "Import-Module GroupPolicy; (Get-GPInheritance -Target ''' & $sOUName & "').GpoLinks" ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. Local $iGPOCmdOutputSS = StringInStr($sGPOCmdOutput, @CRLF & @CRLF) If $iGPOCmdOutputSS = 0 Then Return SetError(1, 0, 0) Local $sGPOCmdOutputSS = StringMid($sGPOCmdOutput, 1, $iGPOCmdOutputSS) ;~ ConsoleWrite(@CRLF & @CRLF & $sGPOCmdOutputSS & @CRLF) ;For testing. Local $sRegEx = "([^:\r\n]*):.*" Local $aProperties = StringRegExp($sGPOCmdOutputSS, $sRegEx, 3) ;~ _ArrayDisplay($aProperties) ;For testing. If StringInStr($sGPOCmdOutput, "ArgumentException") Then Return SetError(1, 0, 0) ;Get data on multiple lines to a single line. $sGPOCmdOutput = StringRegExpReplace($sGPOCmdOutput, "(\r\n\h{2,})", "") Local $aGPOCmdOutput = StringSplit($sGPOCmdOutput, @CRLF & @CRLF, 1) ;~ _ArrayDisplay($aGPOCmdOutput) ;For testing. ;Convert from a list output to a 2D array. Local $aGPOCmdOutput2D[$aGPOCmdOutput[0]][UBound($aProperties)] Local $aTemp For $i = 1 To $aGPOCmdOutput[0] Step 1 $aTemp = StringSplit($aGPOCmdOutput[$i], @CRLF, 1) For $j = 1 To $aTemp[0] Step 1 For $k = 0 To UBound($aProperties) - 1 Step 1 If StringInStr($aTemp[$j], $aProperties[$k]) Then $aGPOCmdOutput2D[$i - 1][$k] = StringStripWS(StringReplace($aTemp[$j], $aProperties[$k] & ":", ""), 3) EndIf Next Next Next ;~ _ArrayDisplay($aGPOCmdOutput2D) ;For testing. For $i = 0 To UBound($aProperties) - 1 Step 1 $aProperties[$i] = StringStripWS($aProperties[$i], 3) Next _ArrayTranspose($aProperties) _ArrayConcatenate($aProperties, $aGPOCmdOutput2D) Return $aProperties EndFunc ;==>_AD_GetGPOLinksPS Func _AD_GetGPOInheritedLinksPS($sOUName) ;An array of GPOs that are applied to the location when Group Policy is processed on a client. Local $sGPOCmd = 'powershell "Import-Module GroupPolicy; (Get-GPInheritance -Target ''' & $sOUName & "').InheritedGpoLinks" ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. Local $iGPOCmdOutputSS = StringInStr($sGPOCmdOutput, @CRLF & @CRLF) If $iGPOCmdOutputSS = 0 Then Return SetError(1, 0, 0) Local $sGPOCmdOutputSS = StringMid($sGPOCmdOutput, 1, $iGPOCmdOutputSS) ;~ ConsoleWrite(@CRLF & @CRLF & $sGPOCmdOutputSS & @CRLF) ;For testing. Local $sRegEx = "([^:\r\n]*):.*" Local $aProperties = StringRegExp($sGPOCmdOutputSS, $sRegEx, 3) ;~ _ArrayDisplay($aProperties) ;For testing. If StringInStr($sGPOCmdOutput, "ArgumentException") Then Return SetError(1, 0, 0) ;Get data on multiple lines to a single line. $sGPOCmdOutput = StringRegExpReplace($sGPOCmdOutput, "(\r\n\h{2,})", "") Local $aGPOCmdOutput = StringSplit($sGPOCmdOutput, @CRLF & @CRLF, 1) ;~ _ArrayDisplay($aGPOCmdOutput) ;For testing. ;Convert from a list output to a 2D array. Local $aGPOCmdOutput2D[$aGPOCmdOutput[0]][UBound($aProperties)] Local $aTemp For $i = 1 To $aGPOCmdOutput[0] Step 1 $aTemp = StringSplit($aGPOCmdOutput[$i], @CRLF, 1) For $j = 1 To $aTemp[0] Step 1 For $k = 0 To UBound($aProperties) - 1 Step 1 If StringInStr($aTemp[$j], $aProperties[$k]) Then $aGPOCmdOutput2D[$i - 1][$k] = StringStripWS(StringReplace($aTemp[$j], $aProperties[$k] & ":", ""), 3) EndIf Next Next Next ;~ _ArrayDisplay($aGPOCmdOutput2D) ;For testing. For $i = 0 To UBound($aProperties) - 1 Step 1 $aProperties[$i] = StringStripWS($aProperties[$i], 3) Next _ArrayTranspose($aProperties) _ArrayConcatenate($aProperties, $aGPOCmdOutput2D) Return $aProperties EndFunc ;==>_AD_GetGPOInheritedLinksPS Func _AD_GetAllGPOsPS() ;An array of information on all the GPOs in a domain. Local $sGPOCmd = 'powershell "Import-Module GroupPolicy; Get-GPO -All"' ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. Local $iGPOCmdOutputSS = StringInStr($sGPOCmdOutput, @CRLF & @CRLF) If $iGPOCmdOutputSS = 0 Then Return SetError(1, 0, 0) Local $sGPOCmdOutputSS = StringMid($sGPOCmdOutput, 1, $iGPOCmdOutputSS) ;~ ConsoleWrite(@CRLF & @CRLF & $sGPOCmdOutputSS & @CRLF) ;For testing. Local $sRegEx = "([^:\r\n]*):.*" Local $aProperties = StringRegExp($sGPOCmdOutputSS, $sRegEx, 3) ;~ _ArrayDisplay($aProperties) If StringInStr($sGPOCmdOutput, "ArgumentException") Then Return SetError(1, 0, 0) ;Get data on multiple lines to a single line. $sGPOCmdOutput = StringRegExpReplace($sGPOCmdOutput, "(\r\n\h{2,})", "") Local $aGPOCmdOutput = StringSplit($sGPOCmdOutput, @CRLF & @CRLF, 1) ;~ _ArrayDisplay($aGPOCmdOutput) ;For testing. ;Convert from a list output to a 2D array. Local $aGPOCmdOutput2D[$aGPOCmdOutput[0]][UBound($aProperties)] Local $aTemp For $i = 1 To $aGPOCmdOutput[0] Step 1 $aTemp = StringSplit($aGPOCmdOutput[$i], @CRLF, 1) For $j = 1 To $aTemp[0] Step 1 For $k = 0 To UBound($aProperties) - 1 Step 1 If StringInStr($aTemp[$j], $aProperties[$k]) Then $aGPOCmdOutput2D[$i - 1][$k] = StringStripWS(StringReplace($aTemp[$j], $aProperties[$k] & ":", ""), 3) EndIf Next Next Next ;~ _ArrayDisplay($aGPOCmdOutput2D) ;For testing. For $i = 0 To UBound($aProperties) - 1 Step 1 $aProperties[$i] = StringStripWS($aProperties[$i], 3) Next _ArrayTranspose($aProperties) _ArrayConcatenate($aProperties, $aGPOCmdOutput2D) Return $aProperties EndFunc ;==>_AD_GetAllGPOsPS Func _AD_GetGPOByNamePS($sGPOName) ;An array of information on one Group Policy Object (GPO) in a domain by Display Name. Local $sGPOCmd = 'powershell "Import-Module GroupPolicy; Get-GPO -Name ''' & $sGPOName & '''"' ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. ;Add end of line characters for single return group to be processed. $sGPOCmdOutput = $sGPOCmdOutput & @CRLF & @CRLF Local $iGPOCmdOutputSS = StringInStr($sGPOCmdOutput, @CRLF & @CRLF) If $iGPOCmdOutputSS = 0 Then Return SetError(1, 0, 0) Local $sGPOCmdOutputSS = StringMid($sGPOCmdOutput, 1, $iGPOCmdOutputSS) ConsoleWrite(@CRLF & @CRLF & $sGPOCmdOutputSS & @CRLF) Local $sRegEx = "([^:\r\n]*):.*" Local $aProperties = StringRegExp($sGPOCmdOutputSS, $sRegEx, 3) ;~ _ArrayDisplay($aProperties) ;For testing. If StringInStr($sGPOCmdOutput, "ArgumentException") Then Return SetError(1, 0, 0) ;Get data on multiple lines to a single line. $sGPOCmdOutput = StringRegExpReplace($sGPOCmdOutput, "(\r\n\h{2,})", "") ;Remove last @CRLF to prevent blank row in return array. $sGPOCmdOutput = StringTrimRight($sGPOCmdOutput, 2) Local $aGPOCmdOutput = StringSplit($sGPOCmdOutput, @CRLF & @CRLF, 1) ;~ _ArrayDisplay($aGPOCmdOutput) ;For testing. ;Convert from a list output to a 2D array. Local $aGPOCmdOutput2D[$aGPOCmdOutput[0]][UBound($aProperties)] ;~ _ArrayDisplay($aGPOCmdOutput2D) ;For testing. Local $aTemp For $i = 1 To $aGPOCmdOutput[0] Step 1 $aTemp = StringSplit($aGPOCmdOutput[$i], @CRLF, 1) For $j = 1 To $aTemp[0] Step 1 For $k = 0 To UBound($aProperties) - 1 Step 1 If StringInStr($aTemp[$j], $aProperties[$k]) Then $aGPOCmdOutput2D[$i - 1][$k] = StringStripWS(StringReplace($aTemp[$j], $aProperties[$k] & ":", ""), 3) EndIf Next Next Next ;~ _ArrayDisplay($aGPOCmdOutput2D) ;For testing. For $i = 0 To UBound($aProperties) - 1 Step 1 $aProperties[$i] = StringStripWS($aProperties[$i], 3) Next _ArrayTranspose($aProperties) _ArrayConcatenate($aProperties, $aGPOCmdOutput2D) Return $aProperties EndFunc ;==>_AD_GetGPOByNamePS Func _AD_GetGPOByGuidPS($sGPOGuid) ;An array of information on one Group Policy Object (GPO) in a domain by GUID. Local $sGPOCmd = 'powershell "Import-Module GroupPolicy; Get-GPO -Guid ''' & $sGPOGuid & '''"' ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. ;Add end of line characters for single return group to be processed. $sGPOCmdOutput = $sGPOCmdOutput & @CRLF & @CRLF Local $iGPOCmdOutputSS = StringInStr($sGPOCmdOutput, @CRLF & @CRLF) If $iGPOCmdOutputSS = 0 Then Return SetError(1, 0, 0) Local $sGPOCmdOutputSS = StringMid($sGPOCmdOutput, 1, $iGPOCmdOutputSS) ;~ ConsoleWrite(@CRLF & @CRLF & $sGPOCmdOutputSS & @CRLF) ;For testing. Local $sRegEx = "([^:\r\n]*):.*" Local $aProperties = StringRegExp($sGPOCmdOutputSS, $sRegEx, 3) ;~ _ArrayDisplay($aProperties) ;For testing. If StringInStr($sGPOCmdOutput, "ArgumentException") Then Return SetError(1, 0, 0) ;Get data on multiple lines to a single line. $sGPOCmdOutput = StringRegExpReplace($sGPOCmdOutput, "(\r\n\h{2,})", "") ;Remove last @CRLF to prevent blank row in return array. $sGPOCmdOutput = StringTrimRight($sGPOCmdOutput, 2) Local $aGPOCmdOutput = StringSplit($sGPOCmdOutput, @CRLF & @CRLF, 1) ;~ _ArrayDisplay($aGPOCmdOutput) ;For testing. ;Convert from a list output to a 2D array. Local $aGPOCmdOutput2D[$aGPOCmdOutput[0]][UBound($aProperties)] ;~ _ArrayDisplay($aGPOCmdOutput2D) Local $aTemp For $i = 1 To $aGPOCmdOutput[0] Step 1 $aTemp = StringSplit($aGPOCmdOutput[$i], @CRLF, 1) For $j = 1 To $aTemp[0] Step 1 For $k = 0 To UBound($aProperties) - 1 Step 1 If StringInStr($aTemp[$j], $aProperties[$k]) Then $aGPOCmdOutput2D[$i - 1][$k] = StringStripWS(StringReplace($aTemp[$j], $aProperties[$k] & ":", ""), 3) EndIf Next Next Next ;~ _ArrayDisplay($aGPOCmdOutput2D) ;For testing. For $i = 0 To UBound($aProperties) - 1 Step 1 $aProperties[$i] = StringStripWS($aProperties[$i], 3) Next _ArrayTranspose($aProperties) _ArrayConcatenate($aProperties, $aGPOCmdOutput2D) Return $aProperties EndFunc ;==>_AD_GetGPOByGuidPS Func _AD_GetGPOReportByNamePS($sGPOName, $sReportFullPath, $sReportType = "HTML") ;Generates a report either in XML or HTML format for a specified GPO by name in a domain. Switch $sReportType Case "HTML", "XML" Case Else Return SetError(1, 0, False) EndSwitch Local $sPath = StringRegExpReplace($sReportFullPath, "(^.*\\)(.*)", "$1") ;~ ConsoleWrite($sPath & @CRLF) ;For testing. ;~ If Not FileExists($sPath) Then Return SetError(2, 0, False) Local $sGPOCmd = 'powershell "Get-GPOReport -Name ''' & $sGPOName & ''' -ReportType ' & $sReportType & ' -Path ''' & $sReportFullPath & '''"' ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. If $sGPOCmdOutput <> "" Then SetError(3, 0, False) Return True EndFunc ;==>_AD_GetGPOReportByNamePS Func _AD_GetGPOReportByGuidPS($sGPOGuid, $sReportFullPath, $sReportType = "HTML") ;Generates a report either in XML or HTML format for a specified GPO by GUID in a domain. Switch $sReportType Case "HTML", "XML" Case Else Return SetError(1, 0, False) EndSwitch Local $sPath = StringRegExpReplace($sReportFullPath, "(^.*\\)(.*)", "$1") ;~ ConsoleWrite($sPath & @CRLF) ;For testing. ;~ If Not FileExists($sPath) Then Return SetError(2, 0, False) Local $sGPOCmd = 'powershell "Get-GPOReport -GUID ''' & $sGPOGuid & ''' -ReportType ' & $sReportType & ' -Path ''' & $sReportFullPath & '''"' ConsoleWrite($sGPOCmd & @CRLF) ;Turn off redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(False) Local $iPIDGPOCmd = Run($sGPOCmd, @SystemDir, @SW_HIDE, $STDERR_MERGED) ProcessWaitClose($iPIDGPOCmd) ;Turn on redirection for a 32-bit script on 64-bit system. If @OSArch = "X64" And Not @AutoItX64 Then _WinAPI_Wow64EnableWow64FsRedirection(True) Local $sGPOCmdOutput = StringStripWS(StdoutRead($iPIDGPOCmd), 3) ;~ ConsoleWrite($sGPOCmdOutput & @CRLF & @CRLF) ;For testing. If $sGPOCmdOutput <> "" Then SetError(3, 0, False) Return True EndFunc ;==>_AD_GetGPOReportByGuidPS  
      Adam
       
    • By Chimp
      Is there an AD way to search if and where (the hostname) an userid is (or on what host was last time) logged?
      Thanks
    • By antmar904
      I'm trying to read all cells used in column "C" in excel to an array but not sure how.
       
      Local $NameArray = _Excel_RangeRead($oWorkbook, $oWorkbook.Activesheet, $oWorkbook.Range["C"].End)  
    • By Blois
      Hey Guys,
      Good?
      I'm ned help to consult in other domain. My three domain contains any domains.
      How do I get this query done?
       
      Tks for the Help!
       
×
×
  • Create New...