Input username and add it to an AD group using VBS

Hi,
I have a text file with a username (Not full DN) and I need a vbscript to read that text file (it only has the username of a single user).  and add it to a specific group.

Any advise please?
johnnyjonathanAsked:
Who is Participating?
 
RobSampsonCommented:
Oh dear.  Now I've tested it properly, and discovered a couple of logic errors.  Please try this revision.

strUsers = "users.txt"
strGroupName = "GroupName"

Const ADS_PROPERTY_APPEND = 3
Set objFSO = CreateObject("Scripting.FileSystemObject")
strGroupDN = Get_LDAP_User_Properties("group", "cn", strGroupName, "distinguishedName")
If strGroupDN = "" Then
	WScript.Echo "Could not find group " & strGroupName & "."
Else
	Set objGroup = GetObject("LDAP://" & strGroupDN)
	Const ForReading = 1
	Set objUsers = objFSO.OpenTextFile(strUsers, ForReading, False)
	While Not objUsers.AtEndOfStream
		strUserName = objUsers.ReadLine
		strUserDN = ""
		strUserDN = Get_LDAP_User_Properties("user", "samAccountName", strUserName, "distinguishedName")
		If strUserDN <> "" Then
			objGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(strUserDN)
			On Error Resume Next
			objGroup.SetInfo
			If Err.Number = 0 Then
				WScript.Echo strUserName & " was added to the group " & strGroupName
			Else
				WScript.Echo strUserName & " is already a member of the group " & strGroupName
			End If
			Err.Clear
			On Error Goto 0
		Else
			WScript.Echo "Could not find " & strUserName & ". User will not be added to the group."
		End If
	Wend
	objUsers.Close
	WScript.Echo vbcrlf & "Finished"
End If

