?
Solved

exporting empty groups AD server 2003

Posted on 2013-11-13
16
Medium Priority
?
276 Views
Last Modified: 2013-11-15
Hi,

I'd like to export all the empty groups in AD.  I have found the vb script below from a previous question.  I would like to know how to write the output to a text file?

On Error Resume Next

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE

objCommand.CommandText = _
    "SELECT Name,Member FROM 'LDAP://dc=rustice,dc=local' WHERE objectCategory='group'"
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    If isNull(objRecordSet.Fields("Member").Value) Then
          Wscript.Echo objRecordSet.Fields("Name").Value
    End If
    objRecordSet.MoveNext
Loop
0
Comment
Question by:cmatchett
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 7
16 Comments
 
LVL 12

Expert Comment

by:piattnd
ID: 39645423
This link describes it pretty well, but I've included the code below.

http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/other/textfiles/#WriteDataText.htm

On Error Resume Next

Const ADS_SCOPE_SUBTREE = 2
'2 indicates you want to write to the file.  This will wipe out the contents of the file when you open it
Const ForWriting = 2

'Path to the log file.  Change this if you want
strLogFilePath = "C:\someLog.txt"

Set objFSO = CreateObject("Scripting.FileSystemObject")

'make sure the file exists, create it if it doesn't
if NOT objFSO.FileExists(strLogFilePath) then
    objFSO.CreateTextFile(strLogFilePath,true)
end if

'Open the log file so we can write to it
Set objLog = objFSO.OpenTextFile(strLogFilePath,ForWriting)

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 

objCommand.CommandText = _
    "SELECT Name,Member FROM 'LDAP://dc=rustice,dc=local' WHERE objectCategory='group'"
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    If isNull(objRecordSet.Fields("Member").Value) Then
          objLog.writeline(objRecordSet.Fields("Name").Value)
          'Wscript.Echo objRecordSet.Fields("Name").Value
    End If
    objRecordSet.MoveNext
Loop 

'close the log file
objLog.close

Open in new window


Let me know if you get any errors
0
 
LVL 12

Expert Comment

by:piattnd
ID: 39645424
Oh, make sure you comment out your On Error Resume Next, otherwise you won't be able to see if it errors on the log file portion (I didn't write in error handling).
0
 

Author Comment

by:cmatchett
ID: 39645488
does appear to create and write to the file
0
Office 365 Training for Admins - 7 Day Trial

Learn how to provision tenants, synchronize on-premise Active Directory, implement Single Sign-On, customize Office deployment, and protect your organization with eDiscovery and DLP policies.  Only from Platform Scholar.

 

Author Comment

by:cmatchett
ID: 39645500
the error is...

Cannot use parentheses when calling a Sub
0
 

Author Comment

by:cmatchett
ID: 39645507
sorry my comment previously was meant to say that it did not create the text file and write to it
0
 
LVL 12

Accepted Solution

by:
piattnd earned 1500 total points
ID: 39645548
Try this:

On Error Resume Next

Const ADS_SCOPE_SUBTREE = 2
'2 indicates you want to write to the file.  This will wipe out the contents of the file when you open it
Const ForWriting = 2

'Path to the log file.  Change this if you want
strLogFilePath = "C:\someLog.txt"

Set objFSO = CreateObject("Scripting.FileSystemObject")

'make sure the file exists, create it if it doesn't
if NOT objFSO.FileExists(strLogFilePath) then
    objFSO.CreateTextFile strLogFilePath,true
end if

'Open the log file so we can write to it
Set objLog = objFSO.OpenTextFile(strLogFilePath,ForWriting)

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 

objCommand.CommandText = _
    "SELECT Name,Member FROM 'LDAP://dc=rustice,dc=local' WHERE objectCategory='group'"
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    If isNull(objRecordSet.Fields("Member").Value) Then
          objLog.writeline objRecordSet.Fields("Name").Value
          'Wscript.Echo objRecordSet.Fields("Name").Value
    End If
    objRecordSet.MoveNext
Loop 

'close the log file
objLog.close

Open in new window

0
 

Author Comment

by:cmatchett
ID: 39646538
top stuff piattnd
0
 

Author Comment

by:cmatchett
ID: 39646548
How do i add further fields into it?  Like if i want the type of the group?
0
 
LVL 12

Expert Comment

by:piattnd
ID: 39646569
Hah, now you're getting into the nitty-gritty of how Microsoft stores stuff like that in Active Directory!  :)

See this link:

http://blogs.technet.com/b/heyscriptingguy/archive/2004/12/21/how-can-i-tell-whether-a-group-is-a-security-group-or-a-distribution-group.aspx

