Count in der WMI

  • Hi,
    Ich wollte mir die Benutzerangaben in einem 2D Array ausgeben lassen.
    An sich funktioniert das Script schon.
    Nur möchte ich es optimieren ^^.

    Im Moment mache ich zwei WMI aufrufe.
    Einmal um die Anzahl der Benutzer und somit die Größe des Arrays festzustellen
    Dann noch einmal um die Werte ins Array zu schreiben.
    Ich wollte mir den einen Aufruf für die Größe des Arrays sparen. Nur leite funktioniert ein Select count anscheinend nicht und .Count ist auch nicht drin. :(
    Nun wollte ich mal nachfragen, ob jemand da nen Rat für mich hat ;).

    Script
    [autoit]

    Dim Const $wbemFlagReturnImmediately = 0x10
    Dim Const $wbemFlagForwardOnly = 0x20
    #Include <Array.au3>
    $return = _WinWMI_UserAccount_Name()
    _ArrayDisplay($return)

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

    Func _WinWMI_UserAccount_Name($Computer = "127.0.0.1")
    $WMIConnect = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $Computer & "\root\CIMV2")
    If @error Then SetError(1, 0, -1)
    $ObjList = $WMIConnect.ExecQuery("SELECT * from Win32_UserAccount", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($ObjList) = 0 Then SetError(1, 0, -2)
    $i = 0
    For $ObjItem In $ObjList
    $i += 1
    Local $aReturn[$i][16]
    Next
    $ObjList = $WMIConnect.ExecQuery("SELECT * from Win32_UserAccount", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($ObjList) = 0 Then SetError(1, 0, -3)
    $i = 0
    For $ObjItem In $ObjList
    With $ObjItem
    $aReturn[$i][0] = .AccountType
    $aReturn[$i][1] = .Caption
    $aReturn[$i][2] = .Description
    $aReturn[$i][3] = .Disabled
    $aReturn[$i][4] = .Domain
    $aReturn[$i][5] = .FullName
    $aReturn[$i][6] = .InstallDate
    $aReturn[$i][7] = .LocalAccount
    $aReturn[$i][8] = .Lockout
    $aReturn[$i][9] = .Name
    $aReturn[$i][10] = .PasswordChangeable
    $aReturn[$i][11] = .PasswordExpires
    $aReturn[$i][12] = .PasswordRequired
    $aReturn[$i][13] = .SID
    $aReturn[$i][14] = .SIDType
    $aReturn[$i][15] = .Status
    EndWith
    $i += 1
    Next
    Return $aReturn
    EndFunc

    [/autoit]

    Danke

    Daniel

    21 is only half the truth.

    Einmal editiert, zuletzt von Mahagon (15. Mai 2010 um 00:38)

  • .Count ist auch nicht drin.

    .Count funktioniert schon.
    Da darfst du aber nicht das Flag $wbemFlagForwardOnly setzen da damit der Enumerator nur in eine Richtung funktioniert was zwar schneller ist aber eben halt die Collection nur einmal durchlaufbar macht:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>

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

    $a = _WinWMI_UserAccount_Name()
    If @error Then
    MsgBox(0, "Fehler", "Fehlercode: " & @error)
    Else
    _ArrayDisplay($a)
    EndIf

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

    Func _WinWMI_UserAccount_Name(Const $sComputer = "127.0.0.1")
    Local $iC = 0
    Local $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\CIMV2")
    If @error Then Return SetError(1, 0, -1)
    Local $oList = $oWMI.ExecQuery("SELECT * from Win32_UserAccount", "WQL", 0)
    If Not IsObj($oList) Then Return SetError(2, 0, -1)

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

    Local $aR[$oList.Count][16]

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

    For $i In $oList
    $aR[$iC][0] = $i.AccountType
    $aR[$iC][1] = $i.Caption
    $aR[$iC][2] = $i.Description
    $aR[$iC][3] = $i.Disabled
    $aR[$iC][4] = $i.Domain
    $aR[$iC][5] = $i.FullName
    $aR[$iC][6] = $i.InstallDate
    $aR[$iC][7] = $i.LocalAccount
    $aR[$iC][8] = $i.Lockout
    $aR[$iC][9] = $i.Name
    $aR[$iC][10] = $i.PasswordChangeable
    $aR[$iC][11] = $i.PasswordExpires
    $aR[$iC][12] = $i.PasswordRequired
    $aR[$iC][13] = $i.SID
    $aR[$iC][14] = $i.SIDType
    $aR[$iC][15] = $i.Status
    $iC += 1
    Next
    Return $aR
    EndFunc

    [/autoit]


    Ansonsten ist halt die Frage ob du wirklich unbedingt ein 2D-Array benötigst oder ob du gleich mit der WMI-Collection weiterarbeiten kannst was durchaus durch die .Item-Schreibweise übersichtlicher sein könnte.
    Mal als Beispiel:

    Spoiler anzeigen
    [autoit]

    $return = _WinWMI_UserAccount_Name()
    For $i In $return
    MsgBox(0, "", $i.Name & ': ' & $i.Status)
    Next

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

    Func _WinWMI_UserAccount_Name(Const $sComputer = "127.0.0.1")
    Static $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputer & "\root\CIMV2")
    If @error Then SetError(1, 0, -1)
    Return $oWMI.ExecQuery("SELECT * from Win32_UserAccount", "WQL", 0)
    EndFunc

    [/autoit]
  • Okay da hätte man drauf kommen können das der Count einmal die Liste durchläuft.... ^^
    Danke hat mir wirklich sehr geholfen :)

    21 is only half the truth.

  • Okay da hätte man drauf kommen können das der Count einmal die Liste durchläuft

    Gerade das ist es eigentlich was ich persönlich nicht ganz verstehe.
    Sollte ich so eine Collection programmieren so wäre bei mir Count eine Variable die beim Zufügen und Entfernen von Elementen in und dekrementiert wird.
    Hier scheint es aber wirklich eine Methode zu sein die die ganze Collection durchläuft.
    Verstehe aber nicht warum da ich das ganze für ziemlich ineffektiv halte.
    Naja die werden sich schon was dabei gedacht haben.
    Aber auch sonst ist WMI nicht gerade ein Performance-Wunder...