"Subscript used on non-accessible variable" beim AD UDF, zB: "_AD_GetObjectProperties"

  • Letzter Versuch. Was kriegst Du (Console, MsgBox), wenn Du folgendes Script laufen lässt?[spoiler]

    [autoit]

    #include <AD.au3>
    _AD_ErrorNotify(2)
    _AD_Open()
    ConsoleWrite("_AD_Open: " & @error & @CRLF)
    $aProperties = _AD_GetObjectPropertiesEX()
    ConsoleWrite("_AD_GetObjectPropertiesEX: " & @error & @CRLF)
    _AD_Close()
    ConsoleWrite("_AD_Close: " & @error & @CRLF)
    Exit

    [/autoit][autoit][/autoit][autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _AD_GetObjectProperties
    ; Description ...: Returns a two-dimensional array of all or selected properties and their values of an object in readable form.
    ; Syntax.........: _AD_GetObjectProperties([$sObject = @UserName[, $sProperties = ""]])
    ; Parameters ....: $sObject - Optional: SamAccountName or FQDN of the object properties from (e.g. computer, user, group ...) (default = @Username)
    ; |Can be of type object as well. Useful to get properties for a schema or configuration object (see _AD_ListRootDSEAttributes)
    ; $sProperties - Optional: Comma separated list of properties to return (default = "" = return all properties)
    ; Return values .: Success - Returns a two-dimensional array with all properties and their values of an object in readable form
    ; Failure - "" or property name, sets @error to:
    ; |1 - $sObject could not be found
    ; |2 - No values for the specified property. The property in error is returned as the function result
    ; Author ........: Sundance
    ; Modified.......: water
    ; Remarks .......: Dates are returned in format: YYYY/MM/DD HH:MM:SS local time of the calling user (AD stores all dates in UTC - Universal Time Coordinated)
    ; Exception: AD internal dates like "whenCreated", "whenChanged" and "dSCorePropagationData". They are returned as UTC
    ; NT Security Descriptors are returned as: Control:nn, Group:Domain\Group, Owner:Domain\Group, Revision:nn
    ; No error is returned if there are properties in $sProperties that are not available for the selected object
    ;+
    ; Properties are returned in alphabetical order. If $sProperties is set to "samaccountname,displayname" the returned array will contain
    ; displayname as the first and samaccountname as the second row.
    ; Related .......:
    ; Link ..........: http://www.autoitscript.com/forum/index.ph…ndpost&p=422402, http://msdn.microsoft.com/en-us/library/ms675090(VS.85).aspx
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _AD_GetObjectPropertiesEX($sObject = @UserName, $sProperties = "")

    [/autoit][autoit][/autoit][autoit]

    Local $aObjectProperties[1][2], $oObject
    Local $oItem, $oPropertyEntry, $oValue, $iCount3, $xAD_Dummy
    ; Data Type Mapping between Active Directory and LDAP
    ; http://msdn.microsoft.com/en-us/library/aa772375(VS.85).aspx
    Local Const $ADSTYPE_DN_STRING = 1
    Local Const $ADSTYPE_CASE_IGNORE_STRING = 3
    Local Const $ADSTYPE_BOOLEAN = 6
    Local Const $ADSTYPE_INTEGER = 7
    Local Const $ADSTYPE_OCTET_STRING = 8
    Local Const $ADSTYPE_UTC_TIME = 9
    Local Const $ADSTYPE_LARGE_INTEGER = 10
    Local Const $ADSTYPE_NT_SECURITY_DESCRIPTOR = 25
    Local Const $ADSTYPE_UNKNOWN = 26
    Local $aSAMAccountType[12][2] = [["DOMAIN_OBJECT", 0x0],["GROUP_OBJECT", 0x10000000],["NON_SECURITY_GROUP_OBJECT", 0x10000001], _
    ["ALIAS_OBJECT", 0x20000000],["NON_SECURITY_ALIAS_OBJECT", 0x20000001],["USER_OBJECT", 0x30000000],["NORMAL_USER_ACCOUNT", 0x30000000], _
    ["MACHINE_ACCOUNT", 0x30000001],["TRUST_ACCOUNT", 0x30000002],["APP_BASIC_GROUP", 0x40000000],["APP_QUERY_GROUP", 0x40000001], _
    ["ACCOUNT_TYPE_MAX", 0x7fffffff]]
    Local $aUAC[21][2] = [[0x00000001, "SCRIPT"],[0x00000002, "ACCOUNTDISABLE"],[0x00000008, "HOMEDIR_REQUIRED"],[0x00000010, "LOCKOUT"],[0x00000020, "PASSWD_NOTREQD"], _
    [0x00000040, "PASSWD_CANT_CHANGE"],[0x00000080, "ENCRYPTED_TEXT_PASSWORD_ALLOWED"],[0x00000100, "TEMP_DUPLICATE_ACCOUNT"],[0x00000200, "NORMAL_ACCOUNT"], _
    [0x00000800, "INTERDOMAIN_TRUST_ACCOUNT"],[0x00001000, "WORKSTATION_TRUST_ACCOUNT"],[0x00002000, "SERVER_TRUST_ACCOUNT"],[0x00010000, "DONT_EXPIRE_PASSWD"], _
    [0x00020000, "MNS_LOGON_ACCOUNT"],[0x00040000, "SMARTCARD_REQUIRED"],[0x00080000, "TRUSTED_FOR_DELEGATION"],[0x00100000, "NOT_DELEGATED"], _
    [0x00200000, "USE_DES_KEY_ONLY"],[0x00400000, "DONT_REQUIRE_PREAUTH"],[0x00800000, "PASSWORD_EXPIRED"],[0x01000000, "TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION"]]

    [/autoit][autoit][/autoit][autoit]

    $sProperties = "," & StringReplace($sProperties, " ", "") & ","
    If Not IsObj($sObject) Then
    ; If _AD_ObjectExists($sObject) = 0 Then Return SetError(1, 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
    $oObject = __AD_ObjGet($sLDAPEntry) ; Retrieve the COM Object
    Else
    $oObject = $sObject
    EndIf
    $oObject.GetInfo()
    Local $iCount1 = $oObject.PropertyCount()
    For $iCount2 = 0 To $iCount1 - 1
    $oItem = $oObject.Item($iCount2)
    If Not ($sProperties = ",," Or StringInStr($sProperties, "," & $oItem.Name & ",") > 0) Then ContinueLoop
    $oPropertyEntry = $oObject.GetPropertyItem($oItem.Name, $ADSTYPE_UNKNOWN)
    If Not IsObj($oPropertyEntry) Then
    Return SetError(2, 0, $oItem.Name)
    Else
    For $vPropertyValue In $oPropertyEntry.Values
    ReDim $aObjectProperties[UBound($aObjectProperties, 1) + 1][2]
    $iCount3 = UBound($aObjectProperties, 1) - 1
    $aObjectProperties[$iCount3][0] = $oItem.Name
    If $oItem.ADsType = $ADSTYPE_CASE_IGNORE_STRING Then
    $aObjectProperties[$iCount3][1] = $vPropertyValue.CaseIgnoreString
    ElseIf $oItem.ADsType = $ADSTYPE_INTEGER Then
    If $oItem.Name = "sAMAccountType" Then
    For $iCount4 = 0 To 11
    If $vPropertyValue.Integer = $aSAMAccountType[$iCount4][1] Then
    $aObjectProperties[$iCount3][1] = $aSAMAccountType[$iCount4][0]
    ExitLoop
    EndIf
    Next
    ElseIf $oItem.Name = "userAccountControl" Then
    $aObjectProperties[$iCount3][1] = $vPropertyValue.Integer & " = "
    For $iCount4 = 0 To 20
    If BitAND($vPropertyValue.Integer, $aUAC[$iCount4][0]) = $aUAC[$iCount4][0] Then
    $aObjectProperties[$iCount3][1] &= $aUAC[$iCount4][1] & " - "
    EndIf
    Next
    If StringRight($aObjectProperties[$iCount3][1], 3) = " - " Then $aObjectProperties[$iCount3][1] = StringTrimRight($aObjectProperties[$iCount3][1], 3)
    Else
    $aObjectProperties[$iCount3][1] = $vPropertyValue.Integer
    EndIf
    ElseIf $oItem.ADsType = $ADSTYPE_LARGE_INTEGER Then
    If $oItem.Name = "pwdLastSet" Or $oItem.Name = "accountExpires" Or $oItem.Name = "lastLogonTimestamp" Or $oItem.Name = "badPasswordTime" Or $oItem.Name = "lastLogon" Or $oItem.Name = "lockoutTime" Then
    If $vPropertyValue.LargeInteger.LowPart = 0 And $vPropertyValue.LargeInteger.HighPart = 0 Then
    $aObjectProperties[$iCount3][1] = "1601/01/01 00:00:00"
    Else
    Local $sTemp = DllStructCreate("dword low;dword high")
    DllStructSetData($sTemp, "Low", $vPropertyValue.LargeInteger.LowPart)
    DllStructSetData($sTemp, "High", $vPropertyValue.LargeInteger.HighPart)
    Local $sTemp2 = _Date_Time_FileTimeToSystemTime(DllStructGetPtr($sTemp))
    Local $sTemp3 = _Date_Time_SystemTimeToTzSpecificLocalTime(DllStructGetPtr($sTemp2))
    $aObjectProperties[$iCount3][1] = _Date_Time_SystemTimeToDateTimeStr($sTemp3, 1)
    EndIf
    Else
    $aObjectProperties[$iCount3][1] = __AD_LargeInt2Double($vPropertyValue.LargeInteger.LowPart, $vPropertyValue.LargeInteger.HighPart)
    EndIf
    ElseIf $oItem.ADsType = $ADSTYPE_OCTET_STRING Then
    $xAD_Dummy = DllStructCreate("byte[56]")
    DllStructSetData($xAD_Dummy, 1, $vPropertyValue.OctetString)
    ; objectSID etc. See: http://msdn.microsoft.com/en-us/library/aa379597(VS.85).aspx
    ; objectGUID etc. See: http://www.autoitscript.com/forum/index.ph…ndpost&p=767558
    If _Security__IsValidSid(DllStructGetPtr($xAD_Dummy)) Then
    $aObjectProperties[$iCount3][1] = _Security__SidToStringSid(DllStructGetPtr($xAD_Dummy)) ; SID
    Else
    $aObjectProperties[$iCount3][1] = _WinAPI_StringFromGUID(DllStructGetPtr($xAD_Dummy)) ; GUID
    EndIf
    ElseIf $oItem.ADsType = $ADSTYPE_DN_STRING Then
    $aObjectProperties[$iCount3][1] = $vPropertyValue.DNString
    ElseIf $oItem.ADsType = $ADSTYPE_UTC_TIME Then
    Local $iDateTime = $vPropertyValue.UTCTime
    $aObjectProperties[$iCount3][1] = StringLeft($iDateTime, 4) & "/" & StringMid($iDateTime, 5, 2) & "/" & StringMid($iDateTime, 7, 2) & _
    " " & StringMid($iDateTime, 9, 2) & ":" & StringMid($iDateTime, 11, 2) & ":" & StringMid($iDateTime, 13, 2)
    ElseIf $oItem.ADsType = $ADSTYPE_BOOLEAN Then
    If $vPropertyValue.Boolean = 0 Then
    $aObjectProperties[$iCount3][1] = "False"
    Else
    $aObjectProperties[$iCount3][1] = "True"
    EndIf
    ElseIf $oItem.ADsType = $ADSTYPE_NT_SECURITY_DESCRIPTOR Then
    $oValue = $vPropertyValue.SecurityDescriptor
    $aObjectProperties[$iCount3][1] = "Control:" & $oValue.Control & ", " & _
    "Group:" & $oValue.Group & ", " & _
    "Owner:" & $oValue.Owner & ", " & _
    "Revision:" & $oValue.Revision
    Else
    $aObjectProperties[$iCount3][1] = "Has the unknown ADsType: " & $oItem.ADsType
    EndIf
    Next
    EndIf
    Next
    $aObjectProperties[0][0] = UBound($aObjectProperties, 1) - 1
    $aObjectProperties[0][1] = UBound($aObjectProperties, 2)
    _ArraySort($aObjectProperties, 0, 1)
    Return $aObjectProperties

    [/autoit][autoit][/autoit][autoit]

    EndFunc ;==>_AD_GetObjectProperties

    [/autoit]

    [spoiler]

  • @freddyd

    dein Quelltext aus Post 40 funktioniert bei mir, wobei du mit der Anweisung "$aProperties = _AD_GetObjectProperties()" den Inhalt von $aProperties wieder überschreibst!
    Entweder ein _ArrayDisplay ($aProperties) zwischen die Zeilen, sodass du beide Ausgaben siehst oder eine von beiden einfach auskommentieren.

    Spoiler anzeigen
    [autoit]


    #Region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Outfile=C:\temp\test.Exe
    #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <AD.au3>
    #include <DATE.au3>
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    _AD_ErrorNotify(2)

    [/autoit] [autoit][/autoit] [autoit]

    _AD_Open("Domain\User","*PW*","","dc.domain.de:3268")

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(@error & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    $aProperties = _AD_GetObjectProperties(@UserName, "displayname,distinguishedName,pwdlastset")
    $aProperties = _AD_GetObjectProperties()

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite(@error & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    _ArrayDisplay ($aProperties)

    [/autoit] [autoit][/autoit] [autoit]

    ;$ddd = $aProperties[3][1]
    ;_DateTimeFormat($ddd,2)
    ;$zuletzt = _DateTimeFormat($ddd,2)&" "&" "&_DateTimeFormat($ddd,4)
    ;$aProperties = _AD_GetObjectProperties(@ComputerName & "$")
    ;$PCName = $aProperties[4][1]
    ;$PCBeschreibung = $aProperties[7][1]
    _AD_Close()

    [/autoit]

    funktioniert denn bei dir eine vbs abfrage auf das AD?
    als Beispiel diese

    [autoit]


    UserNameFromEmail "vorname.nachname@domain.de" 'hier deine firmenmailadresse eintragen

    [/autoit][autoit][/autoit][autoit]

    Sub UserNameFromEmail(sEmail)
    Const ADS_SCOPE_SUBTREE = 2
    Const PageSize = 1000
    Dim sRootLDAP, oConnection, oCommand, oRecordSet

    [/autoit][autoit][/autoit][autoit]

    sRootLDAP = "'LDAP://" & GetObject("LDAP://RootDSE").Get("defaultNamingContext") & "'"

    [/autoit][autoit][/autoit][autoit]

    Set oConnection = CreateObject("ADODB.Connection")
    oConnection.Provider = "ADsDSOObject"
    oConnection.Open "Active Directory Provider"
    Set oCommand = CreateObject("ADODB.Command")
    Set oCommand.ActiveConnection = oConnection
    oCommand.CommandText = "Select sAMAccountName from " & sRootLDAP & " Where mail='" & sEmail & "'"
    oCommand.Properties("Page Size") = PageSize
    oCommand.Properties("Timeout") = 30
    oCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    oCommand.Properties("Cache Results") = True
    Set oRecordSet = oCommand.Execute
    oRecordSet.MoveFirst
    Do Until oRecordSet.EOF
    WScript.Echo "Username for """ & sEmail & """ is """ & oRecordSet.Fields(0) & """"
    oRecordSet.MoveNext
    Loop
    Set oRecordSet = Nothing
    Set oCommand = Nothing
    Set oConnection = Nothing
    End Sub

    [/autoit]

    Gruß gmmg

  • Coole Idee :P

  • Du sagst es! Da es sich um eine überschaubare AD-Umgebung handelt, kann es eigentlich fast nur ein Bug in der UDF sein.