Basically, you'd need to change a few lines, starting with your query line:
objCommand.CommandText = _
    "SELECT Name,Member FROM 'LDAP://dc=rustice,dc=local' WHERE objectCategory='group'"

Open in new window

Change that to include the distinguishedName:
objCommand.CommandText = _
    "SELECT distinguishedName,Name,Member FROM 'LDAP://dc=rustice,dc=local' WHERE objectCategory='group'"

Open in new window

Now once you've found a group that is empty, get the type of group.  Here is the chunk of code as you have it:
    If isNull(objRecordSet.Fields("Member").Value) Then
          objLog.writeline objRecordSet.Fields("Name").Value
          'Wscript.Echo objRecordSet.Fields("Name").Value
    End If

Open in new window

Change that to:
    If isNull(objRecordSet.Fields("Member").Value) Then
          'grab the distinguishedName and throw it into a variable
          strGroupDN = objRecordSet.Fields("distinguishedName").Value
          'connect to that object so you can grab further attributes
          Set objGroup = GetObject(strGroupDN)
          'Set the strGroupType to unknown in case it doesn't match one of the below
          strGroupType = "unknown"
          'Using the code in the link, determine the group type and assign it to a variable
           Select Case objGroup.GroupType
           Case 2
                strGroupType = "global distro"
                'Wscript.Echo "This is a global distribution group."
           Case 4
                strGroupType = "local distro"
                'Wscript.Echo "This is a domain local distribution group."
           Case 8
                strGroupType = "universal distro"
                'Wscript.Echo "This is a universal distribution group."
           Case -2147483646
                strGroupType = "global security"
                'Wscript.Echo "This is a global security group."
           Case -2147483644
                strGroupType = "local security"
                'Wscript.Echo "This is a domain local security group."
          Case -2147483640
                strGroupType = "universal security"
                'Wscript.Echo "This is a universal security group."
          End Select

          objLog.writeline objRecordSet.Fields("Name").Value & " - GROUP TYPE: " & strGroupType
          'Wscript.Echo objRecordSet.Fields("Name").Value
    End If

Open in new window

That should do it for ya.  Let me know if you get any errors.
0
 

Author Comment

by:cmatchett
ID: 39646581
in these sections below, fields member and name is selected.  The evaluation is done on member and then the name is written to text file.  Could you not also SELECT TYPE, NAME, MEMBER and then write type and name to the log too?  I tried an extra line to write type but it didn't work

objCommand.CommandText = _
    "SELECT Name,Member FROM 'LDAP://dc=rustice,dc=local' WHERE objectCategory='group'"
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    If isNull(objRecordSet.Fields("Member").Value) Then
          objLog.writeline objRecordSet.Fields("Name").Value
          'Wscript.Echo objRecordSet.Fields("Name").Value
    End If
    objRecordSet.MoveNext
Loop
0
 
LVL 12

Expert Comment

by:piattnd
ID: 39646586
I posted all the code changes needed to accomplish this in my previous response.  You cannot grab additional attributes from a query that you didn't ask for.

For example, your query asks for "name" and "member".  You will only be given the values of "name" and "member" for each group matching your filter (all groups).  Some attributes are not indexed and not possible to grab through a query like that, so you have to connect directly to the object (see my code).  Once you are bound to the object, you can grab those attributes.
0
 

Author Comment

by:cmatchett
ID: 39646598
super stuff, i will try it in the morning.
0
 

Author Comment

by:cmatchett
ID: 39647351
Hi,

The output lists all groups as unknown.  The values match the values in ADSI edit
0
 
LVL 12

Expert Comment

by:piattnd
ID: 39647965
Put a wscript.echo right before the "select case..." statement to echo out the value of objGroup.GroupType.  Also echo the name of the group in there so you can compare the value it echos for GroupType to the actual type of group it is.
0
 
LVL 12

Expert Comment

by:piattnd
ID: 39647969
Oh, and if you put the On Error Resume Next back in, take that out.  You want to be notified if there's an error (or you need to code in error handling).
0
 

Author Comment

by:cmatchett
ID: 39650848
I got the group type using LDIFDE.  You were a great help super stuff
0

Featured Post

Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Had a business requirement to store the mobile number in an environmental variable. This is just a quick article on how this was done.
Uncontrolled local administrators groups within any organization pose a huge security risk. Because these groups are locally managed it becomes difficult to audit and maintain them.
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles from a Windows Server 2008 domain controller to a Windows Server 2012 domain controlle…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …
Suggested Courses

765 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