Solved

Finding members of a group through all domains.

Posted on 2011-09-22
7
300 Views
Last Modified: 2012-05-12
Hi guys hope you are all well and can assist.

We are attempting to use the following script to output all members of the following groups:

Schema Admins
Enterprise Admins
Domain Admins

What we are finding is that it is working, but not completely finishing..

It gets the list of domain admins from the first domain, then it seems to try for the second domain, and fails....it writes the name Domain Admins for the second domain and then fails.

The error we get is:

Line: 101
Char: 1
Error: Object not a collection
Code: 800A01C3
Source: Microsoft VBScript runtime error


We believe it is something in the following section of the code:

Do Until adoRS.EOF
Dim strMember
objTempFile.WriteLine vbTab & adoRS.Fields(0).Value
For Each strMember in adoRS.Fields(1).Value
objTempFile.WriteLine vbTab & vbTab & strMember
Next
adoRS.MoveNext
Loop


ANy help greatly appreciated.

If there is a way to change the script so that it does not look through every domain, but only one domain would be good.

Thanks guys.


'==========================================================================
' VBScript Source File
' NAME  : Active Directory Admin Audit
' AUTHOR : Andrew J Healey
' DATE  : 2009.04.16
' UPDATED: 2011.06.21
' USAGE  : cscript /nologo AD-AdminAudit.vbs
' COMMENT: This script will check all the domains within a forest
'    and report all the members of the following groups: Schema
'    Admins, Enterprise Admins and Domain Admins. See notes to
'    expand on the groups.
'==========================================================================

Option Explicit

'Define Constants
Const adUseClient = 3
Const ForWriting = 2

'Set the path and filename for the dump of sensitive users
'  Folder must exist!
Dim fileTemp : fileTemp = "D:\temp\AD_Admin_Audit.txt"

' Create tmp file and report file
Dim objFSO, objTempFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTempFile = objFSO.OpenTextFile(fileTemp, ForWriting, True)

' Query RootDSE and return array with all AD domains in forest
Dim adoCommand, adoConnection, objRootDSE
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.cursorLocation = adUseClient
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
Set objRootDSE = GetObject("LDAP://RootDSE")

' Build the LDAP Query
Dim strBase, strFilter, strAttrs, strScope, strQuery
strBase  =  "<GC://" & objRootDSE.Get("rootDomainNamingContext") & ">;"
strFilter = "(objectcategory=domainDNS);"
strAttrs  = "distinguishedName;"
strScope  = "subtree"
strQuery = strBase & strFilter & strAttrs & strScope

' Set Query parameters
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 50
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

' Execute the query
Dim adoRecordSet : Set adoRecordSet = adoCommand.Execute

' Start Loop
Do Until adoRecordSet.EOF
' Parse ad search results to create well formed DNS domain
Dim strDomain
strDomain = Replace(adoRecordSet.Fields(0).Value,"DC=","")
strDomain = Replace(strDomain,",",".")
Call GrpAll(strDomain)
adoRecordSet.MoveNext
Loop
adoRecordSet.Close
adoConnection.Close

Private Function GrpAll(byVal strDomain)
' To search for more groups, edit the "strFilter" line. It uses a simple
'  LDAP or (|) so multiple groups can be added. It uses ADO record sets
'  to loop so it doesn't have to find all of them, just one. Every domain
'  will contain at least the Domain Admins group.
Dim adoComm, adoConn
Set adoComm = CreateObject("ADODB.Command")
Set adoConn = CreateObject("ADODB.Connection")
adoConn.Provider = "ADsDSOObject"
adoConn.cursorLocation = adUseClient
adoConn.Open "Active Directory Provider"
adoComm.ActiveConnection = adoConn

strBase  = "<GC://" & strDomain & ">;"
strFilter = "(&(objectCategory=group)(|((name=Enterprise Admins*)(name=Domain Admins*)(name=Schema Admins*))));"
strAttrs  = "name,member;"
strScope  = "subtree"

strQuery = strBase & strFilter & strAttrs & strScope
adoComm.CommandText = strQuery
adoComm.Properties("Page Size") = 5000
adoComm.Properties("Timeout") = 30
adoComm.Properties("Cache Results") = False

Dim adoRS : Set adoRS = adoComm.Execute

objTempFile.WriteLine "Group report for domain: " & strDomain

adoRS.MoveFirst

Do Until adoRS.EOF
Dim strMember
objTempFile.WriteLine vbTab & adoRS.Fields(0).Value
For Each strMember in adoRS.Fields(1).Value
objTempFile.WriteLine vbTab & vbTab & strMember
Next
adoRS.MoveNext
Loop

adoRS.Close
adoConn.Close
End Function

Open in new window

0
Comment
Question by:Simon336697
  • 5
  • 2
7 Comments
 
LVL 39

Expert Comment

by:Krzysztof Pytko
ID: 36585335
Have you considered to use for that PowerShell? In 2003/XP environment you can use Quest PowerShell Module for AD. It's free and can be downloaded from

http://www.quest.com/powershell/activeroles-server.aspx

and you can use this syntax

create text file with all domains in this format

