Jump to content
Sign in to follow this  

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
Msgbox(0,"", $Result)
Edited by mikell

Share this post

Link to post
Share on other sites

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


NT AUTHORITYAuthenticated Users



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
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))
_ArrayDelete($aLocalUsers, 0) ; remove first empty line
_ArrayDisplay($aLocalUsers) ; show local users



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()
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
    $aReturn[0][0] = UBound($aReturn) - 1
    Return $aReturn

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
        SetExtended( $iCount )
    Return $sString
Edited by jguinch

Share this post

Link to post
Share on other sites


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,


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()

; 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
    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...