Remove all disabled users from distribution lists

Cause of company policy we don’t delete users which are leaving, but we disabled them. The exchange mailbox will be removed after some months. For this incomming mails have to be forwarded to an exchange contact with an unresolvable address, so the sender receives an error message.

Cause of this, we need to remove the disabled users from all distribution list. If not, senders receive error messages each time a message was send to a distribution list with disabled users.

To automate this, i wrote a script. You can filter it by OU and run it first in a display-only mode before you remove the disabled users definitely from all distribution lists.

You can download the script RemoveDisabledUsers.vbs or copy/paste it from here:

' ===========================================================================================
'
'   Script Information
'
'   Title:              RemoveDisabledUsers.vbs
'   Author:             Josh Burkard
'   Date:               23.06.2011
'   Description:        - displays or removes disabled users from all distribution lists
'                       - you can filter the output / removal by User-OU
'                       - to remove users from AD, you need to start the script with an
'                         administrator account
'
'   Startup:            only display disabled users in distribution lists:
'                       --------------------------------------------------
'                            cscript RemoveDisabledUsers.vbs
'
'                       remove disabled users from distribution lists:
'                       ----------------------------------------------
'                            cscript RemoveDisabledUsers.vbs remove
'
' ===========================================================================================

' If enabled users are filtered by OU's:
booFilterOUs = true
' User-OU's (this array will be ignored if booFilterOUs is false):
strOUs = Array (	"OU=OU1,DC=domain,DC=local", _
					"OU=OU2,DC=domain,DC=local", _
					"OU=OU3,DC=domain,DC=local")

if wscript.arguments.length = 0 then
	wscript.echo "Display Mode"
	wscript.echo "To remove this users from distribution lists, start the script with parameter 'remove'."
else
	if lcase(wscript.arguments(0)) = "remove" then
		mode = "remove"
		wscript.echo "Remove Mode"
	else
		wscript.echo "Display Mode"
		wscript.echo "To remove this users from distribution lists, start the script with parameter 'remove'."
	end if
end if
wscript.echo
set conn = createobject("ADODB.Connection")
set com = createobject("ADODB.Command")
set conn1 = createobject("ADODB.Connection")
strConnString = "Data Provider=NONE; Provider=MSDataShape"
conn1.Open strConnString
Set iAdRootDSE = GetObject("LDAP://RootDSE")
strNameingContext = iAdRootDSE.Get("configurationNamingContext")
strDefaultNamingContext = iAdRootDSE.Get("defaultNamingContext")
set objParentRS = createobject("adodb.recordset")
set objChildRS = createobject("adodb.recordset")
strSQL = "SHAPE APPEND" & _
			"  NEW adVarChar(255) AS GRPDisplayName, " & _
			"  NEW adVarChar(255) AS GRPDN, " & _
			" ((SHAPE APPEND  " & _
			"      NEW adVarChar(255) AS USDisplayName, " & _
			"      NEW adVarChar(255) AS USDN, " & _
			"      NEW adVarChar(255) AS USGRPDisplayName, " & _
			"      NEW adVarChar(255) AS USGRPDN " & _
			")" & _
			"      RELATE GRPDN TO USGRPDN) AS rsGRPUS "
objParentRS.LockType = 3
objParentRS.Open strSQL, conn1
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"

' Read distribution lists from AD
GALQueryFilter =  "(&(mailnickname=*)(|(objectCategory=group)))"
strQuery = "<LDAP://"  & strDefaultNamingContext & ">;" & GALQueryFilter & ";distinguishedName,displayname,legacyExchangeDN,homemdb;subtree"
Com.ActiveConnection = Conn
Com.CommandText = strQuery
Set Rs = Com.Execute
while not rs.eof
	objParentRS.addnew
	objParentRS("GRPDisplayName") = rs.fields("displayname")
	objParentRS("GRPDN") = rs.fields("distinguishedName")
	objParentRS.update
	rs.movenext
wend

' Read users from AD
GALQueryFilter = "(&(&(mailnickname=*)(objectCategory=person)(userAccountControl:1.2.840.113556.1.4.803:=2)))"
strQuery = "<LDAP://"  & strDefaultNamingContext & ">;" & GALQueryFilter & ";distinguishedName,displayname,legacyExchangeDN,homemdb;subtree"
Com.ActiveConnection = Conn
Com.CommandText = strQuery
Set Rs1 = Com.Execute
Set objChildRS = objParentRS("rsGRPUS").Value
while not rs1.eof
	if instr(rs1.fields("displayname"),"SystemMailbox{") = 0 then
		set objuser = getobject("LDAP://" & replace(rs1.fields("distinguishedName"),"/","\/"))

		' Check if user is in one of the defined OU's
		If booFilterOUs = true then
			booOU = false
			For Each strOU In strOUs
				If instr(lcase(objuser.distinguishedName), lcase(strOU)) Then
					booOU = true
				End If
			Next
		end if

		If (booOU = true) or (booFilterOUs = false) then
			For each objgroup in objuser.groups
				objChildRS.addnew
				objChildRS("USDisplayName") = rs1.fields("displayname")
				objChildRS("USDN") = rs1.fields("distinguishedName")
				objChildRS("USGRPDisplayName") = objgroup.name
				objChildRS("USGRPDN") = objgroup.distinguishedName
				objChildRS.update
			Next
		End If
	end if
	rs1.movenext
wend

' Output of Groups and Users
objParentRS.MoveFirst
wscript.echo "GroupName,Disabled User's Name"
wscript.echo
Do While Not objParentRS.EOF
	Set objChildRS = objParentRS("rsGRPUS").Value
    if objChildRS.recordCount <> 0 then
		Do While Not objChildRS.EOF
			Wscript.echo objParentRS.fields("GRPDisplayName") & ", " & objChildRS.fields("USDisplayName")

			if mode = "remove" then
				' Removing users from groups
				set objgroup = getobject("LDAP://" & replace(objChildRS.fields("USGRPDN"),"/","\/"))
				Set objUser = getobject("LDAP://" & replace(objChildRS.fields("USDN"),"/","\/"))
				objGroup.Remove(objUser.AdsPath)
				objgroup.setinfo
				wscript.echo "User-Removed"
			end if
			objChildRS.MoveNext
		loop
	end if
	objParentRS.MoveNext
Loop

Comments are closed.