|
|
Hello Group,
I am trying to locate a script that would read and input file which contains a number of servers (1 per line), then connect to each computer and report on the userid (logon name) and description of each user connected to that group (ie: Administrators, Backup Operators, Power Users, etc). The drawback is, that on a number of the local computers, the Administrators group will have sub-groups that point back to Active Directory (ie: Domain Admins, Intel Admins, Security Admins, Web Admins, etc).
My predissor, gave me a couple of batch files and excutables that he used to use, but his batch script only used the "local.exe" program which only produced a report of the userids and did not expand the sub- groups. He then would go thru the list and import it into the spreadsheet and manually type in all the necessay information (which is contained in the description field). This would take him some time to complete due to the volume and the number of servers that had to be reported on.
I found a script that would ping a computer and then connect and query the groups to produce a list, but the script relies on the computer(s) being listed under the "Computers" folder. All the computers that I have to report on are listed under different folder under a sub-folder and they are all set up as group profiles and not computers.
The privileged access is normally granted by the computer group (ie: My_Computer_1, My_Computer_2, etc), as well as individual Active Directory user ids being connected locally on the computer(s) to the Administrators group or Power Users group.
Unfornately my expertise is in mainframe and rexx, I was assign this "temporary" position as no one else had free time to administer the servers (bummer).
Has any got a sample script that would read a input file of computers, connect to the computer, write out the logon names with descriptions, and also include any logon names/descriptions that are contained sub- groups (ie Administrators/My_Computer_1 would need to be expanded as it is in Active Directory as a group).?
Any insight would be greatly appreciated.
Mack
|
|
"Mack" <mbarss[ at ]shaw.ca> wrote in message news:1183481067.750428.290230[ at ]m36g2000hse.googlegroups.com...
[Quoted Text] > Hello Group, > > I am trying to locate a script that would read and input file which > contains a number of servers (1 per line), then connect to each > computer and report on the userid (logon name) and description of each > user connected to that group (ie: Administrators, Backup Operators, > Power Users, etc).
I'm getting dizzy, here. is this what you mean to say:
for each computer name for each group local to that computer
' LIST MEMBERS OF GROUP
for each member of that group if the member is a user then display the name and description elseif the member is a group LIST MEMBERS OF GROUP (a recursive call) end if next next
And, are the users and/or groups likely to include local objects, active directory objects, or perhaps both?
> The drawback is, that on a number of the local > computers, the Administrators group will have sub-groups that point > back to Active Directory (ie: Domain Admins, Intel Admins, Security > Admins, Web Admins, etc). > > My predissor, gave me a couple of batch files and excutables that he > used to use, but his batch script only used the "local.exe" program > which only produced a report of the userids and did not expand the sub- > groups. He then would go thru the list and import it into the > spreadsheet and manually type in all the necessay information (which > is contained in the description field). This would take him some time > to complete due to the volume and the number of servers that had to be > reported on. > > I found a script that would ping a computer and then connect and query > the groups to produce a list, but the script relies on the computer(s) > being listed under the "Computers" folder.
Which "Computers" folder - the one in active directory?
> All the computers that I > have to report on are listed under different folder under a sub-folder > and they are all set up as group profiles and not computers.
folder/sub-folder or ou/sub-ou?
> The privileged access is normally granted by the computer group (ie: > My_Computer_1, My_Computer_2, etc),
Computer group, what's that, a group that has computers as members?
> as well as individual Active > Directory user ids being connected locally on the computer(s) to the > Administrators group or Power Users group.
Connected to a group - do you mean they are members of a group?
> Unfornately my expertise is in mainframe and rexx, I was assign this > "temporary" position as no one else had free time to administer the > servers (bummer). > > Has any got a sample script that would read a input file of computers, > connect to the computer, write out the logon names with descriptions, > and also include any logon names/descriptions that are contained sub- > groups (ie Administrators/My_Computer_1 would need to be expanded as > it is in Active Directory as a group).?
I think it highly unlikely that anyone will have such a script sitting around in the form of an operational script, let alone a sample script.
> Any insight would be greatly appreciated.
First, is this something you plan on doing totally in batch, or are your options open to use vbscript or powershell?
Once you've decided on the platform, break the larger problem down into manageable chunks. And browse through the excellent example scripts on Richard Mueller's site at:
http://www.rlmueller.net/products.htm
/Al
|
|
Hello Al,
[Quoted Text] > I'm getting dizzy, here. is this what you mean to say: > > for each computer name > for each group local to that computer > > ' LIST MEMBERS OF GROUP > > for each member of that group > if the member is a user then > display the name and description > elseif the member is a group > LIST MEMBERS OF GROUP (a recursive call) > end if > next > next > > And, are the users and/or groups likely to include local objects, active > directory objects, or perhaps both?
Yes that is what I am trying to say. But on a number of the local computers, the local groups will contain groups that are defined at the Actived Directory level. ie: For local computer server123, the local Administrator's group can groups Intel_Team, Security_Team. These groups are defined in Active Directory and contains the users who belong to each particluar group.
> > Which "Computers" folder - the one in active directory? > > > All the computers that I > > have to report on are listed under different folder under a sub-folder > > and they are all set up as group profiles and not computers. > > folder/sub-folder or ou/sub-ou?
I'm still try to get the terminology right when it comes to Active Directory. When I look at Active Directory, there is a folder called Computers, I believe thats what you call the OU. The computers that I need to report on are actually in a sub OU of another OU and they are defined as groups instead of computers. Instead of it being Server123, it is defined as LA_Server123. They use it to give individuals local admin access to a computer. Then on the local computer, in the Administrators group, they add LA_Server123. >
> First, is this something you plan on doing totally in batch, or are your > options open to use vbscript or powershell?
My options are open, I'm hoping not having to do it totally in batch.
Mack
|
|
[Quoted Text] Ok, I've looke at Richard's site and found a vbs script that comes close to what I need to do. The vbs script is called EnumLocalGroup.vbs (http://www.rlmueller.net/Programs/ EnumLocalGroup.txt)
Now, if I'm reading the script right, it is getting the local computer names from Active Directory.
Is it possible to have the script read a input file that contains the list of computers?
The computers that I need to report on are defined as groups, ie:
Server Groups (folder name/ou I believe is the correct term Local Admin Server Groups (sub ou) LA_Server123 (actual server name is Server123) LA_BillyBob (actual server name is BillyBob) LA_server... LA_server... etc.. etc..
Mack
|
|
"Mack" <mbarss[ at ]shaw.ca> wrote in message news:1183642792.325725.265370[ at ]q69g2000hsb.googlegroups.com...
[Quoted Text] > >> >> http://www.rlmueller.net/products.htm>> > > Ok, I've looke at Richard's site and found a vbs script that comes > close to what I need to do. The vbs script is called > EnumLocalGroup.vbs ( http://www.rlmueller.net/Programs/> EnumLocalGroup.txt) > > Now, if I'm reading the script right, it is getting the local computer > names from Active Directory. > > Is it possible to have the script read a input file that contains the > list of computers? > > The computers that I need to report on are defined as groups, ie: > > Server Groups (folder name/ou I believe is the correct term > Local Admin Server Groups (sub ou) > LA_Server123 (actual server name is > Server123) > LA_BillyBob (actual server name is > BillyBob) > LA_server... > LA_server... > etc.. > etc.. > > Mack > The program EnumLocalGroup.vbs enumerates the membership of a local group. It is designed to be run on the computer with the group. The program retrieves the NetBIOS name of the domain and the name of the local computer from the wshNetwork object. The members can be local users or domain users. The program works through the group nesting to reveal all members, whether local or domain.
The program can be easily modified to enumerate the membership of a local group on a remote computer. You can also have the program read computer NetBIOS names and enumerate the membership of a local group on each computer. I'm not sure which local group or groups you are interested in, but you could expand this to enumerate several local groups.
In the example below (not tested), I don't include the code for Sub EnumLocalGroup or Sub EnumDomainGroup: ==================== Const ForReading = 1
' Specify file with NetBIOS names of computers. strFile = "c:\Scripts\Computers.txt"
' Open the text file for read access. Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile(strFile, ForReading)
' Determine NetBIOS name of domain. Set objNetwork = CreateObject("Wscript.Network") strNetBIOSDomain = objNetwork.UserDomain
' Read computer names from the file. Do Until objFile.AtEndOfStream strComputer = Trim(objFile.ReadLine) ' Skip blank lines. If (strComputer <> "") Then ' Output computer name. Wscript.Echo "Computer: " & strComputer ' Bind to local Administrators group on remote computer. ' Trap error if computer not available (or group does not exist). On Error Resume Next Set objLocalGroup = GetObject("WinNT://" & strComputer & "/Administrators,group") If (Err.Number = 0) Then On Error GoTo 0 ' No Error. Enumerate members of the local group. Call EnumLocalGroup(objLocalGroup) Else On Error GoTo 0 ' Error attempting to bind to group. Wscript.Echo "Unable to connect to group on " & strComputer End If End If Loop
' Clean up. objFile.Close =========== Since there could be a lot of output, the program should be run at a command prompt with the cscript host. The output can be redirected to a text file. For example, at a command prompt navigate to the folder where the VBScript program is saved and run a command similar to:
cscript //nologo EnumLocalGroup.vbs > report.txt
This will create a file called report.txt in the same folder with the output from the program. I hope this helps.
-- Richard Mueller Microsoft MVP Scripting and ADSI Hilltop Lab - http://www.rlmueller.net --
|
|
On Jul 5, 10:35 pm, "Richard Mueller [MVP]" <rlmueller- nos...[ at ]ameritech.nospam.net> wrote:
[Quoted Text] > "Mack" <mba...[ at ]shaw.ca> wrote in message > > The program EnumLocalGroup.vbs enumerates the membership of a local group. > It is designed to be run on the computer with the group. The program > retrieves the NetBIOS name of the domain and the name of the local computer > from the wshNetwork object. The members can be local users or domain users. > The program works through the group nesting to reveal all members, whether > local or domain. > > The program can be easily modified to enumerate the membership of a local > group on a remote computer. You can also have the program read computer > NetBIOS names and enumerate the membership of a local group on each > computer. I'm not sure which local group or groups you are interested in, > but you could expand this to enumerate several local groups. >
Hi Richard,
I've got the vbs script sort of working by combining the code you provided and adding in the EnumLocalGroup. At the moment, the code writes out the first name last name and then the ou and dc. What would I have to point to have it write out the login name and description?
I am also getting the following error:
ListPrivUsers.vbs(92, 9) (null): Name translation: Could not find the name or insufficient right to see name.
line 92 is coded (EnumLocalGroup routine from your site)
objTrans.Set ADS_NAME_TYPE_NT4, strNTName
When I look at the output to see what group it was hiccupping on, I checked both the group in AD and the sub groups with in it and all the groups are valid. I have Domain Admin rights.
Mack
|
|
|
[Quoted Text] > Hi Richard, > > I've got the vbs script sort of working by combining the code you > provided and adding in the EnumLocalGroup. At the moment, the code > writes out the first name last name and then the ou and dc. What > would I have to point to have it write out the login name and > description? > > I am also getting the following error: > > ListPrivUsers.vbs(92, 9) (null): Name translation: Could not find > the name or insufficient right to see name. > > line 92 is coded (EnumLocalGroup routine from your site) > > objTrans.Set ADS_NAME_TYPE_NT4, strNTName > > When I look at the output to see what group it was hiccupping on, I > checked both the group in AD and the sub groups with in it and all the > groups are valid. I have Domain Admin rights. > > Mack >
The problem could be that not all required constants were defined, or all global variables declared. The complete tested script is below. I added a statement to echo the name of the group, in case you want to enumerate more than one group. I also added to the statements that output member names. I output the AdsPath because that is the only way to tell whether the members are local or domain, and to uniquely identify each user. I added to the Echo statement so the NT name (pre-Windows 2000 logon name) and description are also display, separated by commas. ============== Option Explicit
Dim objNetwork, objLocalGroup, strFile, objFSO, objFile
' These attributes must be declared in the main program, ' so they are global in scope. Dim objTrans, strComputer, strNetBIOSDomain
' Constants for the NameTranslate object. Const ADS_NAME_INITTYPE_GC = 3 Const ADS_NAME_TYPE_NT4 = 3 Const ADS_NAME_TYPE_1779 = 1
Const ForReading = 1
' Specify file with NetBIOS names of computers. strFile = "c:\Scripts\Computers.txt"
' Open the text file for read access. Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile(strFile, ForReading)
' Determine NetBIOS name of domain. Set objNetwork = CreateObject("Wscript.Network") strNetBIOSDomain = objNetwork.UserDomain
' Read computer names from the file. Do Until objFile.AtEndOfStream strComputer = Trim(objFile.ReadLine) ' Skip blank lines. If (strComputer <> "") Then ' Output computer name. Wscript.Echo "Computer: " & strComputer ' Bind to local Administrators group on remote computer. ' Trap error if computer not available (or group does not exist). On Error Resume Next Set objLocalGroup = GetObject("WinNT://" & strComputer _ & "/Administrators,group") If (Err.Number = 0) Then On Error GoTo 0 ' No Error. Enumerate members of the local group. Wscript.Echo "Members of group " & objLocalGroup.Name Call EnumLocalGroup(objLocalGroup) Else On Error GoTo 0 ' Error attempting to bind to group. Wscript.Echo "Unable to connect to group on " & strComputer End If End If Loop
' Clean up. objFile.Close
Sub EnumLocalGroup(ByVal objGroup) ' Subroutine to enumerate members of local group. ' The variable strComputer has global scope.
Dim objMember
' Enumerate direct members of group. For Each objMember In objGroup.Members Wscript.Echo objMember.AdsPath & ", " & objMember.Name _ & ", " & objMember.description ' Test if member is a group. If (LCase(objMember.Class) = "group") Then ' Nested group. Test if objMember is a local group. If (InStr(LCase(objMember.AdsPath), "/" _ & LCase(strComputer) & "/") > 0) Then ' objMember is a local group. ' Call sub recursively to enumerate nested local group. Call EnumLocalGroup(objMember) Else ' objMember is a domain group. ' Call sub that uses LDAP provider to enumerate ' nested domain group. objMember is bound with ' WinNT provider. Call EnumDomainGroup(objMember, True) End If End If Next
End Sub
Sub EnumDomainGroup(ByVal objDomainGroup, ByVal blnNT) ' Subroutine to enumerate members of domain group. ' blnNT is True if objDomainGroup is bound with WinNT, ' False if bound with LDAP. ' The variables objTrans and strNetBIOSDomain have global scope.
Dim strNTName, strGroupDN, objGroup, objMember
' Check if this function called before. If (IsEmpty(objTrans) = True) Then ' objDomainGroup must be bound with WinNT. ' Setup NameTranslate. Connect to Global Catalog. Set objTrans = CreateObject("NameTranslate") objTrans.Init ADS_NAME_INITTYPE_GC, ""
' Convert NetBIOS name of group to Distinguished Name. strNTName = strNetBIOSDomain & "\" & objDomainGroup.Name objTrans.Set ADS_NAME_TYPE_NT4, strNTName strGroupDN = objTrans.Get(ADS_NAME_TYPE_1779) Else ' NameTranslate already setup. Check if objDomainGroup ' bound with WinNT. If (blnNT = True) Then ' Convert NetBIOS name of group to Distinguished Name. strNTName = strNetBIOSDomain & "\" & objDomainGroup.Name objTrans.Set ADS_NAME_TYPE_NT4, strNTName strGroupDN = objTrans.Get(ADS_NAME_TYPE_1779) Else ' objDomainGroup bound with LDAP. Retrieve Distinguished Name. strGroupDN = objDomainGroup.distinguishedName End If End If ' Bind to group with the LDAP provider, if required. If (blnNT = True) Then Set objGroup = GetObject("LDAP://" & strGroupDN) Else Set objGroup = objDomainGroup End If ' Enumerate direct members of objDomainGroup (bound with LDAP). For Each objMember In objGroup.Members Wscript.Echo objMember.AdsPath & ", " & objMember.sAMAccountName _ & ", " & objMember.description ' Check if objMember is a group. If (LCase(objMember.Class) = "group") Then ' Call sub recursively. objMember bound with LDAP. Call EnumDomainGroup(objMember, False) End If Next
End Sub
-- Richard Mueller Microsoft MVP Scripting and ADSI Hilltop Lab - http://www.rlmueller.net --
|
|
On Jul 6, 11:28 am, "Richard Mueller [MVP]" <rlmueller- nos...[ at ]ameritech.nospam.net> wrote:
[Quoted Text] > > The problem could be that not all required constants were defined, or all > global variables declared. The complete tested script is below. I added a > statement to echo the name of the group, in case you want to enumerate more > than one group. I also added to the statements that output member names. I > output the AdsPath because that is the only way to tell whether the members > are local or domain, and to uniquely identify each user. I added to the Echo > statement so the NT name (pre-Windows 2000 logon name) and description are > also display, separated by commas. > ============== > Option Explicit >
Thank you Richard... you are a life saver. Works great!!! I greatly appreciated your insight.
Mack
|
|
Hi Richard,
Everything was going smoothly until I expanded my computers.txt to include more computers.
On one server, as its reading and writing the info from the local Administrators group, I get the error:
ListPrivUsers.vbs(74, 9) Active Directory: An unknown directory user object was requested
I looked at the Administrators group on the local computer and believe I see the problem. There is a "S-1-5-21-1275210071-", (I believe its refered to as a SID) showing instead of a user name.
I have seen this before on other local computers but could not figure how it came to be. Checking the computers that were processed earlier in the list, I see that they do not have this problem.
Malcolm
|
|
My Administrators groups don't have this, but my Users groups do. The SIDs are used when the corresponding object no longer exists. It may help to not attempt to retrieve the values of sAMAccountName and decription, but just output the AdsPath. The AdsPath can be displayed, it will use the SID instead of the Common Name of the member. The error is raised when we attempt to retrieve other attributes. I would replace:
Wscript.Echo objMember.AdsPath & ", " & objMember.Name _ & ", " & objMember.description
with this:
On Error Resume Next Wscript.Echo objMember.AdsPath & ", " & objMember.Name _ & ", " & objMember.description If (Err.Number <> 0) Then Wscript.Echo objMember.AdsPath End If On Error GoTo 0
This first attempts to output all 3 values, but if that fails traps the errror and just outputs the AdsPath.
-- Richard Mueller Microsoft MVP Scripting and ADSI Hilltop Lab - http://www.rlmueller.net --
"Mack" <mbarss[ at ]shaw.ca> wrote in message news:1183744320.299222.41970[ at ]c77g2000hse.googlegroups.com...
[Quoted Text] > Hi Richard, > > Everything was going smoothly until I expanded my computers.txt to > include more computers. > > On one server, as its reading and writing the info from the local > Administrators group, I get the error: > > ListPrivUsers.vbs(74, 9) Active Directory: An unknown directory > user object was requested > > I looked at the Administrators group on the local computer and believe > I see the problem. There is a > "S-1-5-21-1275210071-", (I believe its refered to as a SID) showing > instead of a user name. > > I have seen this before on other local computers but could not figure > how it came to be. Checking the computers that were processed earlier > in the list, I see that they do not have this problem. > > Malcolm > >
|
|
Hi Richard,
Hit another snag. The script was very happily going along until I was on the 36 server.
I now get the following error:
ListPrivUsers.vbs(132, 13) (null): Name translation: Could not find the name or insufficient right to see name.
the code that is erroring in is:
' NameTranslate already setup. Check if objDomainGroup ' bound with WinNT. If (blnNT = True) Then ' Convert NetBIOS name of group to Distinguished Name. strNTName = strNetBIOSDomain & "\" & objDomainGroup.Name objTrans.Set ADS_NAME_TYPE_NT4, strNTName <==== this is line 132 strGroupDN = objTrans.Get(ADS_NAME_TYPE_1779) Else ' objDomainGroup bound with LDAP. Retrieve Distinguished Name. strGroupDN = objDomainGroup.distinguishedName End If
At first I thought that it was choking on the next server name in the list, so I opened "Computer Management" to ensure that I could connect to the next server in the list. I was to view the Groups and Users on the server. I then used Computer Management to connect to the server that it was currently executing the script against. I looked at the Administrators group and then at the output and it appears everything was reported on. I could not see anything wrong with the Administrators group.
Is there a way to write the errors to a seperate error log when an error is encountered and still be able to process to the end of the server input list?
Malcolm
|
|
|