O caminho rápido e sujo
Você precisará do PsExec da Microsoft para que esse script funcione. Eu estou supondo que você pode se conectar ao membro não-domínio e computadores membros do domínio com o mesmo nome de usuário e senha. Se isso não for possível, me avise e vou alterar o roteiro um pouco.
Coloque uma lista de nomes de máquinas em machines.txt e execute:
@echo off
for /F "delims=" %%i in (machines.txt) do (
psexec \%%i NET USER > %%i.txt
)
Você vai acabar com um monte de arquivos de texto no formato computer-name.txt com a saída "NET USER" em cada computador.
O modo Fancy (tm)
Isso é muito rápido e sujo e a saída seria bastante dolorosa para analisar. Aqui está um script mais elaborado no 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_EXACT = 1
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
Eu incluí algumas funcionalidades para "ignorar" grupos ou usuários também.
-
Adicione nomes de grupos que não devem ser informados à lista dictGroupsToIgnore (conforme mostrado no script). MATCH_EXACT significa que o nome do grupo é correspondido exatamente. MATCH_LEFT significa que apenas a parte mais à esquerda do nome do grupo será correspondida (por exemplo, imagine que a correspondência de nome tenha um "*" depois disso).
-
Adicione nomes de usuários que não devem ser informados à lista dictUsersToIgnore (como mostrado no script também). MATCH_EXACT e MATCH_LEFT têm os mesmos significados que com a lista dictGroupsToIgnores (ou seja, "IUSR_" com MATCH_LEFT significa que qualquer conta de usuário que comece com "IUSR_" não será informada).
Chame esse script redirecionando a entrada de um arquivo de texto e a saída para um arquivo de texto (por exemplo, "cscript script-name.vbs < machines.txt > report.txt") e você obterá uma saída delimitada por TAB do formato:
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
...
Talvez você não precise das informações do grupo, mas será fácil filtrá-las depois.
Se você precisar se conectar a cada máquina com credenciais diferentes, avise-me e alterarei um pouco o script.