tobstah
asked on
vb script to find empty ad groups
Can someone share a vb script that will generate a list of groups with zero user objects as members active directory groups from a 2000 domain? thanks.
I'll throw in the adfind/LDAP method
http://www.joeware.net/fre etools/too ls/adfind/index.htm
adfind -default -f "&(objectcategory=group)(! member=*)" name member
member should not return/output any results but I added it to double check the query.
Thanks
Mike
http://www.joeware.net/fre
adfind -default -f "&(objectcategory=group)(!
member should not return/output any results but I added it to double check the query.
Thanks
Mike
You'll probably find Domain Users included in the output from the queries above (unless you changed the Primary Group setting for anyone). That's because of how membership for that group is stored. So, if it is included, it's not an error and you can just ignore it.
Chris
ASKER
Unfortunately powershell does not work with windows 2000 AD.
It won't install on the server, but it will run against the directory if you have an XP workstation (or a 2003 server somewhere).
Still, ADFind will, or the query Mike wrote can be used in AD Users and Computers if you prefer. Either in a Saved Query or in the Find option, in both cases, choose Custom Search, then use the Advanced tab and paste the query into there.
Chris
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Nice script. What about putting the output into an excel spreadsheet with the group name, parent OU, and LDAP path in separate cells? Here is kinda what I have in mind at the bottom...
'Define Constants
Const ADS_SCOPE_SUBTREE = 2 ' Search target object and all sub levels
'Set Variables
DQ = Chr(34) 'Double Quote
'Create Objects
Set objShell = CreateObject("Wscript.Shell")
'Verifies script was run using CSCRIPT, and if not relauches it using CSCRIPT
If Not WScript.FullName = WScript.Path & "\cscript.exe" Then
objShell.Popup "Launched using wscript. Relaunching...", 5, "WSCRIPT"
objShell.Run "cmd.exe /k " & WScript.Path & "\cscript.exe //NOLOGO " & _
DQ & WScript.scriptFullName & DQ, 1, False
WScript.Quit 0
End If
'Construct an ADsPath to the Current Domain with rootDSE
Set objRootDSE = GetObject("LDAP://rootDSE")
strADsPath = "LDAP://" & objRootDSE.Get("defaultNamingContext")
'Connect to Active Directory
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 ADsPath,member FROM '" & strADsPath & _
"'" & " WHERE objectClass='group'"
Set objRecordSet = objCommand.Execute
If objRecordSet.EOF Then
WScript.echo "Error, no groups found"
WScript.quit
Else
WScript.Echo "List of empty groups"
WScript.Echo "============================================================="
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
strGroupName = objRecordSet.Fields("ADsPath").Value
arrMembers = objRecordSet.Fields("member").Value
If IsNull(arrMembers) Then
WScript.Echo strGroupName
End If
objRecordSet.MoveNext
Loop
End If
WScript.Echo "Script has finished"
________________________
'constant for incrementing the line in the excel spreadsheet.
k=2
strExcelPath = InputBox ("Please enter the path to save file to: ", "File path", "F:\")
strExcelPath = strExcelPath & "Printers_" & strComputer & ".xls"
' Bind to Excel object.
On Error Resume Next
Set objExcel = CreateObject("Excel.Application")
If Err.Number <> 0 Then
On Error GoTo 0
Wscript.Echo "Excel application not found."
Wscript.Quit
End If
' Create a new workbook.
objExcel.Workbooks.Add
'populate the row with this printer's data
objSheet.Cells(k, 1).Value = strGroupName
objSheet.Cells(k, 2).Value = strGroupName.dn
'move down one line
k = k + 1
ASKER
Incidentally I have *hundreds* of empty groups and dozens of nested OUs to identify and remove.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Code comments are good for us newbs.
Ahh true, sorry, bit of a rush had to go and cook dinner ;)
Chris
' Create an object to connect to AD
Dim objConnection : Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
' Create the Command object
Dim objCommand : Set objCommand = CreateObject("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
' Enable Paging. Limited to 1000 results otherwise, this returns 1000 per page
objCommand.Properties("Page Size") = 1000
' Connect to RootDSE, useful to get configuration information for the current forest
Dim objRootDSE : Set objRootDSE = GetObject("LDAP://RootDSE")
' Create a command to search AD. defaultNamingContext is the current domain in the form
' DC=domain,DC=com.
objCommand.CommandText = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">;" & _
"(&(objectClass=group)(!member=*));name,distinguishedName;subtree"
' Execute the command
Dim objRecordSet : Set objRecordSet = objCommand.Execute
' Create the file system object so we can work with files
Dim objFSO : Set objFSO = CreateObject("Scripting.FileSystemObject")
' Create a text file called EmptyGroups.csv. Open for Writing (2) and overwrite the file
' if it exists (True). Use system default text formatting (options include ASCII and Unicode)
Dim objFile : Set objFile = objFSO.OpenTextFile("EmptyGroups.csv", 2, True, 0)
' Write a comma delimited header line to the file
objFile.WriteLine "Name,DN"
' Begin looping through the results
Do Until objRecordSet.EOF
' Write the group name and distinguishedName to the file in the following format:
' "name","CN=name,OU=somewhere,DC=domain,DC=com"
' Note that doubling up quotes escapes the script meaning, "" represents a single quote in a
' string.
objFile.WriteLine """" & objRecordSet.Fields("name").Value & """,""" & _
objRecordSet.Fields("distinguishedName").Value & """"
objRecordSet.MoveNext
Loop
Get-QADGroup -Empty $true -sizelimit 0