dc=testenv,dc=local
dc=europe,dc=testenv,dc=local
dc=asia,dc=testenv,dc=local

and user PowerShell script

Get-Content c:\domains.txt | For-Each {

Get-QADGroup "cn=Domain Admins,cn=users,$_" | Get-QADGroupMembers | Get-QADUser | Select sAMAccountName,givenName,sn
Get-QADGroup "cn=Enterprise Admins,cn=users,$_" | Get-QADGroupMembers | Get-QADUser | Select sAMAccountName,givenName,sn
Get-QADGroup "cn=Schema Admins,cn=users,$_" | Get-QADGroupMembers | Get-QADUser | Select sAMAccountName,givenName,sn
}

save it as domains.ps1 and run in PowerShell

I've no tested it yet :/ so maybe there are some errors in a syntax. I'm connecting to my env to check that :)

Regards,
Krzysztof
0
 
LVL 39

Expert Comment

by:Krzysztof Pytko
ID: 36585470
OK, I've checked a script and fixed errors. Now it works better :)

Use this sytnax, but before use will be able to run PowerShell scripts in PS console, you need to modify execution policy by typing

Set-ExecutionPolicy Unrestricted

and confirm by "Y" key

Example PS script:

Clear-Host

Get-Content c:\output\domains.txt | ForEach {

Write-Host ""
Write-Host "Domain $_"
Write-Host ""

Write-Host "Domain Administrators"
Get-QADGroup -SearchRoot $_ "Domain Admins" | Get-QADGroupMember -Indirect | Get-QADUser | Select
sAMAccountName,givenName,sn
Write-Host ""

Write-Host "Enterprise Administrators"
Get-QADGroup -SearchRoot $_ "Enterprise Admins" | Get-QADGroupMember -Indirect | Get-QADUser | Select
sAMAccountName,givenName,sn
Write-Host ""

write-Host "Schema Administrators"
Get-QADGroup -SearchRoot $_ "Schema Admins" | Get-QADGroupMember -Indirect | Get-QADUser | Select
sAMAccountName,givenName,sn
Write-Host ""


Write-Host ""

}

Krzysztof
0
 
LVL 1

Author Comment

by:Simon336697
ID: 36654031
Hi Krzysztof,

Thanks mate.

I tried your script, and it does return results, but does error on the following:



This is the code Im using:

The term 'sAMAccountName' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is cor
rect and try again.
At D:\temp\scripts\getusers.ps1:11 char:15
+ sAMAccountName <<<< ,givenName,sn
    + CategoryInfo          : ObjectNotFound: (sAMAccountName:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException


Enterprise Administrators
The term 'sAMAccountName' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is cor
rect and try again.
At D:\temp\scripts\getusers.ps1:16 char:15
+ sAMAccountName <<<< ,givenName,sn
    + CategoryInfo          : ObjectNotFound: (sAMAccountName:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException


Schema Administrators
The term 'sAMAccountName' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is cor
rect and try again.
At D:\temp\scripts\getusers.ps1:21 char:15
+ sAMAccountName <<<< ,givenName,sn
    + CategoryInfo          : ObjectNotFound: (sAMAccountName:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Clear-Host

Get-Content d:\temp\scripts\domains.txt | ForEach { 

Write-Host ""
Write-Host "Domain $_"
Write-Host ""

Write-Host "Domain Administrators"
Get-QADGroup -SearchRoot $_ "Domain Admins" | Get-QADGroupMember -Indirect | Get-QADUser | Select 
sAMAccountName,givenName,sn
Write-Host ""

Write-Host "Enterprise Administrators"
Get-QADGroup -SearchRoot $_ "Enterprise Admins" | Get-QADGroupMember -Indirect | Get-QADUser | Select 
sAMAccountName,givenName,sn
Write-Host ""

write-Host "Schema Administrators"
Get-QADGroup -SearchRoot $_ "Schema Admins" | Get-QADGroupMember -Indirect | Get-QADUser | Select 
sAMAccountName,givenName,sn
Write-Host ""


Write-Host ""

}

Open in new window

0
 
LVL 39

Accepted Solution

by:
Krzysztof Pytko earned 500 total points
ID: 36707693
Yup, when I run your script it shows me the same error :/ When I run my script it works :O
So, please try with attached file, remove .txt extension from file

 domains.ps1.txt

Krzysztof
0
 
LVL 39

Expert Comment

by:Krzysztof Pytko
ID: 36715709
Does the script work for you or we need to dig deeper why it doesn't want to work? Thanks in advance for the answer

Krzysztof
0
 
LVL 39

Expert Comment

by:Krzysztof Pytko
ID: 36915716
Any progress with this script in your newtrok?
Thanks for the answer in advance

Krzysztof
0
 
LVL 1

Author Comment

by:Simon336697
ID: 37034806
Thanks iSiek
0

Join & Write a Comment

I know all systems administrator at some time or another has had to create a script to copy file from a server share to a desktop. Well now there is an easy way to do this in Group Policy. Using Group policy preferences is not hard. The first thing …
Resolve DNS query failed errors for Exchange
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now