AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Active Directory - Alle Benutzer auslesen - mit ActiveDS_TLB
Thema durchsuchen
Ansicht
Themen-Optionen

Active Directory - Alle Benutzer auslesen - mit ActiveDS_TLB

Offene Frage von "wschrabi"
Ein Thema von cherry · begonnen am 6. Dez 2007 · letzter Beitrag vom 20. Apr 2023
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#11

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 18. Mär 2008, 13:41
Hey alter Mann...

viellecht kannst du mir ja helfen. Ich verzweifle an dem Versuch dein Code mit BDS 2005 zu compillieren...

Ich denke es liegt evt. An der ActiveDS_TLB ?! oder an mir. Ich kann es drehen wie ich will, ich brings nicht zustande alle Fehler zu beheben, sodass ich das Programm kompillieren kann.

Wenn ich den Code so nehme wie du ihn hier hochgestellt hast, erhalte ich folgenden Pascal Fehler:
(Hab deine losen Dateien in ein Projekt zusammengefasst und die Units: ActiveDs_TLB, ADsHlp, AdsErr; verlinkt.. [uses])

[Pascal Fataler Fehler] AdsErr.pas(9): F1026 Datei nicht gefunden: 'WINDEFINES.INC' Keine Ahnung was WINDEFINES.INC ist... habe aber hier etw. gefunden: http://www.koders.com/noncode/fid51D92531297E3E551D073B83B780F0EC12AF01D7.aspx. Habe die Datei dort mal heruntergeladen und dem Projekt zugänglich gemacht. -> Die Fehlermedlung verschwindet...

Nun kommt eine andere Meldung und zwar:

[Pascal Fehler] frmMain.pas(152): E2010 Inkompatible Typen: 'Pointer' und 'ads_searchpref_info' und es markiert diese Zeile:

if not SUCCEEDED(search.SetSearchPreference(opt, 1)) then wie krieg ich nun diese Meldung weg? (danach kommen sicher nochmal n paar, aber ohne eure Hilfe schaff ich das eh net...)

// EDIT:

Hab nun auch diese Meldung weggebracht, indem ich in ActiveDS_TLB folgende Änderung vorgenommen habe:

Delphi-Quellcode:
function SetSearchPreference( pSearchPrefs : ads_searchpref_info; // vorher " Pointer " #enemyleft 18.03.2008
                                          dwNumPrefs : LongWord ): HResult; stdcall;
aber wie es so ist, erhalte ich nun eine andere Fehlermeldung...

[Pascal Fehler] frmMain.pas(173): E2003 Undefinierter Bezeichner: 'ObjectName' in den Zeilen:

Delphi-Quellcode:
if Included(SearchText, col.pAdsValues^.__MIDL_0010.BackLink.ObjectName) then
                     Items.Add(col.pszAttrName + ': ' + col.pAdsValues^.__MIDL_0010.BackLink.ObjectName);
// EDIT2:

Ich hab die Zeile von

Delphi-Quellcode:
if Included(SearchText, col.pAdsValues^.__MIDL_0010.BackLink.ObjectName) then
                     Items.Add(col.pszAttrName + ': ' + col.pAdsValues^.__MIDL_0010.BackLink.ObjectName);
auf:

Delphi-Quellcode:
if Included(SearchText, col.pAdsValues^.__MIDL_0010.DNString) then
                     Items.Add(col.pszAttrName + ': ' + col.pAdsValues^.__MIDL_0010.DNString);
geändert... jetzt klappts...
aber is doch irgendwie schräg.. naja
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#12

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 18. Mär 2008, 16:30
Ich konnte das Programm von alterMann jetzt zwar kompillieren, aber manchmal! treten komische Fehler auf...
ich kann im Moment noch keine logische Regelmäsigkeiten feststellen...

je nachdem wieviele und welche Propertys ich mitgebe... Manchmal gehts machmal nicht ?!


aber es ist eine

Zugriffsveletzung bei der Adresse 76DE1D17 in Modul 'adsldpc.dll'. Schreiben von Adresse 00000025. Die Zeile

if not SUCCEEDED(search.SetSearchPreference(opt, 1)) then wird hierbei markiert...

Genau bei der Funktion die ich in ActiveDs_TLB etwas angepasst habe.. ich habe den Parametertyp von Pointer auf ads_searchpref_info
ändern müssen damit ich das Projekt kompillieren konnte.

Wär toll wenn mir noch jmd sagen kann was ich falsch mache...
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
947 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#13

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 18. Mär 2008, 18:56
Hallo cherry,

ich werde mich des Problems annehmen.
Es gab damals einige Ungereimtheiten, da der Typlib-Import andere Deklarationen zu Tage brachte
als in der MSDN vermerkt.
Falls ich es schaffe werden ich diesmal (hoffentlich) alles beilegen.

Bis bald.

Edit:

