Jump to content
Sign in to follow this  
Luigi

This WMI way to get all windows's users is good?

Recommended Posts

On XP the Win32_UserAccount class gives the same results than jguinch's code in post #14

Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
Local $colItems = $objWMIService.ExecQuery("SELECT Name FROM Win32_UserAccount", "WQL", 0x10 + 0x20)
If IsObj($colItems) Then
    Local $Result = ""
    For $objItem In $colItems
        $Result &= $objItem.Name & @crlf
    Next
 EndIf
Msgbox(0,"", $Result)
Edited by mikell

Share this post


Link to post
Share on other sites

@Chimp - I get this as output (Win7 - Home)...

Nancy

NT AUTHORITYAuthenticated Users

NT AUTHORITYINTERACTIVE

 

I see, you are right,  those are only the members of the local "user" group

not exactly what op asked indeed...

op needs all the local users, not only "user" group's members.

Well, I can remedy with the "net user" command and a little output parsing adapting.

here is the "clumsy attempt"

#include <array.au3>
Local $sDOS_out, $aLocalUsers[1]

; Returns local users of this computer (remove first 4 unwanted lines)
$iPID = Run(@ComSpec & ' /c NET user | MORE /E +4', "", @SW_HIDE, 2)

Do ; wait that dos has finished
    $sDOS_out &= StdoutRead($iPID)
Until @error

; Parse DOS output
$RawUsers = StringSplit(StringStripCR($sDOS_out), @LF, 2)
_ArrayPop($RawUsers); remove last 4 unwanted lines
_ArrayPop($RawUsers)
_ArrayPop($RawUsers)
_ArrayPop($RawUsers)
For $i = 0 To UBound($RawUsers) - 1
    For $i2 = 1 To StringLen($RawUsers[$i]) Step 25
        _ArrayAdd($aLocalUsers, StringStripWS(StringMid($RawUsers[$i], $i2, 20), 2))
    Next
Next
_ArrayDelete($aLocalUsers, 0) ; remove first empty line
_ArrayDisplay($aLocalUsers) ; show local users

edit:

p.s.

from a DOS prompt, enter the following command:

control userpasswords2

then click on "advanced" and on "advanced" again

this will start the user manager gui where you can see all local users and all groups with belonging users

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

@Mikell : you should add a filter in your query, to retrieve only the local accounts (default is all users and groups accounts - included domain users and groups)

Sorry Mikell, I red Win32_Account in your post, but you wrote Win32_UserAccount

So, with Win32_Account, we can do this (works with XP) :

Local $colItems = $objWMIService.ExecQuery("select * from Win32_Account where LocalAccount = True AND SIDType = 1", "WQL", 0x10 + 0x20)

@Danyfirex : the registry method is faster than an object method. But the profile path (ProfileImagePath value) does not always match with the user name. For some reasons, the profile can be stored in a directory like c:users<username>.<computername> on something else... It's possible to use _Security__LookupAccountSid to find the username from its SID.

So, another way :

#Include <Array.au3>
#include <Security.au3>
 
$aProfiles = _GetUserProfileList()
_ArrayDisplay($aProfiles)
 
