Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I would like to compile a list of local users accounts from all servers on the network. This would include domain and non domain W2K3 machines. A script to run net user and pipe the results to a file? Any help is appreciated. Thx

share|improve this question

The Quick and Dirty Way

You'll need PsExec from Microsoft for this script to work. I'm assuming that you can connect to the non-domain member and domain member computers with the same username and password. If that's not possible, let me know and I'll change up the script a little bit.

Put a list of machine names into machines.txt and run:

@echo off

for /F "delims=" %%i in (machines.txt) do (
 psexec \\%%i NET USER > %%i.txt

You'll end up with a bunch of text files of the format computer-name.txt with the output of "NET USER" on each computer.

The Fancy(tm) Way

That's pretty quick-and-dirty and the output would be fairly painful to parse. Here's a fancier script in VBScript:

Option Explicit

Dim dictGroupsToIgnore, dictUsersToIgnore, objNetwork, strComputer
Dim colUsers, colGroups, objGroup, objUser

' Debugging
Const DEBUGGING = True

' Constants for comparison of accounts to ignore list
Const MATCH_LEFT = 2

Set dictGroupsToIgnore = CreateObject("Scripting.Dictionary")
' dictGroupsToIgnore.Add "Name of group you want to ignore (matching left only)", MATCH_LEFT
' dictGroupsToIgnore.Add "Name of group you want to ignore", MATCH_EXACT

' Accounts to ignore during copying
Set dictUsersToIgnore = CreateObject("Scripting.Dictionary")
' dictUsersToIgnore.Add "Name of user you want to ignore (matching left only)", MATCH_LEFT
' dictUsersToIgnore.Add "Name of user you want to ignore", MATCH_EXACT

' Should this account be ignored
Function IgnoreObject(Name, dictNames)
    Dim strToIgnore

    IgnoreObject = False

    For Each strToIgnore in dictNames

    	' Match Exact
    	If (dictNames.Item(strToIgnore) = MATCH_EXACT) and (UCase(Name) = UCase(strToIgnore)) Then
    		IgnoreObject = True
    		Exit Function
    	End If

    	' Match left
    	If (dictNames.Item(strToIgnore) = MATCH_LEFT) and (Left(UCase(Name), Len(strToIgnore)) = UCase(strToIgnore)) Then
    		IgnoreObject = True
    		Exit Function
    	End If

    Next' strToIgnore
End Function

' Main

Set objNetwork = CreateObject("Wscript.Network")

While NOT WScript.StdIn.AtEndOfStream

    strComputer = WScript.StdIn.ReadLine

    ' Get accounts on source computer and loop through them, copying as necessary
    Set colUsers = GetObject("WinNT://" & strComputer)
    colUsers.Filter = Array("user")

    For Each objUser In colUsers
    	If IgnoreObject(objUser.Name, dictUsersToIgnore) = False Then
    		WScript.Echo strComputer & Chr(9) & "user" & Chr(9) & objUser.Name
    	End If
    Next ' objUser

    ' Get groups on source computer and loop through them, copying as necessary
    Set colGroups = GetObject("WinNT://" & strComputer)
    colGroups.Filter = Array("group")

    ' Put user into destination groups
    For Each objGroup In colGroups
    	If IgnoreObject(objGroup.Name, dictGroupsToIgnore) = False then
    		For Each objUser In objGroup.Members
    			WScript.Echo strComputer & Chr(9) & "group" & Chr(9) & objGroup.Name & Chr(9) & "member" & Chr(9) & objUser.Name
    		Next ' objUser
    	End If
    Next 'objGroup
Wend ' WScript.StdIn.AtEndOfStream

I've included some functionality to "ignore" groups or users, too.

  • Add any group names that should not be reported to the dictGroupsToIgnore list (as shown in the script). MATCH_EXACT means that the name of the group is matched exactly. MATCH_LEFT means that only the leftmost portion of the group name will be matched (i.e. imagine that the name match has a "*" after it).

  • Add any user names that should not be reported to the dictUsersToIgnore list (as shown in the script, too). MATCH_EXACT and MATCH_LEFT have the same meanings as with the dictGroupsToIgnores list (i.e. "IUSR_" with MATCH_LEFT means that any user account starting with "IUSR_" will not be reported).

Call this script redirecting input from a text file and output to a text file (i.e. "cscript script-name.vbs < machines.txt > report.txt") and you'll get a TAB delimited output of the format:

computer_name   user   username
computer_name   group  groupname   member   member_1_name
computer_name   group  groupname   member   member_2_name
computer_name   group  groupname   member   member_3_name

You might not need the group information but it'll be easy to filter away later.

If you need to connect to each machine with different credentials let me know and I'll change up the script a bit.

share|improve this answer
The quick and dirty way worked for me. I had to add the -h switch to psexec to get it to work on Vista (and I presume Win7, 2008r2 but haven't tested yet) machines.. – Joe Niland Mar 19 '11 at 2:39

I remember working on something similar a few years ago. There is probably 5 ways that you could easily have this done via a script however recently I was introduced to SYDI and I recommend that you check it out, it might serve more benefits then just the audit tracking of users localy.

Snippit from site :Usage Scenarios You might want to track how many local administrators you have in your organization, perhaps some users have been placed in the local administrators group “temporarily” but have now settled in with all the privileges it provides. Even if your organization doesn’t yet disallow local administrative access you still might want to be able to see in black and white which users have been granted this access. The Power Users group can be another group you want to monitor.

If you have a standardized environment your group structure on your clients should all look the same way. You can use the tool to find any additional groups which shouldn’t be there.

Using the Script Like many other SYDI tools this script is written in vbscript and intended to be run from cscript.exe. To use it you provide an argument with the path to your SYDI Server output files:

Cscript.exe sydi-audit-localgroups.vbs -xN:\SYDI\Output

Let me know how it works out

Best, Nick

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.