Function Get_LDAP_User_Properties(strObjectType, strSearchField, strObjectToGet, strCommaDelimProps)
	
	If InStr(strObjectToGet, "\") > 0 Then
		arrGroupBits = Split(strObjectToGet, "\")
		strDC = arrGroupBits(0)
		strDNSDomain = strDC & "/" & "DC=" & Replace(Mid(strDC, InStr(strDC, ".") + 1), ".", ",DC=")
		strObjectToGet = arrGroupBits(1)
	Else
		Set objRootDSE = GetObject("LDAP://RootDSE")
		strDNSDomain = objRootDSE.Get("defaultNamingContext")
	End If

	strBase = "<LDAP://" & strDNSDomain & ">"
	' Setup ADO objects.
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	adoCommand.ActiveConnection = adoConnection

 
	' Filter on user objects.
	'strFilter = "(&(objectCategory=person)(objectClass=user))"
	strFilter = "(&(objectClass=" & strObjectType & ")(" & strSearchField & "=" & strObjectToGet & "))"

	' Comma delimited list of attribute values to retrieve.
	strAttributes = strCommaDelimProps
	arrProperties = Split(strCommaDelimProps, ",")

	' Construct the LDAP syntax query.
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 100
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False

	WScript.Echo ""
	WScript.Echo "Executing " & strQuery
	' Run the query.
	Set adoRecordset = adoCommand.Execute
	' Enumerate the resulting recordset.
	Do Until adoRecordset.EOF
	    ' Retrieve values and display.    
	    For intCount = LBound(arrProperties) To UBound(arrProperties)
	    	If strDetails = "" Then
	    		strDetails = adoRecordset.Fields(intCount).Value
	    	Else
	    		strDetails = strDetails & VbCrLf & adoRecordset.Fields(intCount).Value
	    	End If
	    Next
	    ' Move to the next record in the recordset.
	    adoRecordset.MoveNext
	Loop

	' Clean up.
	adoRecordset.Close
	adoConnection.Close
	Get_LDAP_User_Properties = strDetails

End Function 

Open in new window


Sorry about that.

Regards,

Rob.
0
 
Tony MassaCommented:
See here for more on using "NameTranslate" to get distinguished AD name from sAMAccountname:  http://www.rlmueller.net/NameTranslateFAQ.htm
Const ForReading = 1, ForWriting = 2, ForAppending = 8

'*********************************
'Define the variables here:
'*********************************
Set objGroup = GetObject _
   ("LDAP://cn=Sales Group,ou=Groups,ou=Sales,dc=yourAD,dc=domain,dc=com") 
UserList = "C:\Path\to\my\input.txt"
strDomain = "DOMAIN-NETBIOS"
'*********************************

Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(UserList, ForReading, True)

Do While f.AtEndOfStream <> True
	strNTName = f.ReadLine
	On Error Resume Next
	' Use the NameTranslate object to convert the NT user name to the
	' Distinguished Name required for the LDAP provider.
	Set objTrans = CreateObject("NameTranslate")
	
	' Initialize NameTranslate by locating the Global Catalog.
	objTrans.Init ADS_NAME_INITTYPE_GC, ""
	' Use the Set method to specify the NT format of the object name.
	objTrans.Set ADS_NAME_TYPE_NT4, strDomain & "\" & strNTName
	
	' Use the Get method to retrieve the RPC 1779 Distinguished Name.
	strUserDN = objTrans.Get(ADS_NAME_TYPE_1779)
	Set objUser = GetObject("LDAP://" & strUserDN)
	
	'Add user to the group
	objGroup.Add(objUser.ADsPath)
	
Loop

Wscript.Echo "Done"

Open in new window

0
 
johnnyjonathanAuthor Commented:
Hi,
Thanks, i tried that, edited with the group DN, the domain name and the text file but got an error (null) in line 23 (i removed the On error resume next)
0
Making Bulk Changes to Active Directory

Watch this video to see how easy it is to make mass changes to Active Directory from an external text file without using complicated scripts.

 
Will SzymkowskiSenior Solution ArchitectCommented:
If you can do it via powershell i can assist.

Will.
0
 
johnnyjonathanAuthor Commented:
Must use it in VBS :(
0
 
Tony MassaCommented:
Can you add a line:
WScript.Echo strDomain & "\" & strNTName

Open in new window

on line 18?  Just need to make sure the AD domain and user account information is valid.
0
 
johnnyjonathanAuthor Commented:
i see the username properly but the addition to the group isn't actually working
0
 
RobSampsonCommented:
Hi, I haven't tested this at all, but I think it should work.  You will need to change the name of the users.txt file, and the name of the group.

Regards,

Rob.

strUsers = "users.txt"
strGroupName = "YourGroupName"

Const ADS_PROPERTY_APPEND = 3
strGroupDN = Get_LDAP_User_Properties("group", "cn", strGroupName, "distinguishedName")
If strGroupDN <> "" Then
Else
	WScript.Echo "Could not find group " & strGroupName & "."
Else
	Set objGroup = GetObject("LDAP://" & strGroupDN)
	Const ForReading = 1
	Set objUsers = objFSO.OpenTextFile(strUsers, ForReading, False)
	While Not objUsers.AtEndOfStream
		strUserName = objUsers.ReadLine
		strUserDN = ""
		strUserDN = Get_LDAP_User_Properties("user", "samAccountName", strUserName, "distinguishedName")
		If strUserDN <> "" Then
			objGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(strUserDN)
			On Error Resume Next
			objGroup.SetInfo
			If Err.Number = 0 Then
				WScript.Echo strUserName & " was added to the group " & strGroupName
			Else
				WScript.Echo strUserName & " is already a member of the group " & strGroupName
			End If
			Err.Clear
			On Error Goto 0
		Else
			WScript.Echo "Could not find " & strUserName & ". User will not be added to the group."
		End If
	Wend
	objUsers.Close
	WScript.Echo vbcrlf & "Finished"
End If

Function Get_LDAP_User_Properties(strObjectType, strSearchField, strObjectToGet, strCommaDelimProps)
	
	If InStr(strObjectToGet, "\") > 0 Then
		arrGroupBits = Split(strObjectToGet, "\")
		strDC = arrGroupBits(0)
		strDNSDomain = strDC & "/" & "DC=" & Replace(Mid(strDC, InStr(strDC, ".") + 1), ".", ",DC=")
		strObjectToGet = arrGroupBits(1)
	Else
		Set objRootDSE = GetObject("LDAP://RootDSE")
		strDNSDomain = objRootDSE.Get("defaultNamingContext")
	End If

	strBase = "<LDAP://" & strDNSDomain & ">"
	' Setup ADO objects.
	Set adoCommand = CreateObject("ADODB.Command")
	Set adoConnection = CreateObject("ADODB.Connection")
	adoConnection.Provider = "ADsDSOObject"
	adoConnection.Open "Active Directory Provider"
	adoCommand.ActiveConnection = adoConnection

 
	' Filter on user objects.
	'strFilter = "(&(objectCategory=person)(objectClass=user))"
	strFilter = "(&(objectClass=" & strObjectType & ")(" & strSearchField & "=" & strObjectToGet & "))"

	' Comma delimited list of attribute values to retrieve.
	strAttributes = strCommaDelimProps
	arrProperties = Split(strCommaDelimProps, ",")

	' Construct the LDAP syntax query.
	strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
	adoCommand.CommandText = strQuery
	adoCommand.Properties("Page Size") = 100
	adoCommand.Properties("Timeout") = 30
	adoCommand.Properties("Cache Results") = False

	WScript.Echo ""
	WScript.Echo "Executing " & strQuery
	' Run the query.
	Set adoRecordset = adoCommand.Execute
	' Enumerate the resulting recordset.
	Do Until adoRecordset.EOF
	    ' Retrieve values and display.    
	    For intCount = LBound(arrProperties) To UBound(arrProperties)
	    	If strDetails = "" Then
	    		strDetails = adoRecordset.Fields(intCount).Value
	    	Else
	    		strDetails = strDetails & VbCrLf & adoRecordset.Fields(intCount).Value
	    	End If
	    Next
	    ' Move to the next record in the recordset.
	    adoRecordset.MoveNext
	Loop

	' Clean up.
	adoRecordset.Close
	adoConnection.Close
	Get_LDAP_User_Properties = strDetails

End Function 

Open in new window

0
 
johnnyjonathanAuthor Commented:
Hi Rob,
Thanks, i'm getting this error though -

Line 9
Error: Expected 'End'
?
0
 
RobSampsonCommented:
Oops. Please remove the Else from line 7 above.
0
 
johnnyjonathanAuthor Commented:
Thanks!
Did it and got the following -

2 Echos -

1. ---------------------------
Windows Script Host
---------------------------
Executing <LDAP://DC=DOMAINNAME,DC=COM>;(&(objectClass=TESTGROUP)(cn=GROUPNAME));distinguishedName;subtree
---------------------------
OK  
---------------------------


2. ---------------------------
Windows Script Host
---------------------------
Could not find group TESTGROUP.
---------------------------
OK  
---------------------------
0
 
RobSampsonCommented:
I'm confused why objectClass is TESTGROUP? Did you change line 5? You don't need to change that. The only lines you need to change are lines 1 and 2.  Line 5 makes an query for "group" object types, with the name of your strGroupName.

Rob.
0
 
johnnyjonathanAuthor Commented:
Your right!
my mistake, this is the notification -

---------------------------
Windows Script Host
---------------------------
Executing <LDAP://DC=DOMAINNAME,DC=COM>;(&(objectClass=group)(cn=TESTGROUP));distinguishedName;subtree
---------------------------
OK  
---------------------------
0
 
Tony MassaCommented:
You can have multiple AD groups with the same CN (or RDN) so be careful when using this attribute to find the group.
0
 
RobSampsonCommented:
The error is suggesting that no group is found at all, using the CN specified by strGroupName.  Can you try it with strGroupName set to a group that has no special characters, and maybe not even spaces?

If you have the Attribute Editor tab in your ADUC console, can you verify the CN from the CN field or the DistinguishedName field?

Rob.
0
 
johnnyjonathanAuthor Commented:
I tried it with a group without special characters (not even a space) and i still got the same.
the executing output seems strange to me it isn't the actual DN of the group.

Any simpler way maybe to do it in PS if VBS isn't working?
0
 
johnnyjonathanAuthor Commented:
AMAZING! Thank you so much!
0
 
RobSampsonCommented:
No problem, sorry that took a while. Thanks for the grade.

Rob.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.