Avatar billede kennethv Nybegynder
10. januar 2014 - 12:12 Der er 37 kommentarer og
1 løsning

AD og LargeInteger/Interval

Hejsa.

Jeg sidder og skal trække data ud fra vores AD miljø via SQL syntax. Noget af det data er at finde ud af hvornår en computer sidst har været logget ind i systemet.

Atribute: lastLogonTimestamp

men den er en largeInteger/Interval.

Jeg aner ikke hvordan den ged skal barberes.

Er der nogen der kan hjælpe mig med det?

Hvis jeg bruger ADSI edit kan jeg hive det her ud fra een:

129938926523378190
Avatar billede kennethv Nybegynder
10. januar 2014 - 12:14 #1
129938926523378190 = 05-10-2012 08:37:32
Avatar billede kennethv Nybegynder
10. januar 2014 - 13:00 #2
Det er selvfølgelig en dato jeg er interesseret i.

:)
Avatar billede MADOlsen Forsker
10. januar 2014 - 13:54 #3
Halvvejs frit fra hukommelsen:


function LargeIntToDateTime(Value: Int64): TDateTime;
var
  lastLogonTime: double;
begin
  lastLogonTime := Value / (60 * 10000000);
  lastLogonTime := lastLogonTime / 1440;

  Result := EncodeDate(1601,1,1) + lastLogonTime ;
end;


Forklaring følger lige, når jeg kommer hjem.
Avatar billede kennethv Nybegynder
10. januar 2014 - 15:22 #4
Jeg har prøvet at kalde din funktion.

var
  dt : TDateTime;
begin  //objectClass='+ Quotedstr('computer');
  try
    ADOQuery4.SQL.Clear;
    ADOQuery4.SQL.Text := 'SELECT operatingSystem, lastLogonTimestamp FROM '+ Quotedstr'LDAP://OU=COMPUTERS,OU='+copy(ComputerNavn,3,2)',OU='+copy(ComputerNavn,1,2)',OU=firmanavn,DC=AD,DC=firmanavn,DC=ORG') + ' WHERE cn = '+ QuotedStr(ComputerNavn);
    ADOQuery4.Open;
    DT := LargeIntToDateTime(ADOQuery4.FieldByName('lastLogonTimestamp').AsLargeInt);
  finally
    ADOQuery4.Close;
  end;
end;

Men jeg får denne fejl:

'Could not convert variant of type (Dispatch) into type (Boolean)'
Avatar billede kennethv Nybegynder
10. januar 2014 - 15:42 #5
Tilgengæld, hvis jeg gør sådanne her får jeg ingen fejl og MyVarArray er : $046efab4


var
MyVarArray : Variant

MyVarArray := ADOQuery4.FieldByName('lastLogonTimestamp').AsVariant;

Jeg har ingen ide om hvad jeg pt laver prøver mig frem, men jeg ved om man kan bruge $046efab4 til noget.

Håber at du kan hjælpe mig.
Avatar billede kennethv Nybegynder
10. januar 2014 - 15:46 #6
Hov, ved IKKE om $046efab4 kan bruges til noget. Skulle der have stået. :)
Avatar billede kroning Nybegynder
10. januar 2014 - 20:23 #7
The 18-digit Active Directory timestamps, also named 'Windows NT time format' and 'Win32 FILETIME or SYSTEMTIME'. These are used in Microsoft Active Directory for pwdLastSet, accountExpires, LastLogon, LastLogonTimestamp and LastPwdSet. The timestamp is the number of 100-nanoseconds intervals (1 nanosecond = one billionth of a second) since Jan 1, 1601 UTC.
Avatar billede kroning Nybegynder
10. januar 2014 - 20:24 #8
Avatar billede MADOlsen Forsker
10. januar 2014 - 21:39 #9
#4 Har du prøvet bare at kalde funktionen med f.eks. det tal du skrev, for at se om den virker?
Avatar billede kennethv Nybegynder
10. januar 2014 - 22:31 #10
@kroning.

Det er en lille smule besværligt at skulle gøre det med 50+ rekords.
Avatar billede kroning Nybegynder
10. januar 2014 - 23:05 #11
Det var ikke min tanke at du skulle bruge hjemmesiden til din læsning men blot så du kunne se at det er den rigtige måde at regne tallet om til en dato/tid.
Men nu da jeg har læst alle indlæg :-) kan jeg se at fedeko´s function LargeIntToDateTime jo gør lige det.
Avatar billede kroning Nybegynder
10. januar 2014 - 23:07 #12
Og jeg mener "til din løsning" og ikke "til din læsning" som jeg skrev.
Avatar billede kennethv Nybegynder
13. januar 2014 - 11:11 #13
@Fedeko

Jeg får denne fejl:

Incompatible types: 'Int64' and 'string'

Når jeg kalder funktionen med det tal

dt : TDatatime;

Begin
  dt := LargeIntToDateTime('129938926523378190');
end;
Avatar billede MADOlsen Forsker
13. januar 2014 - 11:28 #14
#13 Som fejlmeddelesen siger, så skal funktionen kaldes med en Int64 i stedet for en String. Så prøv at fjerne de to ' ;-)

Jeg nåede da i øvrigt ikke at komme med en nærmere forklaring, men det kan jeg se, at kroning har klaret for mig.
Avatar billede MADOlsen Forsker
13. januar 2014 - 11:33 #15
Nu har jeg i øvrigt netop endelig fået tid til at teste funktionen selv, og den ser ud til at fungere præcis efter hensigten.
Avatar billede kennethv Nybegynder
13. januar 2014 - 13:02 #16
@Kroning.

Jeps. Jeg prøvede det på det link du sendte og det virkede på den første af de 2 muligheder.
Avatar billede kennethv Nybegynder
13. januar 2014 - 13:06 #17
@Fedeko.