Func _GetUserProfileList()
    Local $sKey = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
    Local $iCount = 0, $sSubKey, $sProfileImagePath, $aAccountInfos
 
    Local $aReturn[1][2]
 
    While 1
        $iCount += 1
        $sSubKey = RegEnumKey($sKey, $iCount)
        If @error Then ExitLoop
 
 
        If StringRegExp($sSubKey, "(?i)S-1-5-21-(\d+-){3}\d+") Then
            $sProfileImagePath = StringReplace( _ExpandEnvStringsEx ( RegRead($sKey & "\" & $sSubKey, "ProfileImagePath") ), "::", ":")
            If FileExists($sProfileImagePath) Then
                Redim $aReturn[ UBound($aReturn) + 1][2]
                
                $aAccountInfos = _Security__LookupAccountSid($sSubKey)
                If IsArray($aAccountInfos) Then $aReturn[ UBound($aReturn) - 1][0] = $aAccountInfos[0]
                $aReturn[ UBound($aReturn) - 1][1] = $sProfileImagePath
            EndIf
        EndIf
    WEnd
    $aReturn[0][0] = UBound($aReturn) - 1
 
    Return $aReturn
EndFunc
 
 

Func _ExpandEnvStringsEx($sString)
    Local $aVars = StringRegExp($sString, "%([^%]+)%", 3)
    Local $iCount = 0
 
    If IsArray($aVars) Then
        For $i = 0 To UBound($aVars) - 1
            $sVal = EnvGet($aVars[$i])
            If $sVal <> "" Then
                $sString = StringReplace($sString, "%" & $aVars[$i] & "%", $sVal )
                $iCount += 1
            EndIf
        Next
        SetExtended( $iCount )
    Else
        SetExtended(0)
    EndIf
 
    Return $sString
EndFunc
Edited by jguinch

Share this post


Link to post
Share on other sites

Detefon,

I am very happy to see that so many people reply this topic, and especially with different ways of doing the same thing!

 

Yes, these are the kinds of threads that I find most valualable.  Every responder, regardless of facility with AutoIT, brings something to the conversation and affords me an opportunity to learn something.

Good Luck,

kylomas


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

Another possibility, with WinAPI (found with Google, not from me - of course) :

#Include <Array.au3>

$aUsers = _NetUserEnum()
_ArrayDisplay($aUsers)

; http://msdn.microsoft.com/en-us/library/windows/desktop/aa370652%28v=vs.85%29.aspx
; http://msdn.microsoft.com/en-us/library/windows/desktop/aa371109%28v=vs.85%29.aspx
Func _NetUserEnum($sServer = "") ; array[0] contains number of elements
    Local $tBufPtr = DllStructCreate("ptr")
    Local $tEntriesRead = DllStructCreate("dword")
    Local $tTotalEntries = DllStructCreate("dword")
    Local $aRet = DllCall("Netapi32.dll", "int", "NetUserEnum", "wstr", $sServer, "dword", 1, "dword", 2, "ptr", DllStructGetPtr($tBufPtr), "dword", -1, "ptr", DllStructGetPtr($tEntriesRead), "ptr", DllStructGetPtr($tTotalEntries), "ptr", 0 )
    If $aRet[0] Then Return SetError(1, $aRet[0], False)
    Local Const $UF_ACCOUNTDISABLE = 0x2
    Local $iEntriesRead = DllStructGetData($tEntriesRead,1)
    Local $pBuf = DllStructGetData($tBufPtr,1)
    Local $aUserEnum[1] = [0]
    Local $sUserInfo1 = "ptr;ptr;dword;dword;ptr;ptr;dword;ptr"
    Local $tUserInfo1 = DllStructCreate ($sUserInfo1)
    Local $zUserInfo1 = DllStructGetSize($tUserInfo1)
    For $i=1 To $iEntriesRead
        $tUserInfo1 = DllStructCreate($sUserInfo1, $pBuf+($i-1)*$zUserInfo1)
        $tName = DllStructCreate("wchar[256]", DllStructGetData($tUserInfo1,1))
        $tFlag = DllStructGetData($tUserInfo1,7)
        ; If BitAnd($tFlag, $UF_ACCOUNTDISABLE)=0 Then
            $aUserEnum[0] += 1
            ReDim $aUserEnum[$aUserEnum[0]+1]
            $aUserEnum[$aUserEnum[0]] = DllStructGetData($tName,1)
        ; EndIf
    Next
    DllCall("Netapi32.dll", "int", "NetApiBufferFree", "ptr", $pBuf)
    Return $aUserEnum
EndFunc    ;_NetUserEnum

Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...