AD LastloginTimeStamp VB Script nach Autoit

  • Hallo Zusammen,

    für eines meiner Scripte benötige ich den AD LastLoginTimeStamp!
    Dieser ist ja in der AD.au3 dabei, aber sehr langsam!

    nun habe ich mir gedacht, ich frage diesen schon beim einlesen über "lastlogontimestamp" ab!

    Spoiler anzeigen
    [autoit]


    $aObjects = _AD_GetObjectsInOU("OU=User,OU="&$aOUs[$x]&",DC=xxx,DC=int", "(&(objectcategory=person)(objectclass=user)(lastlogontimestamp<=129171852000000000))", 2, "sAMAccountName,mail,company")

    [/autoit]

    wenn ich nun hier alle user haben möchte, die sich zum beispiel vor 60 tagen das letzte mal eingeloogt haben, muss ich mir die zahl bei lastlogontimestamp<=129171852000000000 generieren!
    hierzu habe ich auf der inet seite http://www.selfadsi.de/deep-inside/mi…-attributes.htm eine Funktion gefunden, die zeigt, wie man ein Datum in einen Integer8 umwandelt.
    diese möchte ich gern in autoit wandeln!

    [autoit]


    'zeigt den Integer8 Wert des aktuellen Datums+Uhrzeit...

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

    WScript.Echo DateToLargeIntegerString(Now)

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

    Function DateToLargeIntegerString(value)
    'nimmt ein Datun+Uhrzeit und gibt den entsprechenden Microsoft LargeInteger Wert (Integer8) zurück

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

    'erst die lokale Zeitabweichung aus der Registry auslesen
    Set sho = CreateObject("Wscript.Shell")
    timeShiftValue = sho.RegRead("HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias")
    If IsArray(timeShiftValue) Then
    timeShift = 0
    For i = 0 To UBound(timeShiftValue)
    timeShift = timeShift + (timeShiftValue(i) * 256^i)
    Next
    Else
    timeShift = timeShiftValue
    End If

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

    'die Zeit von lokaler Zeit in UTC umrechnen
    value = DateAdd("n", timeShift, value)

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

    'wieviele Sekunden seit 1601 sind vergangen?
    secs = DateDiff("s", #1/1/1601#, value)

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

    'in Nano-Sekunden umrechnen
    DateToLargeIntegerString = CStr(secs) & "0000000"
    End Function

    [/autoit]


    im englischen forum hab ich nur von lastlogintimestam in lesbares datumsfpormat gefunden!
    http://www.autoitscript.com/forum/topic/86…ript-to-autoit/

    kann man diese funktion einfach umsetzen oder gibt es eventuell dafür schon eine lösung?

    mein bisheriger versuch :(

    [autoit]


    #Include <Date.au3>

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

    ;last logon timestamp

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

    $ll_datum = "01.01.2012 00:00:00"

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

    _DateToLargeIntegerString($ll_datum)

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

    Func _DateToLargeIntegerString($value)
    ;nimmt ein Datun+Uhrzeit und gibt den entsprechenden Microsoft LargeInteger Wert (Integer8) zurück

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

    ;erst die lokale Zeitabweichung aus der Registry auslesen
    ;Set sho = CreateObject("Wscript.Shell")
    $timeShiftValue = RegRead("HKLM\System\CurrentControlSet\Control\TimeZoneInformation\","ActiveTimeBias")
    MsgBox(0,"",$timeShiftValue)

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

    If IsArray($timeShiftValue) Then
    $timeShift = 0
    For $i = 0 To UBound($timeShiftValue)
    $timeShift = $timeShift + ($timeShiftValue($i) * 256^$i)
    Next
    Else
    $timeShift = $timeShiftValue
    EndIf

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

    ;die Zeit von lokaler Zeit in UTC umrechnen
    $value = _DateAdd("n", $timeShift, $value)
    ;_DateAdd($sType, $iValToAdd, $sDate)

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

    ;wieviele Sekunden seit 1601 sind vergangen?
    $secs = _DateDiff("s", "#1/1/1601#", $value)
    ;_DateDiff($sType, $sStartDate, $sEndDate)

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

    MsgBox(0,"",$secs)
    ;in Nano-Sekunden umrechnen
    $DateToLargeIntegerString = CStr($secs) & "0000000"

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

    EndFunc

    [/autoit]

    gruß gmmg

    4 Mal editiert, zuletzt von gmmg (6. März 2012 um 09:21)

  • Welche Version des AD UDFs verwendest Du und wieviele Domänen Controller hast Du?

  • hallo water :)

    es gibt an jedem standort einen dc! wobei das script jeweils immer nur von einem standord ausgeführt werden soll!

    hier mal der abschnitt mit dem ich das ganze ausführe!

    praktisch vergleiche ich die lastlogintime mit _nowcalc! wenn die tage im beispiel > 60 zeige mir die an oder schreibe die in eine array oder sonstwas!

    [autoit]


    ;---------------LastLoginDate -----------------------------
    For $i = 1 To $aObjects[0][0]
    Local $result
    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"sitename")
    ;Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],$aOUs[$x])
    $result = StringLeft($iLLDate, 8)
    $yyyy = StringTrimRight($result,4)
    $mm = StringTrimLeft($result,4)
    $mm = StringTrimRight($mm,2)
    $dd = StringTrimLeft($result,6)
    $YYYY_MM_DD = $yyyy & "/" & $mm & "/" & $dd & " 00:00:00"
    ;MsgBox(0, "Leftmost 3 characters are:", $result & " " & $YYYY_MM_DD)
    $DateDiff = _DateDiff('D', $YYYY_MM_DD, _NowCalc()) ;"YYYY/MM/DD[ HH:MM:SS]"
    If $DateDiff > 60 Then
    ;MsgBox(0, "Älter 60 Tage:",$aOUs[$x] & " " & $aObjects[$i][0] & " " & $DateDiff & " " & $result)
    _ArrayAdd($alogin, $aObjects[$i][0] & ";" & $DateDiff)

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

    EndIf
    Next
    _ArrayDisplay($alogin)
    ;-------------------------------------------------------

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

    :)

    gruß gmmg

  • Bei mir dauert _AD_GetlastLoginDate unter 1 Sekunde.
    Hatten wir nicht das PerformanceProblem bereits gestern in einem anderen Thread behoben?

  • water

    das war die änderung mit _AD_ListDomainControllers in der AD.au3
    Beitrag:
    Active Directory Funktionen - Neues Beispielskript

    ich häng mal das ganze script an, die daten werden in ein excel sheet geschrieben!
    vielleicht ist da nen geschwindigkeitsproblem!

    Spoiler anzeigen
    [autoit]


    #include <Excel.au3>
    #Include <File.au3>
    #include <AD.au3>
    #include <Array.au3>
    #include <GUIConstantsEx.au3>
    #Include <Date.au3>

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

    ;ldap attribute -> http://www.selfadsi.de/user-attributes-w2k3.htm
    ; excel book erstellen
    ; user nach sites eintragen
    ; user nach company eintragen
    ; user gesamt nach sites eintragen

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

    DIM $oMyRet, $oMyError, $oExcel, $saveas, $sOU
    Local $avArray[1] ,$avArray_01[1], $alogin[1], $aObjects , $aObjects_01, $avArray_10[1], $sValue
    _AD_Open()

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

    ;auslesen der einzelnen OU's
    $aOUs = _AD_GetObjectsInOU($sOU, "(objectCategory=organizationalUnit)", 1, "name") ;"distinguishedName")
    If @error > 0 Then
    MsgBox(64, "Active Directory Functions - Example 2", "No OUs could be found")
    Else
    ;_ArrayDisplay($aOUs, "Active Directory Functions - Example 2 - All OUs starting with: '" & $sOU & "'")
    EndIf
    ;---------------------------------
    ;_ArrayDelete($aOUs, 0) ;löscht 1 eintrag aus dem array
    _ArraySort($aOUs)
    ;_ArrayDisplay($aOUs, "AD all Site OUs!")

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

    ;erstelle excel dokument
    Local $oExcel = _ExcelBookNew() ;Create new book, make it visible
    _ExcelSheetDelete($oExcel, "Sheet1") ;Delete Sheet by string name of SheetName
    _ExcelSheetDelete($oExcel, "Sheet2") ;Delete Sheet by string name of SheetName
    _ExcelSheetDelete($oExcel, "Sheet3") ;Delete Sheet by string name of SheetName
    _ExcelSheetDelete($oExcel, "Tabelle1") ;Delete Sheet by string name of SheetName
    _ExcelSheetDelete($oExcel, "Tabelle2") ;Delete Sheet by string name of SheetName
    ;-----------------------
    Sleep(1000)

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

    For $x = 1 to $aOUs[0]
    ;(lastlogontimestamp<=129171852000000000)
    ;$aObjects = _AD_GetObjectsInOU("OU=User,OU="&$aOUs[$x]&",DC=xxx,DC=int", "(&(objectcategory=person)(objectclass=user)(mail=*)(userAccountControl=512))", 2, "sAMAccountName,mail,company")
    ;$aObjects = _AD_GetObjectsInOU("OU=User,OU="&$aOUs[$x]&",DC=xxx,DC=int", "(&(objectcategory=person)(objectclass=user)(mail=*)(|(userAccountControl=512)(msExchHideFromAddressLists="")(msExchHideFromAddressLists=TRUE)(userAccountControl=66048)))", 2, "sAMAccountName,department,company")
    $aObjects = _AD_GetObjectsInOU("OU=User,OU=Site,DC=xxx,DC=int", "(&(objectcategory=person)(objectclass=user)(mail=*)(|(userAccountControl=512)(msExchHideFromAddressLists="")(msExchHideFromAddressLists=False)(userAccountControl=66048)))", 2, "sAMAccountName,department,company")
    $aObjects_01 = $aObjects
    _ArrayDisplay($aObjects_01)

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

    ;---------------LastLoginDate -----------------------------
    For $i = 1 To $aObjects[0][0]
    Local $result
    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"erf01")
    ;Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],$aOUs[$x])
    $result = StringLeft($iLLDate, 8)
    $yyyy = StringTrimRight($result,4)
    $mm = StringTrimLeft($result,4)
    $mm = StringTrimRight($mm,2)
    $dd = StringTrimLeft($result,6)
    $YYYY_MM_DD = $yyyy & "/" & $mm & "/" & $dd & " 00:00:00"
    ;MsgBox(0, "Leftmost 3 characters are:", $result & " " & $YYYY_MM_DD)
    $DateDiff = _DateDiff('D', $YYYY_MM_DD, _NowCalc()) ;"YYYY/MM/DD[ HH:MM:SS]"
    If $DateDiff > 60 Then
    ;MsgBox(0, "Älter 60 Tage:",$aOUs[$x] & " " & $aObjects[$i][0] & " " & $DateDiff & " " & $result)
    _ArrayAdd($alogin, $aObjects[$i][0] & ";" & $DateDiff)

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

    EndIf
    Next
    _ArrayDisplay($alogin)
    ;-------------------------------------------------------

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

    If @error > 0 Then
    ;MsgBox(64, "", "Nichts gefunden Error: " & @error)
    Else
    ;$bench = TimerInit() ; laufzeittest
    ;--user pro company in site zählen-----
    $Array_05 = _GetUsers_Summary($aObjects_01) ;dieses Array enthält die Ergebnisse
    $Array_06 = _GetUsers_Summary1($aObjects_01) ;dieses Array enthält die Ergebnisse
    ;If Not @error Then _ArrayDisplay($Array_05)
    ;If Not @error Then _ArrayDisplay($avArray_10)
    ;ConsoleWrite(Round(TimerDiff($bench) / 1000, 4) & " s" & @CRLF) ; laufzeittest ausgabe
    ;--------------------------------------
    _ExcelSheetAddNew($oExcel, $aOUs[$x])
    _ExcelWriteCell($oExcel, "User", 1, 1) ;Write to the Cell
    _ExcelWriteCell($oExcel, "Department", 1, 2) ;Write to the Cell
    _ExcelWriteCell($oExcel, "Company", 1, 3) ;Write to the Cell
    $oExcel.Columns("A:A").ColumnWidth = "30" ;setze spaltenbreite
    $oExcel.Columns("B:B").ColumnWidth = "50" ;setze spaltenbreite
    $oExcel.Columns("C:C").ColumnWidth = "50" ;setze spaltenbreite
    $oExcel.Range("A1:C1") .Font.Bold = TRUE ; setze schriftgrad
    $oExcel.Range("A1:C1") .Font.Size = 14 ; setze schriftgröße
    ;$oExcel.Range("A1:D1") .Font.Color = 0xffffff
    $oExcel.Range("A1:C1") .Interior.ColorIndex = 43 ; setze Farbe
    ;$oExcel.Name = $aOUs[$x]

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

    For $i = 1 To $aObjects[0][0]
    ;MsgBox(0,"", $aObjects[$i][0])
    #CS
    ;---------------LastLoginDate -----------------------------
    Local $result
    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"erf01")
    ;Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],$aOUs[$x])
    $result = StringLeft($iLLDate, 8)
    $yyyy = StringTrimRight($result,4)
    $mm = StringTrimLeft($result,4)
    $mm = StringTrimRight($mm,2)
    $dd = StringTrimLeft($result,6)
    $YYYY_MM_DD = $yyyy & "/" & $mm & "/" & $dd & " 00:00:00"
    ;MsgBox(0, "Leftmost 3 characters are:", $result & " " & $YYYY_MM_DD)
    $DateDiff = _DateDiff('D', $YYYY_MM_DD, _NowCalc()) ;"YYYY/MM/DD[ HH:MM:SS]"
    If $DateDiff > 60 Then MsgBox(0, "Älter 60 Tage:",$aOUs[$x] & " " & $aObjects[$i][0] & " " & $DateDiff & " " & $result)
    ;-------------------------------------------------------
    #CE
    $zeile = $i + 1
    IF $aObjects[0][0] <> "" Then
    _ExcelWriteCell($oExcel, $aObjects[$i][0], $zeile, 1)
    _ExcelWriteCell($oExcel, $aObjects[$i][1], $zeile, 2)
    _ExcelWriteCell($oExcel, $aObjects[$i][2], $zeile, 3)
    $oExcel.Range("A"& $zeile &":C"& $zeile) .Interior.ColorIndex = 27 ; setze Farbe
    $oExcel.Range("A1:C"&$zeile).Borders.LineStyle = 1 ; setze einen Rahmen um die Zellen
    EndIf
    Next
    _ArrayAdd($avArray, $aOUs[$x] & ";" & $aObjects[0][0])
    _ExcelWriteCell($oExcel, $aObjects[0][0], $zeile + 2, 2)
    _ExcelWriteCell($oExcel, "All USER " & $aOUs[$x] & ":", $zeile + 2, 1)

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

    $oExcel.Range("A"& $zeile +2 &":B"& $zeile+2) .Interior.ColorIndex = 27 ; setze Farbe
    $oExcel.Range("A1:B"&$zeile +2).Borders.LineStyle = 1 ; setze einen Rahmen um die Zellen
    $oExcel.Range("A"& $zeile +2 &":B"& $zeile+2) .Font.Bold = TRUE ; setze schriftgrad

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

    ;-------schreibe user pro company in excelsheet -------
    For $i = 0 To UBound($Array_05) - 1
    ;MsgBox(0,"", $Array_05[$i][0] & " " &$Array_05[$i][1])
    IF $Array_05[$i][0] = "" Then
    ;MsgBox(0,"",$Array_05[$i][1])
    _ExcelWriteCell($oExcel,"No Department", $zeile + 4 + $i, 1)
    Else
    _ExcelWriteCell($oExcel, $Array_05[$i][0], $zeile + 4 + $i, 1)
    EndIf
    _ExcelWriteCell($oExcel, $Array_05[$i][1], $zeile + 4 + $i, 2)
    $oExcel.Range("A"& $zeile + 4 + $i &":B"& $zeile + 4 + $i) .Interior.ColorIndex = 27 ; setze Farbe
    $oExcel.Range("A1:B"&$zeile + 4 + $i).Borders.LineStyle = 1 ; setze einen Rahmen um die Zellen
    $oExcel.Range("A"& $zeile + 4 +$i &":B"& $zeile + 4 +$i) .Font.Bold = TRUE ; setze schriftgrad
    IF $aObjects[0][0] <> "" Then _ArrayAdd($avArray_01, $aOUs[$x] & ";" & $Array_05[$i][0] & ";" & $Array_05[$i][1]) ; füge daten in array für YGesamt
    Next
    EndIf
    If $aObjects <> "" Then _ArrayAdd($avArray_01, ";;")
    ;-------------------------------------------------------
    Next

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

    ;_ArrayDisplay($avArray_01)

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

    _AD_Close()

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

    _ExcelSheetDelete($oExcel, "Tabelle3") ;Delete Sheet by string name of SheetName
    _ExcelSheetAddNew($oExcel, "YGesamt")
    _ExcelSheetAddNew($oExcel, "ZGesamt")
    _ExcelSheetOrderByName($oExcel, 0)

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

    ;_ArrayDisplay($avArray)

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

    #Region ZGesamt
    ;---------ZGesamt-------------------------
    _ExcelWriteCell($oExcel, "Site", 1, 1) ;Write to the Cell
    _ExcelWriteCell($oExcel, "Anzahl User", 1, 2) ;Write to the Cell
    _ExcelSheetActivate($oExcel, "ZGesamt")
    $oExcel.Columns("A:A").ColumnWidth = "30" ;setze spaltenbreite
    $oExcel.Columns("B:B").ColumnWidth = "50" ;setze spaltenbreite
    $oExcel.Range("A1:B1") .Font.Bold = TRUE ; setze schriftgrad
    $oExcel.Range("A1:B1") .Font.Size = 14 ; setze schriftgröße
    ;$oExcel.Range("A1:D1") .Font.Color = 0xffffff
    $oExcel.Range("A1:B1") .Interior.ColorIndex = 43 ; setze Farbe
    ;$oExcel.Name = $aOUs[$x]

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

    For $i = 1 To _ArrayMaxIndex($avArray, 0, 1)
    ;MsgBox(0,"", $avArray[$i])
    $zeile_1 = $i + 1
    $eintrag = StringSplit($avArray[$i], ";")
    _ExcelWriteCell($oExcel, $eintrag[1], $zeile_1, 1)
    _ExcelWriteCell($oExcel, $eintrag[2], $zeile_1, 2)
    $oExcel.Range("A"& $zeile_1 &":B"& $zeile_1) .Interior.ColorIndex = 27 ; setze Farbe
    $oExcel.Range("A1:B"&$zeile_1).Borders.LineStyle = 1 ; setze einen Rahmen um die Zellen
    Next

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

    _ExcelWriteCell($oExcel, "=Summe(B2:B"& $zeile_1 ,$zeile_1 + 1 , 2) ;Write formula another way Uses A1 referencing, not R1C1
    _ExcelWriteCell($oExcel, "All User",$zeile_1 + 1 , 1) ;Write formula another way Uses A1 referencing, not R1C1
    ; formatiert letzte Zeile
    $oExcel.Range("A"& $zeile_1 +1 &":B"& $zeile_1 + 1) .Interior.ColorIndex = 27 ; setze Farbe
    $oExcel.Range("A"& $zeile_1 +1 &":B"& $zeile_1 + 1).Borders.LineStyle = 1 ; setze einen Rahmen um die Zellen
    $oExcel.Range("A"& $zeile_1 +1 &":B"& $zeile_1 + 1) .Font.Bold = TRUE ; setze schriftgrad

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

    ;---------Ende ZGesamt---------------------
    #EndRegion ZGesamt
    #Region YGesamt
    ;---------YGesamt--------------------------
    _ExcelSheetActivate($oExcel, "YGesamt")
    _ExcelWriteCell($oExcel, "Site", 1, 1) ;Write to the Cell
    _ExcelWriteCell($oExcel, "Department", 1, 2) ;Write to the Cell
    ;_ExcelWriteCell($oExcel, "User", 1, 3) ;Write to the Cell
    _ExcelSheetActivate($oExcel, "YGesamt")
    $oExcel.Columns("A:A").ColumnWidth = "25" ;setze spaltenbreite
    $oExcel.Columns("B:B").ColumnWidth = "30" ;setze spaltenbreite
    ;$oExcel.Columns("C:C").ColumnWidth = "20" ;setze spaltenbreite
    $oExcel.Range("A1:B1") .Font.Bold = TRUE ; setze schriftgrad
    $oExcel.Range("A1:B1") .Font.Size = 14 ; setze schriftgröße
    ;$oExcel.Range("A1:D1") .Font.Color = 0xffffff
    $oExcel.Range("A1:B1") .Interior.ColorIndex = 43 ; setze Farbe
    ;$oExcel.Name = $aOUs[$x]

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

    For $i = 1 To _ArrayMaxIndex($avArray_10, 0, 1)
    ;IF $aObjects[0][0] <> "" Then
    $zeile_1 = $i + 1
    $eintrag = StringSplit($avArray_10[$i], ";")
    _ExcelWriteCell($oExcel, $eintrag[1], $zeile_1, 1)
    _ExcelWriteCell($oExcel, $eintrag[2], $zeile_1, 2)
    ;_ExcelWriteCell($oExcel, $eintrag[3], $zeile_1, 3)
    If $eintrag[1] = "" Then
    $oExcel.Range("A"& $zeile_1 &":B"& $zeile_1).Interior.ColorIndex = 43 ; setze Farbe
    _ExcelWriteCell($oExcel, $eintrag[2], $zeile_1, 3)
    Else
    $oExcel.Range("A"& $zeile_1 &":B"& $zeile_1).Interior.ColorIndex = 27 ; setze Farbe
    EndIf
    $oExcel.Range("A1:B"&$zeile_1).Borders.LineStyle = 1 ; setze einen Rahmen um die Zellen

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

    Next
    ;---------Ende YGesamt---------------------
    #EndRegion ZGesamt

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

    ;$saveas = "C:\User_in Sites"
    ;_ExcelBookSaveAs($oExcel, $saveas, "xls")
    ;_ExcelBookClose($oExcel, 1, 0)

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

    ;===============================================================================
    ; Function Name: _ExcelSheetOrderByName($oExcel, $iDesc=0)
    ; Description:: Order ExcelBook-Sheets by name ascending (default) or descending
    ; Parameter(s): $oExcel - Excel object opened by a preceding call to _ExcelBookOpen() or _ExcelBookNew()
    ; $iDesc - order descending on=1/off=0 (default)
    ; Requirement(s): #Include <Array.au3>
    ; Return Value(s): On Success - Returns 1
    ; On Failure - Returns 0 and sets @error=1 - Specified object does not exist
    ; Author(s): BugFix ([email='bugfix@autoit.de'][/email])
    ;===============================================================================
    Func _ExcelSheetOrderByName($oExcel, $iDesc=0)
    If Not IsObj($oExcel) Then Return SetError(1, 0, 0)
    If $iDesc <> 1 Then $iDesc = 0
    Local $aList = _ExcelSheetList($oExcel)
    _ArraySort($aList, $iDesc)
    Local $pos = 1
    For $i = 0 To UBound($aList) -1
    If $i = 0 Then
    _ExcelSheetMove($oExcel, $aList[$i], $pos, True)
    Else
    _ExcelSheetMove($oExcel, $aList[$i], $pos, False)
    $pos += 1
    EndIf
    Next
    Return 1
    EndFunc

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

    Func _GetUsers_Summary(ByRef $aObjects_01)
    If Not IsArray($aObjects_01) Then SetError(1, 0, 0)
    _ArrayDelete($aObjects_01, 0)
    If Not IsArray($aObjects_01) Then SetError(2, 0, 0)
    Local $aCompanies = _ArrayUnique($aObjects_01, 2) ; prüfe feld xy
    _ArrayDelete($aCompanies, 0)
    _ArraySort($aCompanies)

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

    Local $aResult[UBound($aCompanies)][2]
    For $i = 0 To UBound($aCompanies) - 1
    $aResult[$i][0] = $aCompanies[$i]
    Next

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

    For $i = 0 To UBound($aResult) - 1
    ;$aTemp = _ArrayFindAll($aObjects_01, $aResult[$i][0], 0, 0, 0, 0, 2)
    $aTemp = _ArrayFindAll($aObjects_01, $aResult[$i][0], 0, 0, 0, 0, 1)
    $aResult[$i][1] = UBound($aTemp)
    Next
    Return $aResult
    EndFunc ;==>_GetUsers_Summary

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

    Func _GetUsers_Summary1(ByRef $aObjects_01)
    If Not IsArray($aObjects_01) Then SetError(1, 0, 0)
    _ArrayDelete($aObjects_01, 0)
    If Not IsArray($aObjects_01) Then SetError(2, 0, 0)
    Local $aCompanies = _ArrayUnique($aObjects_01, 2) ; prüfe feld xy
    _ArrayDelete($aCompanies, 0)
    _ArraySort($aCompanies)

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

    For $i = 0 To UBound($aCompanies) - 1
    _ArrayAdd($avArray_10,$aOUs[$x] & ";" & $aCompanies[$i])
    Next
    If $aObjects_01 <> "" Then _ArrayAdd($avArray_10, ";;")
    EndFunc ;==>_GetUsers_Summary

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

    vielleicht lässt sich hier einiges optimieren!

    gruß gmmg

  • Hab's mir nicht im Detail angesehen, aber das sieht ziemlich umfangreich aus.

    • Wie lang läuft denn das ganze Skript?
    • Wie viele Benutzer werden verarbeitet ?
    • Wieviele Domänen Controller gibt es in der Domäne?
  • hallo water,

    1. das ganze script ohne die Lastlogin funktion läuft 36 sekunden
    2. 2400 user werden in 34 sites abgefragt
    3. 19 domänencontroller, dabei hat aber nicht jede site einen dc, weil es standorte mit nur 2-3 user gibt!

    gruß gmmg

  • Mit dieser Konfiguration kann das natürlich seine Zeit dauern. 2400 mal wird die Liste aller DCs erstellt, dann wird pro User jeder der 19 DCs nach dem lastlogin date angefragt und danach das letzte Anmeldedatum errechnet.
    Man könnte die Funktion so anpassen, dass die Liste der DCs als Parameter übergeben wird und somit nur einmal berechnet werden muss.

  • Du kannst ja mal diese modifizierte Version testen. Erstelle in Deinem Script vor der Schleife wo Du die 2400 user checkst die Liste der DCs. Dann übergib diesen Array als Parameter 3 an die neue Funktion:

    Spoiler anzeigen
    [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _AD_GetLastLoginDate
    ; Description ...: Returns the lastlogin information from all DCs using the SamAccountName.
    ; Syntax.........: _AD_GetLastLoginDate([$sAD_User = @Username[, $sAD_Site = ""[, $aAD_DCList = ""]]])
    ; Parameters ....: $sAD_User - Optional: SamAccountName of a user account to get the last login date (default = @Username).
    ; $sAD_Site - Optional: Only query DCs that belong to this site(s) (default = all sites).
    ; +This can be a single site or a list of sites separated by commas
    ; $aAD_DCList - Optional: one-based two dimensional array of Domain Controllers as returned by function _AD_ListDomainControllers (default = "")
    ; Return values .: Success - Last login date returned as YYYYMMDDHHMMSS. @extended is set to the total number of Domain Controllers.
    ; +@error could be > 0 and contains the number of DCs that could not be reached or returns no data
    ; Failure - 0, sets @error to:
    ; |1 - $sAD_User could not be found. @extended = 0
    ; |2 - $sAD_User has never logged in to the domain. @extended = 0
    ; |3 - $aAD_DCList has to be an array or blank
    ; |4 - $aAD_DCList has to be a 2-dimensional array
    ; Warning - Last login date returned as YYYYMMDDHHMMSS (see Success), sets @error and @extended to:
    ; |x - Number of DCs which could not be reached. Result is returned from all available DCs. @extended is set to the total number of Domain Controllers
    ; Author ........: Jonathan Clelland
    ; Modified.......: water, Stephane
    ; Remarks .......: If it takes (too) long to get a result either some DCs are down or you have too many DCs in your AD.
    ; +Case one: Please check @error and @extended as described above
    ; +Case two: Specify parameter $sAD_Site to reduce the number of DCs to query and/or retrieve the list of DCs yourself and pass the array as parameter 3
    ; Related .......:
    ; Link ..........: http://blogs.technet.com/b/askds/archiv…w-it-works.aspx
    ; Example .......: Yes
    ; ===============================================================================================================================
    Func _AD_GetLastLoginDate($sAD_User = @UserName, $sAD_Site = "", $aAD_DCList = "")

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

    If _AD_ObjectExists($sAD_User) = 0 Then Return SetError(1, 0, 0)
    If Not IsArray($aAD_DCList) And $aAD_DCList <> "" Then Return SetError(3, 0, 0)
    If IsArray($aAD_DCList) And UBound($aAD_DCList, 0) <> 2 Then Return SetError(4, 0, 0)
    If $aAD_DCList = "" Then $aAD_DCList = _AD_ListDomainControllers()
    Local $aAD_Site, $sAD_SingleDC, $bAD_WasIn
    ; Delete all DCs not belonging to the specified site
    $aAD_Site = StringSplit($sAD_Site, ",", 2)
    If UBound($aAD_Site) > 0 And $aAD_Site[0] <> "" Then
    For $iAD_Count1 = $aAD_DCList[0][0] To 1 Step -1
    $bAD_WasIn = False
    For $sAD_SingleDC In $aAD_Site
    If $aAD_DCList[$iAD_Count1][3] = $sAD_SingleDC Then $bAD_WasIn = True
    Next
    If Not $bAD_WasIn Then _ArrayDelete($aAD_DCList, $iAD_Count1)
    Next
    $aAD_DCList[0][0] = UBound($aAD_DCList, 1) - 1
    EndIf
    ; Get LastLogin from all DCs
    Local $aAD_Result[$aAD_DCList[0][0] + 1]
    Local $sAD_LDAPEntry, $oAD_Object, $oAD_RecordSet
    Local $iAD_Error1 = 0, $iAD_Error2 = 0
    For $iCount1 = 1 To $aAD_DCList[0][0]
    If Ping($aAD_DCList[$iCount1][2]) = 0 Then
    $iAD_Error1 += 1
    ContinueLoop
    EndIf
    $oAD_Command.CommandText = "<LDAP://" & $aAD_DCList[$iCount1][2] & "/" & $sAD_DNSDomain & ">;(sAMAccountName=" & $sAD_User & ");ADsPath;subtree"
    $oAD_RecordSet = $oAD_Command.Execute ; Retrieve the ADsPath for the object
    ; -2147352567 or 0x80020009 is returned when the service is not operational
    If @error = -2147352567 Or $oAD_RecordSet.RecordCount = 0 Then
    $iAD_Error1 += 1
    Else
    $sAD_LDAPEntry = $oAD_RecordSet.fields(0).value
    $oAD_Object = _AD_ObjGet($sAD_LDAPEntry) ; Retrieve the COM Object for the object
    $aAD_Result[$iCount1] = $oAD_Object.LastLogin
    ; -2147352567 or 0x80020009 is returned when the attribute "LastLogin" isn't defined on this DC
    If @error = -2147352567 Then $iAD_Error2 += 1
    $oAD_Object.PurgePropertyList
    EndIf
    Next
    _ArraySort($aAD_Result, 1, 1)
    ; If error count equals the number of DCs then the user has never logged in
    If $iAD_Error2 = $aAD_DCList[0][0] Then Return SetError(2, 0, 0)
    Return SetError($iAD_Error1, $aAD_DCList[0][0], $aAD_Result[1])

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

    EndFunc ;==>_AD_GetLastLoginDate

    [/autoit]
  • water

    habe das jetzt mal ausgelesen und statisch den dc wie folgt übergeben!

    [autoit]


    ;------list dc's----
    Local $aDC = _AD_ListDomainControllers()
    ;_ArrayDisplay($aDC, "Active Directory Functions - Example 1 - All Domain Controllers, distinguished name, DNS host name, and the site name")
    ;-------------------
    ;scriptabschnitt _AD_GetLastLoginDate
    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"sitename",$aDC[14][0])

    [/autoit]

    hier macht er aber keine abfrage mehr bzw. das array "_ArrayDisplay($alogin)" ist leer ! und es kommt auch kein fehler!
    ohne den 3 parameter wird das array gefüllt!

    gruß gmmg

  • Du must die gesamte Tabelle übergeben:

    [autoit]


    ;------list dc's----
    Local $aDC = _AD_ListDomainControllers()
    ;_ArrayDisplay($aDC,
    "Active Directory Functions - Example 1 - All Domain Controllers,
    distinguished name, DNS host name, and the site name")
    ;-------------------
    ;scriptabschnitt _AD_GetLastLoginDate
    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"sitename",$aDC)

    [/autoit]
  • water hab mir fast sowas gedacht! :)

    so, ich teste gleich mal ....

    ergebnis dauer ca. 50 sek!

    ich muss aber unseren sitename übergeben

    [autoit]

    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"unser Sitename",$aDC)

    [/autoit]


    wenn ich den auch dynamisch übergebe, dann dauert das script wieder ewigkeiten!
    ich nehme an, weil es nicht in jeder site einen dc gibt!

    macht es sinn, anhand der abfrage des @logonservers, das array" $aDC" zu bereinigen und nur den eintrag zu nehmen?

    gruß und danke
    gmmg

    Einmal editiert, zuletzt von gmmg (5. März 2012 um 11:30)

  • Die Bereinigung der DC Tabelle macht die Funktion selbst.
    Probleme gibt es, wenn ein DC nicht erreichbar ist, dann dauert das ewig, da die Funktion zuerst in einen Timeout läuft.

    Grunsätzlich stellt sich natürlich die Frage, ob es innvoll ist 2400 User auf das Datum der letzten Anmeldung zu prüfen.
    Falls ja, dann sollte es auch egal sein, wenn die Geschichte etwas länger läuft.

    Lass Dir mal nach dem Aufruf von _AD_GetLastLoginDate die Werte von @error und @extended ausgeben. Die geben an, wie viele Probleme während der Prüfung auftraten bzw. wie viele DCs für den User angefragt wurden:

    Code
    ; Warning - Last login date returned as YYYYMMDDHHMMSS (see Success), sets @error and @extended to:
    ; |x - Number of DCs which could not be reached. Result is returned from all available DCs. @extended is set to the total number of Domain Controllers
  • water,

    ich muss das Thema mit dem _AD_GetLastLoginDate nochmal aufgreifen!
    Problem hierbei, die Replikation der LastLogin zeiten, der einzelnen Standorte!

    Kann man dem Script irgendwie mitteilen, das er den "@LogonServer" benutzt, an dem der user, der das script startet, angemeldet ist?

    [autoit]


    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"unser Sitename",$aDC)
    ; übergabe des logonservers ...
    Local $iLLDate = _AD_GetLastLoginDate($aObjects[$i][0],"unser Sitename",@LogonServer)

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


    gruß gmmg

  • Wegen der Replikationsproblematik gibt es die Funktion _AD_GetLastLoginDate. Sie fragt alle DCs der Domäne nach dem lastlogin und gibt das aktuellste zurück.
    Durch diese Problematik und die Menge der DCs kann es natürlich zu erheblichen Laufzeiten kommen.
    Nur einen DC abzufragen bringt da leider nichts.

  • hallo water,

    danke erstmal für die antwort! :)

    ich muss mal sehen, wie mein kollege das jetzt haben möchte!
    vielleicht macht es sinn, das für jede einzelne ad site dynamisch umzubauen, da dies jeder siteadmin in seiner site ausführen soll!
    hierzu müsste dann ja nur der DC dieser site abgefragt werden und dieser sollte ja dann auch die aktuellsten daten für diese site haben!

    gruß gmmg

  • Bei uns ist auch von Interesse, wann sich die Leute zuletzt angemeldet haben.
    Wir haben das über das Login-Skript gelöst. Das trägt einfach in eine Datei (je Benutzer) Datum/Uhrzeit ein - fertig.