Jeg fjerne de 2 '

men resultatet er: 30-12-1899.

Det skulle have været 05-10-2012
Avatar billede kroning Nybegynder
13. januar 2014 - 13:13 #18
Du skal nok vise noget kode, jeg har også prøvet fedeko´s funktion og den virker fint.
Avatar billede kennethv Nybegynder
13. januar 2014 - 13:17 #19
Det er den samme kode som i #13 bare uden de der ''
Avatar billede MADOlsen Forsker
13. januar 2014 - 13:25 #20
Hmm... 1899-12-30 svarer til værdien 0. Hvordan udlæser du værdien af variablen dt?
Avatar billede MADOlsen Forsker
13. januar 2014 - 13:28 #21
I #13 kan jeg se, at dt er af typen "TDatatime" - den datatype kender jeg ikke lige... :-)
Avatar billede kennethv Nybegynder
13. januar 2014 - 13:44 #22
Det er osse mig der er en torsk. :)

Det er en TDateTime.
Avatar billede MADOlsen Forsker
13. januar 2014 - 14:07 #23
Det havde jeg godt nok på fornemmelsen ;-)

Men hvis du nu kopierede koden ind, i stedet for at skrive den ind (det går jeg ud fra, at du har gjort, da der jo må have stået TDateTime i din kode, da du ellers ville have fået en compile fejl), så vi slipper vi jo for den ekstra fejlmulighed, at du får skrevet forkert, når du skriver koden herind.

Hvordan udlæser du værdien af din dt-variabel?
Avatar billede kennethv Nybegynder
13. januar 2014 - 14:08 #24
Det var bare en tyrkfejl og ikke en copy'n'paste.
Avatar billede kennethv Nybegynder
13. januar 2014 - 14:12 #25
Jeg har bare lavet en Debug Watch på DT.
Avatar billede MADOlsen Forsker
13. januar 2014 - 14:13 #26
Det jeg prøver at skrive er, at når du skal sætte din kode ind i indlæggene her på Eksperten, ville være klart at foretrække, hvis du kopierede den ind, netop for at udelukke tyrkfejl.

Og da der jo ikke kan have stået "TDataTime" i din kode (for så havde den ikke kompileret), så kan du jo ikke have kopieret den herind.
Avatar billede kennethv Nybegynder
13. januar 2014 - 14:24 #27
Da jeg skrev #24 var #23 ikke tilstede.

Men jeg har forstået. Det gør jeg nu osse normalt. :)

Men når det nu er sagt, så gjorde jeg dette istedet:

strtest := datetimetostr(LargeIntToDateTime(129938926523378190));

Så viser den det rigtige. Eneste forskel er at tiden ikke er korrekt 2 timers til forskel, men det er nu ikke så vigtig. Men hvordan får jeg kun datoen ud og hvordan får jeg det rigtig tal fra AD?

Lige nu har jeg bare sat tallet ind.
Avatar billede MADOlsen Forsker
13. januar 2014 - 14:42 #28
Den forskel du ser, er de to timers forskel, der er mellem UTC og dansk sommertid.

Du kan "filtrere" tiden væk sådan:

DateOf(LargeIntToDateTime(et tal);
Avatar billede kennethv Nybegynder
13. januar 2014 - 14:56 #29
Smukt.

Ved du hvordan jeg trækker det rigtige tal ud af AD?

Jeg har prøvet #4, men får en fejl.

Ved ikke hvad jeg skal bruge.
Avatar billede MADOlsen Forsker
14. januar 2014 - 09:23 #30
Jeg har så nogenlunde styr på Delphi, men Active Directory ved jeg ualmindelig lidt om, så der må jeg nok desværre melde pas :-(
Avatar billede MADOlsen Forsker
14. januar 2014 - 09:24 #31
Meeen jeg har da nu også styr på SQL. Hvilken fejl får du?
Avatar billede kennethv Nybegynder
14. januar 2014 - 11:08 #32
Jeg får skam ikke nogen fejl med min syntax. Det er bare resultatet der ikke spiller sammen med den funktion du har lavet.

Jeg har forsøgt mig frem, som du kan se i de tidligere indlæg, men det har ikke hjulpet.
Avatar billede kennethv Nybegynder
14. januar 2014 - 11:10 #33
Prøv at se #4.
Avatar billede MADOlsen Forsker
14. januar 2014 - 11:49 #34
Hvornår præcist får du fejlen? Det ligner nemlig ikke noget, min funktion kunne finde på at lave.
Avatar billede kennethv Nybegynder
14. januar 2014 - 12:02 #35
Jeg ved ikke hvor problemet er helt præcis. Det eneste jeg kan se er at .AsLargeInt er af typen Int64 og det er osse det din funktion forventer.

http://docwiki.embarcadero.com/VCL/2010/en/DB.TField.AsLargeInt
Avatar billede kennethv Nybegynder
14. januar 2014 - 12:15 #36
Jeg har prøvet det her:

bigInt : Int64;

begin
  bigint := ADOQuery4.FieldByName('lastLogonTimestamp').AsLargeInt;
end;

Det er samme fejl som i #4.

'Could not convert variant of type (Dispatch) into type (Boolean)'
Avatar billede kennethv Nybegynder
15. januar 2014 - 11:50 #37
@fedeko.

Du må ligge et svar for det du har lavet.
Avatar billede MADOlsen Forsker
16. januar 2014 - 08:23 #38
Jeg må desværre blive dig svar skyldig. Har som sagt meget lidt  forstand på Active Directory.

Men nu har du i hvert fald fået sporet dig ind på, hvor fejlen opstår. Så hvis jeg var dig, ville jeg oprette et nyt spørgsmål omkring den fejl du får, når du prøver at hive timestamp'et ud.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester