Active Directory Funktionen - Neue Version 1.5.0.0 freigegeben!

  • Hi Water - ich nochmal,

    da ich hier langsam mal Erfolge sehen möchte, habe ich eine Supportanfrage bei MS gestellt. Die Kostet zwar 299,- Euro, wird aber im Falle eine MS-Bugs (welcher dies hier nunmal ist) kostenlos.
    Da werd ich dem Techniker mal das Problem mit W-XP und Co. zur WLDAP32.DLL mitteilen und die werden darauf hin hoffentlich ein WindowsUpdate verteilen...
    Schaun wir mal. Dies wäre dann auf jeden Fall eine Alternative, daß ich den Leuten, die diese Anwendung ausführen wollen, sage, sie sollen Windows-Update mit KBxxxxxx installieren...
    Das kann jeder selbst und die meisten haben es eh auf automatisches Update.
    Bin mal gespannt, wie schnell MS da arbeitet...

  • Ich habe gerade eine Windows 7 Machine bekommen und werde da mal ein bischen spielen.

  • ich könnt fast wetten, daß dort das Ganze geht, weil ähnlich aktuell wie W2008. Es reicht schon, wenn du ADFind.exe zum testen nimmst...

    Ich hab übrigens nen Beitrag im WWW aus 2006 gefunden, da wird sich auch über das Problem ausgelassen - da gibts nen MSler, der mein, sollst LDAP_BIND_S mit LDAP_AUTH_NEGOTIATE nehmen, weil SIMPLE_BIND_S von MS nicht unterstütz werden will, wegen Klartext-PW...

    siehe hier

    LDAP_BIND_S bekomm ich irgendwie nur nicht zum laufen - sagt er mir immer Error 7 - muss heißen: Authentifizierungsmethode wird vom Server nicht unterstützt... Sollte aber bei W2003-AD klappen ?(

    Beispielaufruf - passt in meine anderen Scripte aus meinen älteren Beiträgen hier rein:

    [autoit]

    Func ldap_bind_s()
    $fkt = "ldap_bind_s"
    $dn = DllStructCreate("char")
    ;DllStructSetData($dn,1, "")

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

    $userdata = DllStructCreate("char[" & (StringLen($username) + 1) & "];" & _
    "ULONG;" & _
    "char[" & (StringLen($domain) + 1) & "];" & _
    "ULONG;" & _
    "char[" & (StringLen($Passwort) + 1) & "];" & _
    "ULONG;" & _
    "ULONG;")
    DllStructSetData($userdata,1, $username)
    DllStructSetData($userdata,2, StringLen($username))
    DllStructSetData($userdata,3, $domain)
    DllStructSetData($userdata,4, StringLen($domain))
    DllStructSetData($userdata,5, $Passwort)
    DllStructSetData($userdata,6, StringLen($Passwort))
    DllStructSetData($userdata,7, $SEC_WINNT_AUTH_IDENTITY_ANSI)

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

    Return DllCall($ldapldll, "ULONG", $fkt, "ptr", $ldapinit[0], "ptr",DllStructGetPtr($dn), "ptr",DllStructGetPtr($userdata), "ULONG", $LDAP_AUTH_NEGOTIATE)
    EndFunc

    [/autoit]
  • Habe ein Problem mit der Funktion _AD_ObjectExists()

    Wenn man ein Computerobjekt prüft, liefert die Funktion immer 0 zurück, auch dann wenn das Objekt existiert.

    Ruft man die Funktion so auf: _AD_ObjectExists($sAD_Object, "name")
    funktioniert es richtig.

    Das Problem tritt vor allem dann auf wenn die Funktion in anderen Funktionen genutzt wird, zum Beispiel _AD_MoveObjekt oder _AD_IsObjectDisabled.
    Hier lässt sich ja der 2. Parameter von _AD_ObjectExists() nicht verändern.


    Mir ist noch etwas aufgefallen, _AD_CreateComputer gibt 0 zurück, auch wenn das Computerobjekt erstellt worden ist. Fehlernummer: -2147352567

    3 Mal editiert, zuletzt von Bitboy (6. Mai 2010 um 10:15)

  • Um ein Computerobject zu prüfen gibt es zwei Möglichkeiten:

    Angabe eines Parameters: Per default wird dann der SamAccountName oder der distinguishedname (FQDN) geprüft (je nachdem wie $sAD_Object angegeben wurde). Bei Computern hat der SamAccountName am Ende ein "$" also z.B.: _AD_ObjectExists(@Computername & "$")
    Angabe von zwei Parametern: Dann kann angegeben werden, welche "Property" geprüft werden soll (die sollte natürlich sinnvollerweise eindeutig sein). Bei Computern lautet z.B. die Property "name" ohne das abschliessende "$" und daher funzt es bei Dir.
    _AD_ObjectExists(@Computername,"name")

    Zitat

    Mir ist noch etwas aufgefallen, _AD_CreateComputer gibt 0 zurück, auch wenn das Computerobjekt erstellt worden ist. Fehlernummer: -2147352567

    Der Code bedeutet: Allgemeiner Fehler. Bei Auftreten eines Fehlers liefert die Funktion immer 0.
    D.h. den Computer gab es vorher noch nicht, er wurde angelegt und trotzdem bekommst Du den angegebenen Fehler?

  • Ah, das mit dem Dollarzeichen hat schonmal das eine Problem gelöst. Danke, hatte cih ganz vergessen.

    Create Computer produziert allerdings immer noch diesen Fehler.
    Und ja es wird ein Computerkonto erstellt, dass vorher nicht da war.
    Kann es daran liegen, dass Ich _AD_Open mit Parametern aufrufe?
    Beziehungsweise an dem Parameter $sAD_UserID ?


    Geht mir darum folgende Funktion Nutzen zu können:

    Spoiler anzeigen
    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _AD_JoinDomainEX
    ; Description ...: Joins the computer to a domain.
    ; Syntax.........: _AD_JoinDomain([$sAD_Computer, $sAD_OU, $sAD_UserParam, $sAD_PasswordParam])
    ; Parameters ....: $sAD_Computer - Optional: Computername to join to the domain, Default = @Computername (The computer the script is running on)
    ; The computer account is created if it not exists
    ; The computer account is enabled if it is disabled
    ; An existing account is moved to the specified OU
    ; $sAD_OU - Optional: Organisation Unit to join to, Default = "Computers"
    ; Use a format like this to specify a sub-ou: Computers\London\Office
    ; The Organisation Unit is created if it not exists
    ; $sAD_UserParam - Optional: User with admin rights to join the computer to the domain (NetBIOSName)
    ; +(Default = credentials under which the script is run or from _AD_Open are used)
    ; $sAD_PasswordParam - Optional: Password for $sAD_UserParam. (Default = credentials under which the script is run are used)
    ; Return values .: Success - 1
    ; Failure - 0, @error set
    ; |1 - Failed to create OU, see @extended to see error code from _AD_CreateOU
    ; |2 - Failed to enable the computer object, see @extended to see error code from _AD_EnableObject
    ; |3 - Failed to move existing computer object, see @extended to see error code from _AD_MoveObject
    ; |4 - Failed to create computer object, see @extended to see error code from _AD_CreateComputer
    ; |5 - Failed to create computer object with UserParam, see @extended to see error code from _AD_CreateComputer
    ; |6 - Joining the domain was not successful. @extended holds the Win32 error code (see: http://msdn.microsoft.com/en-us/library/…1(v=VS.85).aspx)
    ; Author ........: Thomas Rupp
    ; Modified.......: Bitboy
    ; Remarks .......: The domain to which the computer is joined to is the domain the user logged on to using AD_Open.
    ; If no credentials are passed to this function but have been used with _AD_Open() then the _AD_Open credentials will be used for this function.
    ; You have to reboot the computer after a successful join to the domain.
    ; The JoinDomainOrWorkgroup method is available only on Windows XP computer and Windows Server 2003 or later.
    ; Related .......: _AD_CreateComputer
    ; Link ..........: http://technet.microsoft.com/en-us/library/ee692588.aspx, http://msdn.microsoft.com/en-us/library/aa392154(VS.85).aspx
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _AD_JoinDomainEX($sAD_Computer = "", $sAD_OU = "", $sAD_UserParam = "", $sAD_PasswordParam = "")
    Local $OUArr, $i, $sAD_ParentOU
    Local $sAD_DomainName = StringReplace(StringReplace($sAD_DNSDomain, "DC=", ""), ",", ".")

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

    $sAD_ParentOU = $sAD_DNSDomain
    $sAD_OUTemp = $sAD_OU

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

    If $sAD_Computer = "" Then $sAD_Computer = @ComputerName
    If $sAD_OU = "" Then
    $sAD_OU = "OU=Computers," & $sAD_DNSDomain
    Else
    $OUArr = StringSplit($sAD_OU, "\", 1)
    ;Check if OU exits, otherwise create it
    For $i = 1 To $OUArr[0]
    $sAD_OU = $OUArr[$i]
    If _AD_ObjectExists($sAD_OU , "distinguishedName") = 0 Then
    _AD_CreateOU($sAD_ParentOU, $sAD_OU)
    If @error Then
    If @error <> 2 Then Return SetError(1, @error, 0)
    EndIf
    EndIf
    $sAD_ParentOU = "OU=" & $sAD_OU & "," & $sAD_ParentOU
    Next

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

    $sAD_OU = ""
    For $i = $OUArr[0] To 1 Step -1
    $sAD_OU = $sAD_OU & "OU=" & $OUArr[$i] & ","
    Next
    $sAD_OU = $sAD_OU & $sAD_DNSDomain
    EndIf

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

    ;Check if computer account exists
    If _AD_ObjectExists($sAD_Computer & "$") = 1 Then
    _AD_MoveObject($sAD_OU, $sAD_Computer & "$")
    If @error > 0 Then Return SetError(3, @error, 0)

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

    ;Check if is disabled
    If _AD_IsObjectDisabled($sAD_Computer & "$") Then _AD_EnableObject($sAD_Computer & "$")
    If @error Then Return SetError(2, @error, 0)
    Else
    ;account does not exist
    ;create computer account
    If $sAD_UserParam = "" Then
    _AD_CreateComputer($sAD_OU, $sAD_Computer, $sAD_UserId)
    If @error Then Return SetError(4, @error, 0)
    Else
    ;Todo
    ;_AD_CreateComputer($sAD_OU, $sAD_Computer, $sAD_DomainName & "\" & $sAD_UserParam)
    ;If @error Then Return SetError(5, @error, 0)
    EndIf
    EndIf

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

    ; _AD_JoinDomain($sAD_Computer, $sAD_UserParam, $sAD_PasswordParam)
    ; If @error Then Return SetError(6, @error, 0)
    Endfunc

    [/autoit]
  • Bei _AD_CreateComputer wird ein User oder eine Gruppe definiert, die das Recht hat den Computer dann in die Domäne zu hängen (mit _AD_JoinDomain).
    D.h. $sAD_User bei _AD_CreateComputer und $sAD_UserParam bei _AD_JoinDomain müssen ident sein bzw. $sAD_UserParam muss ein Mitglied der bei _AD_CreateComputer angegebenen Gruppe sein.
    Wird bei _AD_JoinDomain kein User/Passwort angegeben, dann werden die credentials von _AD_Open verwendet bzw. - wenn diese nicht gesetzt wurden - die credentials des users der das Skript ausführt.

  • Leider nein - und meine W7 Maschine wird auch erst später so ins Netz genommen, dass ich Zugriff auf das AD habe.
    Ich denke, dass ich dann den GetLastError Ansatz verfolgen werde. Dies hat den Vorteil, dass ich ohne externes Programm auskomme. Wenn ich das in eine Funktion einbaue, dann kann ich jederzeit (nicht nur beim Open) die letzte LDAP Meldung abfragen.

  • ja, auf jeden Fall, das AdFind ist nur ne gute Lösung, um ohne Autoit schnell mal zu testen, obs geht.
    Das Adfind und GetLastError die gleiche DLL schlussendlich verwenden, wird GetLastError immer gehen, wenn AdFind geht...

  • Hm, komisch.

    Der Fehler tritt nciht auf, wenn "Administratoren" als Gruppe eingegeben werden.
    Bei einer anderen Gruppe, die ebenfalls das Recht hat Rechner zur Domäne hinzuzufügen kommt der Fehler wieder.

    Wäre es ein Rechteproblem, dürfte das Objekt doch auch gar nicht erstellt werden oder?

  • Zitat

    Der Fehler tritt nicht auf, wenn "Administratoren" als Gruppe eingegeben werden.
    Bei einer anderen Gruppe, die ebenfalls das Recht hat Rechner zur Domäne hinzuzufügen kommt der Fehler wieder.


    Ich glaube, Du verwechselst hier zwei Dinge. Das Recht Rechner zur Domäne hinzuzufügen wird erst bei _AD_JoinDomain schlagend.

    Zitat

    Wäre es ein Rechteproblem, dürfte das Objekt doch auch gar nicht erstellt werden oder?


    Wenn ich das richtig verstehe wird bei _AD_CreateComputer der Computer korrekt angelegt (Schritt 1). In Schritt2 versucht _AD_CreateComputer die ACL mit dem durch Parameter 3 definierten User zu befüllen. Dieser User müsste dann später _AD_JoinDomain ausführen um den Computer in die Domäne zu nehmen.
    Ein Zugriffsrechteproblem könnte es nur dann sein, wenn der User der _AD_CreateComputer aufruft nur das Recht hat einen Computer anzulegen aber nicht das Recht hat die Berechtigungen anzupassen.

    • Kannst Du mal prüfen, welche Rechte der aufrufende User im AD hat?
    • Oder Du könntest dieses VB-Skript testen. Darauf baut _AD_CreateComputer auf. Wenn es funzt, dann ist es ein Problem meines UDF. Sollte es nicht funzen, dann ist es ein generelles Rechteproblem.
  • Hi water,

    hab ein Statement von MS, nachdem ich den Bug offiziell gemeldet habe.
    Der Bug ist denen bekannt, wenn ich darlegen könnte, daß mir durch den Bug Millionen und Abermillionen an Gewinnen verloren gehen, dann würde eine eher unwahrscheinliche Chance entstehen, den Fehler zu fixen.
    Also ich übersetz mal frei: Egal was du versuchst, wir werden dir bei einem OS, was eigentlich schon nicht mehr aktuell sein sollte, nicht mehr helfen...

    Soviel dazu...

    Schlussendlich bedeutet dies für uns, entweder wir finden eine mini-DLL, die die reine Anmeldefkt. übernehmen kann oder die Anmeldung über dein GetLastError-Objekt wird erst ab Windows 7 (bei Vista keine Erfahrung bislang) mit Bordmitteln klappen.

    card

  • Hi card,
    danke für die Info!
    Das Stichwort ist "Support von MS". Da in nächster Zeit sowieso die meisten Unternehmen auf W7 umstellen (müssen), teste ich die Fehlerprüfung mit W7 sobald ich in der Domäne hänge. Ältere Windows Versionen haben dann leider "Pech" gehabt und müssen die Fehlersuche manuell machen.
    Die ganze Fehlersuche war ziemlich mühsam und das Ergebnis typisch M$.
    Schönes - wenn auch leider verregnetes - WE
    water

  • hi
    habe gerade mal über die ad passwörter nachgedacht...
    wenn ich ein script schreiben will, dass das userpasswort (in meiner gui) auf richtigkeit des entsprechenden ad users überprüfen soll, dann würde das durch die passwort"verschlüsselung" nicht möglich sein oder?

    gruß
    Mark

  • Mein Wissensstand ist folgender (kurz gefasst):
    Userid/Passwort kann nur durch eine Anmeldung geprüft werden. Erst ab Windows 7 gibt Windows dann ausreichend Information zurück um festzustellen, ob das Passwort falsch war. Derzeit ist das aber noch nicht in der UDF implementiert.

    Auf diesem Forum bzw. dem englischen wurde diese Frage aber sicher auch schon zig-mal besprochen. Vielleicht gibt es da eine andere/bessere Lösung.

  • Sorry wenn ich nun hier direkt reinplatze, aber ich bekomme das UDF irgendwie garnicht zum laufen. Vielleicht hat von euch spontan einer eine Idee.

    Ich sitze an einem Win XP mit SP2 und es ist eine 2003er Domäne.

    [autoit]

    #include <AD.au3>

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

    _AD_Open("testuser", "testpasswd"

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

    _AD_Close

    [/autoit]

    Also ihr seht, nichts besonderes ;o))

    Ich erhalte aber folgende Fehlermeldung:

    Spoiler anzeigen

    Hat jemand eine Idee ??

    Grüße
    CrazyER

  • Ja, habe ne Idee (selten aber doch).
    Du hast 'ne "alte" AutoIt Version die im Date UDF noch nicht alle Parameter unterstützt die das AD UDF verwendet.
    Kannst Du mal auf mind. 3.3.6.0 updaten?

  • Hallo Zusammen,

    erst einmal vielen Dank für die klasse UDF.

    Mein Ziel ist es, über die UDF einen Rechner in das AD aufzunehmen. Dabei bin ich leider auf Schwierigkeiten gestossen.

    Eine Frage zu AD_Open: Ein Rechner, der ins AD soll, hat ja noch keinerlei Login-Informationen des AD sondern lediglich einen User mit entsprechenden Rechten (Admin). Nun habe ich versucht, mich mit AD_Open(Username, Passwort, Domain) an der Domäne anzumelden. Dies erzeugte einen Fehler 6 der besagt, daß ich einen DC sowie ConfigParam angeben soll. DC ist mir ja soweit noch klar, aber was ist mit ConfigParam gemeint? Wenn ich nur Benutzername und Passwort angebe, dann bekomme ich einen Fehler in @Error "0" und in @Extended auch "0" ...

    Eine Frage zu AD_CreateComputer: Hier kann ich machen was ich will. Das AD_Open ist erfolgreich, leider liefert mit AD_CreateComputer in @Error und @Extension jeweils nur den Wert "0" zurück. Was mache ich hier falsch? Der Rechnername ist der, den ich mit @ComputerName ermittle, der Anmeldename ist identisch mit dem bei AD_Open. Und die OU ist auch korrekt. Wenn ich den Rechner mit meinen Anmeldedaten manuell ins AD aufnehme, dann klappt alles. Auch mit dem NetDom.exe und den Anmeldedaten bzw. der OU funktioniert es. Insofern liegt es zumindest einmal nicht an fehlenden Rechten im AD, irgendetwas habe ich hier wohl falsch gesetzt. Ich bin mit meiner "Weisheit" ein wenig am Ende ... :S

    In dem Zusammenhang (weil - soweit komme ich ja gar nicht): Gibt es etwas, daß ich bei AD_JoinDomain beachten müßte?

    Vorab vielen Dank für eure Hilfe,
    Grüße

    TheDude

    Cuiusvis hominis est errare, nullius nisi insipientis in errore perseverare.
    [Cicero, Philippica 12,2]