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?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
Will SzymkowskiSenior Solution ArchitectCommented:
If you can do it via powershell i can assist.

Will.
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

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
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
johnnyjonathanAuthor Commented:
AMAZING! Thank you so much!
0
RobSampsonCommented:
No problem, sorry that took a while. Thanks for the grade.

Rob.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.