Anbei ein vollständiges? Beispiel für BDS 2K5U1, getestet.
Angehängte Dateien
Dateityp: zip search_200.zip (51,2 KB, 125x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#14

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 19. Mär 2008, 08:27
Super alterMann, vielen Dank. Das zweite Programm funktioniert... ich habe gesehen, dass es fast gleich ausschaut wie mein abgeändertes der ersten Version.

Ich habe noch eine Zwischenfrage die sicher schnell beantwortet ist. Denn ich werde das Gefühl nicht los, dass ich den sAMAccountName mit diesem Programm nicht auslesen kann. Ist das so? wie krieg ich den?
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
947 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#15

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 19. Mär 2008, 18:34
Hallo cherry,

der sAMAccountName kann damit ausgelesen werden, der Eintrag muss sich in der Liste s.o. Punkt 4 befinden.
Bitte auch das Beispiel und den Nachastz bei #9 beachten, vielleicht liegt es ja daran?

Gruß
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#16

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 20. Mär 2008, 14:14
Versteh ich das richtig...
Die Funktion gibt Übereinstimmungen von SearchText und den angegebenen Properties zurück?! Ich kann z.B. nicht nur nach cn suchen, und dabei mehrere Werte zurück erhalten? -Es wird immer in allen Properties nach Übereinstimmungen gesucht?

- und gibt mir auch nur die Properties zurück in denen was gefunden wurde?

Und was wenn ich nach cn suchen will und folgende Werte erhalten möchte

sAMAccountName
mail
...

???
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
947 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#17

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 20. Mär 2008, 18:55
?

Alles gelesen und fasst richtig verstanden!

Delphi-Quellcode:
    function DirectorySearch(Properties : Array of PWideChar;
                             SearchText : String;
                             Category : String;
                             out Items : TStringList) : Boolean;
In Properties werden alle Attribute gespeichert die gesucht werden sollen.
Wenn also der sAMAccountName vom User "Franz Mustermann" gesucht wird, dann
muss im Array das Attribut 'sAMAccountName' vorhanden sein, als auch ein Attribut
in dem der Name des Benutzers vorkommen muss.

In diesem Fall also die Attribute 'cn' und 'sAMAccountName'.

[Edit]

Damit das ganze dann auch funktionieren soll, muss in der function DirectorySearch
folgende Passage
Delphi-Quellcode:
        if SUCCEEDED(hr) then
        begin
          hr := search.GetNextRow(ptrResult);

          while (hr <> S_ADS_NOMORE_ROWS) do
          begin
             for idx := 0 to dwCount -1 do
             begin
               if Succeeded(search.GetColumn(ptrResult, Properties[idx], col)) then
               begin
                 if col.pADsValues <> nil then
                 begin
                   if Included(SearchText, col.pAdsValues^.__MIDL_0010.BackLink.ObjectName) then
                   Items.Add(col.pszAttrName + ': ' + col.pAdsValues^.__MIDL_0010.BackLink.ObjectName);
                 end;
                 search.FreeColumn(col);
               end;
             end;
             hr := search.GetNextRow(ptrResult);
          end;
        end;
durch diese
Delphi-Quellcode:
        if SUCCEEDED(hr) then
        begin
          hr := search.GetNextRow(ptrResult);
          found := false;
          while (hr <> S_ADS_NOMORE_ROWS) do
          begin
             for idx := 0 to dwCount -1 do
             begin
               if Succeeded(search.GetColumn(ptrResult, Properties[idx], col)) then
               begin
                 if col.pADsValues <> nil then
                 begin
                   if not found then
                   begin
                     found := Included(SearchText, col.pAdsValues^.__MIDL_0010.BackLink.ObjectName);
                     if found then
                     Items.Add(col.pszAttrName + ': ' + WideCharToString(col.pAdsValues^.__MIDL_0010.BackLink.ObjectName));
                   end
                   else
                   Items.Add(col.pszAttrName + ': ' + WideCharToString(col.pAdsValues^.__MIDL_0010.BackLink.ObjectName));
                 end;
                 search.FreeColumn(col);
               end;
             end;
             hr := search.GetNextRow(ptrResult);
             found := false;
          end;
        end;
ersetzt werden. Nicht vergessen die Variable found : Boolean einzufügen.

Und Bitte nur Attribute verwenden die es gibt, es ist dies bezüglich keine Fehlerbehandlung vorhanden.
  Mit Zitat antworten Zitat
Benutzerbild von cherry
cherry

Registriert seit: 14. Nov 2005
561 Beiträge
 
RAD-Studio 2009 Ent
 
#18

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 26. Mär 2008, 10:18
Super, genau das habe ich gewollt.

Nun möchte ich aber als Rückgabewert keine TStringList sondern ein Mehrdimensionales Dynamisches Array...
Ich hab das mal so gemacht:

Delphi-Quellcode:
type
  TItemArray = array of array of String;
Delphi-Quellcode:
function DirectorySearch(ADsPath: String; Properties : Array of PWideChar; SearchText : String; Category : String) : TItemArray; stdcall;

  function Included(str1, str2 : String) : boolean;
  var
    s1, s2 : String;
  begin
    s1 := UpperCase(Str1);
    s2 := UpperCase(Str2);
    Result := POS(s1, s2) <> 0;
  end;
var
  Search : IDirectorySearch;
  ptrResult : THandle;
  col : ads_search_column;
  hr : HResult;
  opt : ads_searchpref_info;
  dwCount : DWORD;
  dwErr : DWord;
  szErr : array[0..255] of WideChar;
  szName : array[0..255] of WideChar;
  i,idx : Integer;
  found, empty : Boolean;
begin
  if SUCCEEDED(ADsGetObject(ADsPath, IDirectorySearch, Search)) then
  begin
    try
      opt.dwSearchPref := ADS_SEARCHPREF_SEARCH_SCOPE;
      opt.vValue.dwType := ADSTYPE_INTEGER;
      opt.vValue.__MIDL_0010.Integer := ADS_SCOPE_SUBTREE;
      if not SUCCEEDED(search.SetSearchPreference(opt, 1)) then
      begin
         ADsGetLastError(dwErr, @szErr[0], 254, @szName[0], 254);
         ShowMessage(WideCharToString(szErr));
         Exit;
      end;
        dwCount := Length(Properties);
        hr := search.ExecuteSearch(StringToOleStr('(objectCategory=' + Category + ')'), @Properties[0], dwCount, ptrResult);
        found := false;
        if SUCCEEDED(hr) then
        begin
          hr := search.GetNextRow(ptrResult);
          i := 0;
          while (hr <> S_ADS_NOMORE_ROWS) do
          begin

            setLength(Items, i+1, dwCount);
            empty := true;

            for idx := 0 to dwCount -1 do
            begin
             if Succeeded(search.GetColumn(ptrResult, Properties[idx], col)) then
             begin
               if col.pADsValues <> nil then
               begin
                 if not found then
                 begin
                   found := Included(SearchText, col.pAdsValues^.__MIDL_0010.BackLink.ObjectName);
                   if found then
                   begin
                     Items[i,idx] := col.pAdsValues^.__MIDL_0010.BackLink.ObjectName; {col.pszAttrName + ': ' +}
                     empty := false;
                   end;
                 end
                 else
                 begin
                   Items[i,idx] := col.pAdsValues^.__MIDL_0010.BackLink.ObjectName; {col.pszAttrName + ': ' +}
                   empty := false;
                 end;
               end;
               search.FreeColumn(col);
             end;
            end;
            hr := search.GetNextRow(ptrResult);
            found := false;

            if not empty then
              inc(i);

          end;
        end;
    finally
    end;
  end;

  Result := Items;
  
end;
Der letzte Array Eintrag ist allerdings immer leer und ich frage mich sowieso, ob dieser Code "schön" ist oder nicht?!
Vielleicht sieht ja jmd gleich eine Verbesserung die gemacht werden könnte?!

- Aber bei mir funktionierts auf jeden fall...

LG Cherry
Ist das nur mein Gefühl, oder ist die ganze Welt verrückt geworden!?
  Mit Zitat antworten Zitat
ducci

Registriert seit: 15. Nov 2006
3 Beiträge
 
#19

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 13. Mai 2008, 09:10
Hi

habe auch das Beispielprogramm von @Alter Mann genutzt, erst einmal super lieben Dank!!

Was mir aber auffällt ist, suche ich z.b. nach sAMAccountname (im Include ist sn, mail, sAMAccountname,distinguishedName)
erhalte ich leider nur dann unter SearchResult einen Eintrag zum sAMAccountname und distinguishedName.
sn und mail sind leider leer, wo ist der Haken, irgendwas ist nicht OK oder ist es Ok und ich habe etwas falsch gemacht.

Denn ich würde gerne nach sAMAccountname suchen und alle anderen Attribute auslesen, geht das irgendwie??

Für Hilfe wäre ich sehr dankbar
  Mit Zitat antworten Zitat
Alter Mann

Registriert seit: 15. Nov 2003
Ort: Berlin
947 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#20

Re: Active Directory - Alle Benutzer auslesen - mit ActiveDS

  Alt 13. Mai 2008, 19:50
Hi

Zitat:
Was mir aber auffällt ist, suche ich z.b. nach sAMAccountname (im Include ist sn, mail, sAMAccountname,distinguishedName)
erhalte ich leider nur dann unter SearchResult einen Eintrag zum sAMAccountname und distinguishedName.
Das kann, muss aber nicht ein Fehler sein. Es kommt darauf an wie die Konten angelegt werden/wurden.
sn ist zum Beispiel ein optionaler Wert, der angelegt werden kann, aber nicht muss.
Bei mail sieht es etwas anders aus, er wird angelegt wenn ein Mail-Server(ExChange ab 2003) verwendet wird,
der sich in die ADS einklinkt.

Die genaue Wertzuweisung kann in diesem Fall nur mit ADSIEDIT überprüft werden(ist auch in den Support-Tools W2K3 enthalten).

Kleiner Tipp an Rande: Die Abfrage von Werten bzw. die Zuweisung von weiteren optionalen Werten kurz nachdem
anlegen eines Benutzers machen keinen Sinn, da die ADS einige Sekunden braucht um die Werte zu replizieren
(Die Zeitspanne ist davon Abhängig wie viele Global Catalog - Server vorhanden sind).

Gruß
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz