View Single Post
Old 06-04-2008   #2 (permalink)
Richard Mueller [MVP]


 
 

Re: Script to remove list of users from groups...

Ron wrote:
Quote:

> Complete noob.... Has found a script that will remove a user from all
> Active
> Directory groups. Trouble is, it only removes a single user. I have csvde
> output of a list of user DNs that I want to remove from all groups. If I
> save
> this list of DNs as C:\DNs.txt How can I get the script to read the list
> and
> remove from groups?
>
> This is script I have (with my comments)
> =====================begin================
> On Error Resume Next
>
> Const ADS_PROPERTY_DELETE = 4
> Const E_ADS_PROPERTY_NOT_FOUND = &h8000500D
>
> 'I guess I need to change something here:
> Set objUser = GetObject _
> ("LDAP://cn=MyerKen,ou=Management,dc=NA,dc=fabrikam,dc=com")
> arrMemberOf = objUser.GetEx("memberOf")
>
> If Err.Number = E_ADS_PROPERTY_NOT_FOUND Then
> WScript.Echo "This account is not a member of any security groups."
> WScript.Quit
> End If
>
> ' I guess I also need to change something in the next few lines also....?
> For Each Group in arrMemberOf
> Set objGroup = GetObject("LDAP://" & Group)
> objGroup.PutEx ADS_PROPERTY_DELETE, _
> "member",
> Array("cn=MyerKen,ou=Management,dc=NA,dc=fabrikam,dc=com")
> objGroup.SetInfo
> Next
> ==================END====================
>
> Many thanks for your help!
>
First, I would never use "On Error Resume Next", unless I anticipated an
error on a particular statement. If I used it, it would be for the one
statement I expected could raise an error, then I would handle the error and
restore normal error handling. Otherwise troubleshooting is very difficult.
Your example actually requires "On Error Resume Next" because of the method
used to determine group memberships, but only one statement needs it. Next,
I don't like modifying the member and memberOf attributes directly, as they
are linked. I much prefer using the Add and Remove methods of the group
object, which are designed for this purpose. This also means no error is
raised if memberOf is empty. The basic VBScript program I would use to
remove a user from all groups would be:
=========
' Specify the Distinguishd Name of the user.
strUserDN = "cn=JimSmith,ou=Sales,ou=West,dc=MyDomain,dc=com"

' Bind to the user object.
Set objUser = GetObject("LDAP://" & strUserDN)

' Enumerate all direct group memberships (except the "primary" group).
For Each objGroup In objUser.Groups
' Remove the user from the group.
objGroup.Remove(objUser.AdsPath)
Next
========
Finally, to do this for all users listed in a group you can use the
FileSystemObject to read the file one line at a time. You would code similar
to above for each name. For example:
=============
Const ForReading = 1

' Specify the text file of user names.
strFilePath = "c:\Scripts\UserList.txt"

' Open the file for read access.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFilePath, ForReading)

' Read each line of the file.
Do Until objFile.AtEndOfStream
strUserDN = Trim(objFile.ReadLine)
' Skip blank lines.
If (strUserDN <> "") Then
' Bind to the user object.
Set objUser = GetObject("LDAP://" & strUserDN)

' Enumerate all direct group memberships (except the "primary"
group).
For Each objGroup In objUser.Groups
' Remove the user from the group.
objGroup.Remove(objUser.AdsPath)
Next
End If
Loop

' Clean up.
objFile.Close
=========
Then finally, my guess is you don't have a file with the user Distinguished
Names. You probably have a file with their "pre-Windows 2000 logon" names,
also called the NT names of the users. This is the value of the
sAMAccountName attribute of the user object. In this case you can use the
NameTranslate object to convert the NT names to Distinguished Names. For
information on using NameTranslate see this link:

http://www.rlmueller.net/NameTranslateFAQ.htm

Now the program could be:
=========
Const ForReading = 1

' Constants for the NameTranslate object.
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1


' Specify the text file of user names.
strFilePath = "c:\Scripts\UserList.txt"

' Determine DNS name of domain from RootDSE.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use the NameTranslate object to find the NetBIOS domain name from the
' DNS domain name.
Set objTrans = CreateObject("NameTranslate")
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain
strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
' Remove trailing backslash.
strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)



' Open the file for read access.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFilePath, ForReading)

' Read each line of the file.
Do Until objFile.AtEndOfStream
strNTName = Trim(objFile.ReadLine)
' Skip blank lines.
If (strNTName <> "") Then
' Use the Set method to specify the NT format of the name.
objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strNTName
' Use the Get method to retrieve the Distinguished Name.
strUserDN = objTrans.Get(ADS_NAME_TYPE_1779)

' Bind to the user object.
Set objUser = GetObject("LDAP://" & strUserDN)

' Enumerate all direct group memberships (except the "primary"
group).
For Each objGroup In objUser.Groups
' Remove the user from the group.
objGroup.Remove(objUser.AdsPath)
Next
End If
Loop

' Clean up.
objFile.Close
==
I didn't test the above, so I could have typos, but most is copied from my
web site.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--


My System SpecsSystem Spec