Link to home
Start Free TrialLog in
Avatar of DRRAM
DRRAM

asked on

copy groups AD

Please,
I have searched a script .VBS or .hta to look for the all groups for user account (Active directory) and copy them
I have searched a script where I can put the name of user then by clicking it, It will I give me the groups list where I can copy easily all these groups
Thx

please, Can I specify path of domains in the script because each user (Source;Target) is in two different domains (example below)
for example :
source user is in the domain : "d1.site.com"
Target user is in the domain : "site.com"

I will copy the groups of source user in the first domain (d1.site.com) and paste them in the member groups of the Target user in the second domain (site.com)
 
thx very much
groups--user-to-user-.png
Avatar of DRRAM
DRRAM

ASKER

,,,,?????
Avatar of DRRAM

ASKER

i AM WAITING A RESPONSE
Avatar of RobSampson
Hi DRRAM, if you run this code, it will retrieve the group memberships of the user defined by strOriginalDN, replace the strOldDomain part of the group DN with strNewDomain, and then add the user of strNewDN to those groups.

Regards,

Rob.

strOriginalDN = "CN=User Name,OU=IT Users,OU=Departments,DC=Old,DC=Domain,DC=Com"
strNewDN = "CN=User Name2,OU=IT Users,OU=Departments,DC=New,DC=Domain,DC=Com"
strOldDomain = "DC=Old,DC=Domain,DC=Com"
strNewDomain = "DC=New,DC=Domain,DC=Com"

Set dctGroups = CreateObject("Scripting.Dictionary")

strLDAPPath = "LDAP://" & strOriginalDN
Set objUser = GetObject(strLDAPPath)
If TypeName(objUser.MemberOf) = "String" Then
	dctGroups.Add objUser.MemberOf, 0
Else
	For Each strGroupDN In objUser.MemberOf
		dctGroups.Add strGroupDN, 0
	Next
End If

If dctGroups.Count = 0 Then
	WScript.Echo "No group memberships."
Else
	'WScript.Echo Join(dctGroups.Keys, vbCrLf)
End If

For Each strGroupDN In dctGroups
	On Error Resume Next
	Set objNewUser = GetObject("LDAP://" & strNewDN)
	If Err.Number = 0 Then
		strGroupDN = Replace(strGroupDN, strOldDomain, strNewDomain)
		Set objGroup = GetObject("LDAP://" & strGroupDN)
		If Err.Number = 0 Then
			On Error Resume Next
			objGroup.Add objNewUser.adsPath
			If Err.Number = 0 Then
				WScript.Echo "Added " & objNewUser.distinguishedName & " to " & strGroupDN
			Else
				WScript.Echo "Error adding " & objNewUser.distinguishedName & " to " & strGroupDN & ". Error " & Err.Number & ": " & Err.Description
				Err.Clear
			End If
		Else
			WScript.Echo "Unable to bind to group " & strGroupDN
		End If
	Else
		WScript.Echo "New user of " & strNewDN & " was not found."
	End If
	Err.Clear
	On Error GoTo 0
Next

WScript.Echo vbCrLf & "Finished."

Open in new window

Avatar of DRRAM

ASKER

RobSampson thx
please can you do your script in GUI --> .hta or other interface
easier to change
thx
Hi, well here's a direct port of the script to add a GUI, but no functionality has changed...

Regards,

Rob.

<html>
<head>
<title>Copy Group Memberships</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Copy_Group_Memberships"
     BORDER="thick"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
<script language="VBScript">

Sub Window_OnLoad
	intWidth = 800
	intHeight = 500
	Me.ResizeTo intWidth, intHeight
    Me.MoveTo ((Screen.Width / 2) - (intWidth / 2)),((Screen.Height / 2) - (intHeight / 2))
End Sub

Sub CopyGroups
strOriginalDN = txt_originaluserdn.value
strNewDN = txt_newuserdn.value
strOldDomain = txt_olddomainname.value
strNewDomain = txt_newdomainname.value

Set dctGroups = CreateObject("Scripting.Dictionary")

strLDAPPath = "LDAP://" & strOriginalDN
Set objUser = GetObject(strLDAPPath)
If TypeName(objUser.MemberOf) = "String" Then
	dctGroups.Add objUser.MemberOf, 0
Else
	For Each strGroupDN In objUser.MemberOf
		dctGroups.Add strGroupDN, 0
	Next
End If

If dctGroups.Count = 0 Then
	span_results.innerHTML = span_results.innerHTML & "No group memberships."
Else
	'span_results.innerHTML = span_results.innerHTML & Join(dctGroups.Keys, vbCrLf)
End If

For Each strGroupDN In dctGroups
	On Error Resume Next
	Set objNewUser = GetObject("LDAP://" & strNewDN)
	If Err.Number = 0 Then
		strGroupDN = Replace(strGroupDN, strOldDomain, strNewDomain)
		Set objGroup = GetObject("LDAP://" & strGroupDN)
		If Err.Number = 0 Then
			On Error Resume Next
			objGroup.Add objNewUser.adsPath
			If Err.Number = 0 Then
				span_results.innerHTML = span_results.innerHTML & "<BR>Added " & objNewUser.distinguishedName & " to " & strGroupDN
			Else
				span_results.innerHTML = span_results.innerHTML & "<BR>Error adding " & objNewUser.distinguishedName & " to " & strGroupDN & ". Error " & Err.Number & ": " & Err.Description
				Err.Clear
			End If
		Else
			span_results.innerHTML = span_results.innerHTML & "<BR>Unable to bind to group " & strGroupDN
		End If
	Else
		span_results.innerHTML = span_results.innerHTML & "<BR>New user of " & strNewDN & " was not found."
	End If
	Err.Clear
	On Error GoTo 0
Next

span_results.innerHTML = span_results.innerHTML & "<BR>" & "Finished."
End Sub

</script>
</head>
<body>
	<table width="90%" border="0">
		<tr>
			<td>
				Original User DN:
			</td>
			<td>
				<input type="text" size="70" id="txt_originaluserdn" name="txt_originaluserdn">
			</td>
		</tr>
		<tr>
			<td>
				New User DN:
			</td>
			<td>
				<input type="text" size="70" id="txt_newuserdn" name="txt_newuserdn">
			</td>
		</tr>
		<tr>
			<td>
				Old Domain (FQDN):
			</td>
			<td>
				<input type="text" size="70" id="txt_olddomainname" name="txt_olddomainname">
			</td>
		</tr>
		<tr>
			<td>
				New Domain (FQDN):
			</td>
			<td>
				<input type="text" size="70" id="txt_newdomainname" name="txt_newdomainname">
			</td>
		</tr>
		<tr>
			<td colspan="2">
				<input type="button" id="btn_run" value="Copy Groups" onclick="CopyGroups">
			</td>
		</tr>
		<tr>
			<td colspan="2">
				<span id="span_results"></span>
			</td>
		</tr>
	</table>
</body>
</html>

Open in new window

Avatar of DRRAM

ASKER

RobSampson
Please can you change your script to give us the form model (attached)
thank you very much
model.png
Avatar of DRRAM

ASKER

PLEASE i AM WAITING YOUR RESPONSE
I have changed the look of the HTA.  I cannot use curved borders since I use IE8.

Regards,

Rob.

<html>
<head>
<title>Copy Group Memberships</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Copy_Group_Memberships"
     BORDER="thick"
     SCROLL="no"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
<script language="VBScript">

Sub Window_OnLoad
	intWidth = 1024
	intHeight = 220
	Me.ResizeTo intWidth, intHeight
    Me.MoveTo ((Screen.Width / 2) - (intWidth / 2)),((Screen.Height / 2) - (intHeight / 2))
End Sub

Sub CopyGroups
strOriginalDN = txt_originaluserdn.value
strNewDN = txt_newuserdn.value
strOldDomain = txt_olddomainname.value
strNewDomain = txt_newdomainname.value

Set dctGroups = CreateObject("Scripting.Dictionary")

strLDAPPath = "LDAP://" & strOriginalDN
Set objUser = GetObject(strLDAPPath)
If TypeName(objUser.MemberOf) = "String" Then
	dctGroups.Add objUser.MemberOf, 0
Else
	For Each strGroupDN In objUser.MemberOf
		dctGroups.Add strGroupDN, 0
	Next
End If

If dctGroups.Count = 0 Then
	span_results.innerHTML = span_results.innerHTML & "No group memberships."
Else
	'span_results.innerHTML = span_results.innerHTML & Join(dctGroups.Keys, vbCrLf)
End If

For Each strGroupDN In dctGroups
	On Error Resume Next
	Set objNewUser = GetObject("LDAP://" & strNewDN)
	If Err.Number = 0 Then
		strGroupDN = Replace(strGroupDN, strOldDomain, strNewDomain)
		Set objGroup = GetObject("LDAP://" & strGroupDN)
		If Err.Number = 0 Then
			On Error Resume Next
			objGroup.Add objNewUser.adsPath
			If Err.Number = 0 Then
				span_results.innerHTML = span_results.innerHTML & "<BR>Added " & objNewUser.distinguishedName & " to " & strGroupDN
			Else
				span_results.innerHTML = span_results.innerHTML & "<BR>Error adding " & objNewUser.distinguishedName & " to " & strGroupDN & ". Error " & Err.Number & ": " & Err.Description
				Err.Clear
			End If
		Else
			span_results.innerHTML = span_results.innerHTML & "<BR>Unable to bind to group " & strGroupDN
		End If
	Else
		span_results.innerHTML = span_results.innerHTML & "<BR>New user of " & strNewDN & " was not found."
	End If
	Err.Clear
	On Error GoTo 0
Next

span_results.innerHTML = span_results.innerHTML & "<BR>" & "Finished."
End Sub

</script>
</head>
<body>
	<table width="100%" border="0">
		<tr>
			<td align="center">
				<h3><b>Copy the Groups Users to Users</b></h2>
			</td>
		</tr>
		<tr>
			<td style="border-width: 5px;border-color: #B26F4C;border-style: solid;">
				<table width="90%" border="0">
					<tr>
						<td>
							Original User DN:
						</td>
						<td>
							<input type="text" size="50" id="txt_originaluserdn" name="txt_originaluserdn">
						</td>
						<td>
							Old Domain (FQDN):
						</td>
						<td>
							<select id="lst_olddomain">
								<option id="old1" value="d1.site.com">d1.site.com</option>
								<option id="old2" value="site.com">site.com</option>
							</select>
						</td>
					</tr>
					<tr>
						<td>
							New User DN:
						</td>
						<td>
							<input type="text" size="50" id="txt_newuserdn" name="txt_newuserdn">
						</td>
						<td>
							New Domain (FQDN):
						</td>
						<td>
							<select id="lst_newdomain">
								<option id="new1" value="d1.site.com">d1.site.com</option>
								<option id="new2" value="site.com">site.com</option>
							</select>
						</td>
					</tr>
				</table>
			</td>
		</tr>
		<tr>
			<td align="center">
				<input type="button" id="btn_run" value="Copy Groups" onclick="CopyGroups">
			</td>
		</tr>
		<tr>
			<td>
				<span id="span_results"></span>
			</td>
		</tr>
	</table>
</body>
</html>

Open in new window

Avatar of DRRAM

ASKER

Thx RobSampson
please I have two questions :
1 - can I run the script without making any change
2- Can I convert the script at .exe or encrypt it

thx
>> 1 - can I run the script without making any change

Yes, but first you need to change the two drop down boxes to reflect your domain structure, so for the old domain drop down box change this bit:
							<select id="lst_olddomain">
								<option id="old1" value="d1.site.com">d1.site.com</option>
								<option id="old2" value="site.com">site.com</option>
							</select>

Open in new window


and for the new domain drop down box change this bit:
							<select id="lst_newdomain">
								<option id="new1" value="d1.site.com">d1.site.com</option>
								<option id="new2" value="site.com">site.com</option>
							</select>

Open in new window


Everything else can stay the same.

>> 2- Can I convert the script at .exe or encrypt it
Yes, if you download VBSEdit from www.vbsedit.com and install it, it will also install HTAEdit.  When you open the HTA in HTAEdit, you can click File --> Convert into Executabe...

Regards,

Rob.
Avatar of DRRAM

ASKER

RobSampson
please I have an error after run the script (in attach)
error-grp.png
Sorry ,try this.

Rob.

<html>
<head>
<title>Copy Group Memberships</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Copy_Group_Memberships"
     BORDER="thick"
     SCROLL="no"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
<script language="VBScript">

Sub Window_OnLoad
	intWidth = 1024
	intHeight = 220
	Me.ResizeTo intWidth, intHeight
    Me.MoveTo ((Screen.Width / 2) - (intWidth / 2)),((Screen.Height / 2) - (intHeight / 2))
End Sub

Sub CopyGroups
strOriginalDN = txt_originaluserdn.value
strNewDN = txt_newuserdn.value
strOldDomain = lst_olddomainname.value
strNewDomain = lst_newdomainname.value

Set dctGroups = CreateObject("Scripting.Dictionary")

strLDAPPath = "LDAP://" & strOriginalDN
Set objUser = GetObject(strLDAPPath)
If TypeName(objUser.MemberOf) = "String" Then
	dctGroups.Add objUser.MemberOf, 0
Else
	For Each strGroupDN In objUser.MemberOf
		dctGroups.Add strGroupDN, 0
	Next
End If

If dctGroups.Count = 0 Then
	span_results.innerHTML = span_results.innerHTML & "No group memberships."
Else
	'span_results.innerHTML = span_results.innerHTML & Join(dctGroups.Keys, vbCrLf)
End If

For Each strGroupDN In dctGroups
	On Error Resume Next
	Set objNewUser = GetObject("LDAP://" & strNewDN)
	If Err.Number = 0 Then
		strGroupDN = Replace(strGroupDN, strOldDomain, strNewDomain)
		Set objGroup = GetObject("LDAP://" & strGroupDN)
		If Err.Number = 0 Then
			On Error Resume Next
			objGroup.Add objNewUser.adsPath
			If Err.Number = 0 Then
				span_results.innerHTML = span_results.innerHTML & "<BR>Added " & objNewUser.distinguishedName & " to " & strGroupDN
			Else
				span_results.innerHTML = span_results.innerHTML & "<BR>Error adding " & objNewUser.distinguishedName & " to " & strGroupDN & ". Error " & Err.Number & ": " & Err.Description
				Err.Clear
			End If
		Else
			span_results.innerHTML = span_results.innerHTML & "<BR>Unable to bind to group " & strGroupDN
		End If
	Else
		span_results.innerHTML = span_results.innerHTML & "<BR>New user of " & strNewDN & " was not found."
	End If
	Err.Clear
	On Error GoTo 0
Next

span_results.innerHTML = span_results.innerHTML & "<BR>" & "Finished."
End Sub

</script>
</head>
<body>
	<table width="100%" border="0">
		<tr>
			<td align="center">
				<h3><b>Copy the Groups Users to Users</b></h2>
			</td>
		</tr>
		<tr>
			<td style="border-width: 5px;border-color: #B26F4C;border-style: solid;">
				<table width="90%" border="0">
					<tr>
						<td>
							Original User DN:
						</td>
						<td>
							<input type="text" size="50" id="txt_originaluserdn" name="txt_originaluserdn">
						</td>
						<td>
							Old Domain (FQDN):
						</td>
						<td>
							<select id="lst_olddomain">
								<option id="old1" value="d1.site.com">d1.site.com</option>
								<option id="old2" value="site.com">site.com</option>
							</select>
						</td>
					</tr>
					<tr>
						<td>
							New User DN:
						</td>
						<td>
							<input type="text" size="50" id="txt_newuserdn" name="txt_newuserdn">
						</td>
						<td>
							New Domain (FQDN):
						</td>
						<td>
							<select id="lst_newdomain">
								<option id="new1" value="d1.site.com">d1.site.com</option>
								<option id="new2" value="site.com">site.com</option>
							</select>
						</td>
					</tr>
				</table>
			</td>
		</tr>
		<tr>
			<td align="center">
				<input type="button" id="btn_run" value="Copy Groups" onclick="CopyGroups">
			</td>
		</tr>
		<tr>
			<td>
				<span id="span_results"></span>
			</td>
		</tr>
	</table>
</body>
</html>

Open in new window

Avatar of DRRAM

ASKER

RobSampson
please I have an error after run the script (in attach)
thx for your help
error-grp2.png
Sorry again, change these two lines:
strOldDomain = lst_olddomainname.value
strNewDomain = lst_newdomainname.value

Open in new window


to this:
strOldDomain = lst_olddomain.value
strNewDomain = lst_newdomain.value

Open in new window


Rob.
Avatar of DRRAM

ASKER

Thx RobSampson
please I have a error when i run the script:

"""Line : 29
character : 1
Error : the server is not operational
code  : 0
URL : ....""""

that's what I'll put in line 29:
d1.site.com
or
site.com
or what .....

thx
Now it depends on what you are putting in the Original User DN text box.  In the Original User DN and New User DN boxes, you need to put something like
CN=User1,OU=Office1

and
CN=User2,OU=Office2

you won't need the DC= parts because that's added by the selection you make from the drop down box.

In the drop down boxes, change the code as I mentioned in comment ID: 38366202 so that they display your required domains.

For example, if it says d1.site.com and you have CN=User1,OU=Office1 in the text box, it will connect to the user LDAP://CN=User1,OU=Office1,DC=d1,DC=site,DC=com

If you get the error on line 34 again, it means that you have not entered a correct user path.

Regards,

Rob.

<html>
<head>
<title>Copy Group Memberships</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Copy_Group_Memberships"
     BORDER="thick"
     SCROLL="no"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
<script language="VBScript">

Sub Window_OnLoad
	intWidth = 1024
	intHeight = 220
	Me.ResizeTo intWidth, intHeight
    Me.MoveTo ((Screen.Width / 2) - (intWidth / 2)),((Screen.Height / 2) - (intHeight / 2))
End Sub

Sub CopyGroups
strOriginalDN = txt_originaluserdn.value
strNewDN = txt_newuserdn.value
strOldDomain = "DC=" & Replace(lst_olddomain.value, ".", "DC=")
strNewDomain = "DC=" & Replace(lst_newdomain.value, ".", "DC=")

Set dctGroups = CreateObject("Scripting.Dictionary")

If InStr(strOriginalDN, "DC=") > 0 Then strOriginalDN = Left(strOriginalDN, InStr(strOriginalDN, "DC=") - 1)
If Right(strOriginalDN, 1) <> "," Then strOriginalDN = strOriginalDN & ","
If InStr(strNewDN, "DC=") > 0 Then strNewDN = Left(strNewDN, InStr(strNewDN, "DC=") - 1)
If Right(strNewDN, 1) <> "," Then strNewDN = strNewDN & ","

strLDAPPath = "LDAP://" & strOriginalDN
Set objUser = GetObject(strLDAPPath)
If TypeName(objUser.MemberOf) = "String" Then
	dctGroups.Add objUser.MemberOf, 0
Else
	For Each strGroupDN In objUser.MemberOf
		dctGroups.Add strGroupDN, 0
	Next
End If

If dctGroups.Count = 0 Then
	span_results.innerHTML = span_results.innerHTML & "No group memberships."
Else
	'span_results.innerHTML = span_results.innerHTML & Join(dctGroups.Keys, vbCrLf)
End If

For Each strGroupDN In dctGroups
	On Error Resume Next
	Set objNewUser = GetObject("LDAP://" & strNewDN)
	If Err.Number = 0 Then
		strGroupDN = Replace(strGroupDN, strOldDomain, strNewDomain)
		Set objGroup = GetObject("LDAP://" & strGroupDN)
		If Err.Number = 0 Then
			On Error Resume Next
			objGroup.Add objNewUser.adsPath
			If Err.Number = 0 Then
				span_results.innerHTML = span_results.innerHTML & "<BR>Added " & objNewUser.distinguishedName & " to " & strGroupDN
			Else
				span_results.innerHTML = span_results.innerHTML & "<BR>Error adding " & objNewUser.distinguishedName & " to " & strGroupDN & ". Error " & Err.Number & ": " & Err.Description
				Err.Clear
			End If
		Else
			span_results.innerHTML = span_results.innerHTML & "<BR>Unable to bind to group " & strGroupDN
		End If
	Else
		span_results.innerHTML = span_results.innerHTML & "<BR>New user of " & strNewDN & " was not found."
	End If
	Err.Clear
	On Error GoTo 0
Next

span_results.innerHTML = span_results.innerHTML & "<BR>" & "Finished."
End Sub

</script>
</head>
<body>
	<table width="100%" border="0">
		<tr>
			<td align="center">
				<h3><b>Copy the Groups Users to Users</b></h2>
			</td>
		</tr>
		<tr>
			<td style="border-width: 5px;border-color: #B26F4C;border-style: solid;">
				<table width="90%" border="0">
					<tr>
						<td>
							Original User DN:
						</td>
						<td>
							<input type="text" size="50" id="txt_originaluserdn" name="txt_originaluserdn">
						</td>
						<td>
							Old Domain (FQDN):
						</td>
						<td>
							<select id="lst_olddomain">
								<option id="old1" value="d1.site.com">d1.site.com</option>
								<option id="old2" value="site.com">site.com</option>
							</select>
						</td>
					</tr>
					<tr>
						<td>
							New User DN:
						</td>
						<td>
							<input type="text" size="50" id="txt_newuserdn" name="txt_newuserdn">
						</td>
						<td>
							New Domain (FQDN):
						</td>
						<td>
							<select id="lst_newdomain">
								<option id="new1" value="d1.site.com">d1.site.com</option>
								<option id="new2" value="site.com">site.com</option>
							</select>
						</td>
					</tr>
				</table>
			</td>
		</tr>
		<tr>
			<td align="center">
				<input type="button" id="btn_run" value="Copy Groups" onclick="CopyGroups">
			</td>
		</tr>
		<tr>
			<td>
				<span id="span_results"></span>
			</td>
		</tr>
	</table>
</body>
</html>

Open in new window

Avatar of DRRAM

ASKER

please Rob,
I have get the error on line 34 again, I have entered a correct user path I'm sure.
please have you a solution for is not obligatoy to specify the path In the "Original User DN" and "New User DN" boxes (example : I not need to put something like CN=User1,OU=Office1)

only, I put the user name (Original and New) in boxes and the domains in the combo box
without specify the path of ldap, because if I do that, I am obliged each time to find the path of LDAP users, I have several "OU" of different users of ldap path and I did not not have the same path ldap users in two domains

thank you very much
and sorry because I bothers with script
Avatar of DRRAM

ASKER

Please RobSampson,

Please It is very urgent, I am waiting for your correction
Thx
I will have to rewrite it a bit to have it search the selected domain.   I'll try to get it done today.

Rob.
OK, I've done the re-write.  You should only need to change this section to specify the old domain list box options:
							<select id="lst_olddomain">
								<option id="old1" value="site1dc.site.com">site.com</option>
								<option id="old2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>

Open in new window


and this section to specify the new domain list box options:
							<select id="lst_newdomain">
								<option id="new1" value="site1dc.site.com">site.com</option>
								<option id="new2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>

Open in new window


In both sections, leave the id= as it is, and change the value= to the FQDN of a domain controller on that domain.  This is required to instruct the script to bind to a specific domain controller in that domain for the username searches.  The text before the </option> tag can be anything, but you can leave it as the domain without the domain controller if you want.

Try this.  You only need to enter the username for each user, and it will search for them.

Regards,

Rob.

<html>
<head>
<title>Copy Group Memberships</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Copy_Group_Memberships"
     BORDER="thick"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
<script language="VBScript">

Sub Window_OnLoad
	intWidth = 1024
	intHeight = 500
	Me.ResizeTo intWidth, intHeight
    Me.MoveTo ((Screen.Width / 2) - (intWidth / 2)),((Screen.Height / 2) - (intHeight / 2))
End Sub

Sub CopyGroups
	strOriginalUsername = Trim(txt_originalusername.value)
	strNewUsername = Trim(txt_newusername.value)
	If strOriginalUsername = "" Then
		MsgBox "Please enter an original username."
		Exit Sub
	ElseIf strNewUsername = "" Then
		MsgBox "Please enter a new username."
		Exit Sub
	End If
	
	strOldDomain = lst_olddomain.value
	strNewDomain = lst_newdomain.value
	
	strOriginalDN = Get_LDAP_User_Properties("user", "samAccountName", strOldDomain & "\" & strOriginalUsername, "distinguishedName")
	strNewDN = Get_LDAP_User_Properties("user", "samAccountName", strNewDomain & "\" & strNewUsername, "distinguishedName")
	
	Set dctGroups = CreateObject("Scripting.Dictionary")
	
	strLDAPPath = "LDAP://" & strOriginalDN
	Set objUser = GetObject(strLDAPPath)
	If TypeName(objUser.MemberOf) = "String" Then
		dctGroups.Add objUser.MemberOf, 0
	Else
		For Each strGroupDN In objUser.MemberOf
			dctGroups.Add strGroupDN, 0
		Next
	End If
	
	If dctGroups.Count = 0 Then
		span_results.innerHTML = span_results.innerHTML & "No group memberships."
	Else
		'span_results.innerHTML = span_results.innerHTML & Join(dctGroups.Keys, vbCrLf)
	End If
	
	For Each strGroupDN In dctGroups
		On Error Resume Next
		Set objNewUser = GetObject("LDAP://" & strNewDN)
		If Err.Number = 0 Then
			strGroupDN = Replace(strGroupDN, strOldDomain, strNewDomain)
			Set objGroup = GetObject("LDAP://" & strGroupDN)
			If Err.Number = 0 Then
				On Error Resume Next
				objGroup.Add objNewUser.adsPath
				If Err.Number = 0 Then
					span_results.innerHTML = span_results.innerHTML & "<BR>Added " & objNewUser.distinguishedName & " to " & strGroupDN
				Else
					span_results.innerHTML = span_results.innerHTML & "<BR>Error adding " & objNewUser.distinguishedName & " to " & strGroupDN & ". Error " & Err.Number & ": " & Err.Description
					Err.Clear
				End If
			Else
				span_results.innerHTML = span_results.innerHTML & "<BR>Unable to bind to group " & strGroupDN
			End If
		Else
			span_results.innerHTML = span_results.innerHTML & "<BR>New user of " & strNewDN & " was not found."
		End If
		Err.Clear
		On Error GoTo 0
	Next
	
	span_results.innerHTML = span_results.innerHTML & "<BR>" & "Finished."
End Sub

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

	'MsgBox "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 

</script>
</head>
<body>
	<table width="90%" border="0">
		<tr>
			<td align="center">
				<h3><b>Copy the Groups Users to Users</b></h2>
			</td>
		</tr>
		<tr>
			<td style="border-width: 5px;border-color: #B26F4C;border-style: solid;">
				<table width="90%" border="0">
					<tr>
						<td>
							Original Username (samaccountname):
						</td>
						<td>
							<input type="text" size="50" id="txt_originalusername" name="txt_originalusername">
						</td>
						<td>
							Old Domain (FQDN):
						</td>
						<td>
							<select id="lst_olddomain">
								<option id="old1" value="site1dc.site.com">site.com</option>
								<option id="old2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>
						</td>
					</tr>
					<tr>
						<td>
							New Username (samaccountname):
						</td>
						<td>
							<input type="text" size="50" id="txt_newusername" name="txt_newusername">
						</td>
						<td>
							New Domain (FQDN):
						</td>
						<td>
							<select id="lst_newdomain">
								<option id="new1" value="site1dc.site.com">site.com</option>
								<option id="new2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>
						</td>
					</tr>
				</table>
			</td>
		</tr>
		<tr>
			<td align="center">
				<input type="button" id="btn_run" value="Copy Groups" onclick="CopyGroups">
			</td>
		</tr>
		<tr>
			<td>
				<span id="span_results"></span>
			</td>
		</tr>
	</table>
</body>
</html>

Open in new window

Avatar of DRRAM

ASKER

RobSampson
please I have an error after run the script (in attach)
I changed only the following variable
In id="lst_olddomain"  I replaced
"site1dc.site.com"  by  "site1dc.mydomain.com"
and
"site2dc.d1.site.com"> by   "site2dc.klm.mydomain.com"

In id="lst_newdomain"  I replaced
"site1dc.site.com" by  "site1dc.mydomain.com"
and
"site2dc.d1.site.com"> by   "site2dc.klm.mydomain.com"

Thx
error.bmp
On line 119, you see this:
      'MsgBox "Executing " & strQuery

can you uncomment that by removing the apostrophe at the front, and run it again?  I will need to see the query to see what it's doing.

Rob.
Avatar of DRRAM

ASKER

RobSampson
please message error (in attach)
thx
error2.png
Avatar of DRRAM

ASKER

Please RobSampson,

Please It is very urgent, I am waiting for your correction
Thx
The server in that shows in the message box....can you ping it, by running
ping site2dc.d1.domain.com

Also, under this line:
	adoCommand.Properties("Cache Results") = False

Open in new window


add this and see if it helps:
	Const ADS_SERVER_BIND = &h200
	objConnection.Properties("ADSI Flag") = ADS_SERVER_BIND

Open in new window


Rob.
Avatar of DRRAM

ASKER

Rob please,
error in line 120 :       objConnection.Properties("ADSI Flag") = ADS_SERVER_BIND
(in attach)
thx
err.png
Avatar of DRRAM

ASKER

Please RobSampson,

Please, I am waiting for your correction
Thx
Sorry, not this:
	Const ADS_SERVER_BIND = &h200
	objConnection.Properties("ADSI Flag") = ADS_SERVER_BIND 

Open in new window


It should actually be this:
	Const ADS_SERVER_BIND = &h200
	adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND 

Open in new window


But, you also didn't answer whether you can ping that server name exactly as it is in the screenshot from post ID: 38401507

If you can't ping that, you will need to put in the address of a server that you can ping.

Regards,

Rob.
Avatar of DRRAM

ASKER

Rob please,
error in line 120 : Provider does not support the property

line 120 is : "      adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND "

yes I can ping the name and the @ IP of a server.

thx
This works for me, although it's not cross-domain

<html>
<head>
<title>Copy Group Memberships</title>
<HTA:APPLICATION 
     APPLICATIONNAME="Copy_Group_Memberships"
     BORDER="thick"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
     ID="oHTA"
>
<script language="VBScript">

Sub Window_OnLoad
	intWidth = 1024
	intHeight = 500
	Me.ResizeTo intWidth, intHeight
    Me.MoveTo ((Screen.Width / 2) - (intWidth / 2)),((Screen.Height / 2) - (intHeight / 2))
End Sub

Sub CopyGroups
	strOriginalUsername = Trim(txt_originalusername.value)
	strNewUsername = Trim(txt_newusername.value)
	If strOriginalUsername = "" Then
		MsgBox "Please enter an original username."
		Exit Sub
	ElseIf strNewUsername = "" Then
		MsgBox "Please enter a new username."
		Exit Sub
	End If
	
	strOldDomain = lst_olddomain.value
	strNewDomain = lst_newdomain.value
	
	strOriginalDN = Get_LDAP_User_Properties("user", "samAccountName", strOldDomain & "\" & strOriginalUsername, "distinguishedName")
	strNewDN = Get_LDAP_User_Properties("user", "samAccountName", strNewDomain & "\" & strNewUsername, "distinguishedName")
	
	Set dctGroups = CreateObject("Scripting.Dictionary")
	
	strLDAPPath = "LDAP://" & strOriginalDN
	Set objUser = GetObject(strLDAPPath)
	If TypeName(objUser.MemberOf) = "String" Then
		dctGroups.Add objUser.MemberOf, 0
	Else
		For Each strGroupDN In objUser.MemberOf
			dctGroups.Add strGroupDN, 0
		Next
	End If
	
	If dctGroups.Count = 0 Then
		span_results.innerHTML = span_results.innerHTML & "No group memberships."
	Else
		'span_results.innerHTML = span_results.innerHTML & Join(dctGroups.Keys, vbCrLf)
	End If
	
	For Each strGroupDN In dctGroups
		On Error Resume Next
		Set objNewUser = GetObject("LDAP://" & strNewDN)
		If Err.Number = 0 Then
			strGroupDN = Replace(strGroupDN, strOldDomain, strNewDomain)
			Set objGroup = GetObject("LDAP://" & strGroupDN)
			If Err.Number = 0 Then
				On Error Resume Next
				objGroup.Add objNewUser.adsPath
				If Err.Number = 0 Then
					span_results.innerHTML = span_results.innerHTML & "<BR>Added " & objNewUser.distinguishedName & " to " & strGroupDN
				Else
					span_results.innerHTML = span_results.innerHTML & "<BR>Error adding " & objNewUser.distinguishedName & " to " & strGroupDN & ". Error " & Err.Number & ": " & Err.Description
					Err.Clear
				End If
			Else
				span_results.innerHTML = span_results.innerHTML & "<BR>Unable to bind to group " & strGroupDN
			End If
		Else
			span_results.innerHTML = span_results.innerHTML & "<BR>New user of " & strNewDN & " was not found."
		End If
		Err.Clear
		On Error GoTo 0
	Next
	
	span_results.innerHTML = span_results.innerHTML & "<BR>" & "Finished."
End Sub

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"
	Const ADS_SERVER_BIND = &h200
	adoConnection.Properties("ADSI Flag") = ADS_SERVER_BIND
	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

	'MsgBox "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 

</script>
</head>
<body>
	<table width="90%" border="0">
		<tr>
			<td align="center">
				<h3><b>Copy the Groups Users to Users</b></h2>
			</td>
		</tr>
		<tr>
			<td style="border-width: 5px;border-color: #B26F4C;border-style: solid;">
				<table width="90%" border="0">
					<tr>
						<td>
							Original Username (samaccountname):
						</td>
						<td>
							<input type="text" size="50" id="txt_originalusername" name="txt_originalusername">
						</td>
						<td>
							Old Domain (FQDN):
						</td>
						<td>
							<select id="lst_olddomain">
								<option id="old1" value="site1dc.site.com">site.com</option>
								<option id="old2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>
						</td>
					</tr>
					<tr>
						<td>
							New Username (samaccountname):
						</td>
						<td>
							<input type="text" size="50" id="txt_newusername" name="txt_newusername">
						</td>
						<td>
							New Domain (FQDN):
						</td>
						<td>
							<select id="lst_newdomain">
								<option id="new1" value="site1dc.site.com">site.com</option>
								<option id="new2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>
						</td>
					</tr>
				</table>
			</td>
		</tr>
		<tr>
			<td align="center">
				<input type="button" id="btn_run" value="Copy Groups" onclick="CopyGroups">
			</td>
		</tr>
		<tr>
			<td>
				<span id="span_results"></span>
			</td>
		</tr>
	</table>
</body>
</html>

Open in new window

Avatar of DRRAM

ASKER

Rob please,
please look in attached
thx
error3.png
Remember you will change these lines for the Old Domain drop down box:
							<select id="lst_olddomain">
								<option id="old1" value="site1dc.site.com">site.com</option>
								<option id="old2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>

Open in new window


and these lines for the New Domain drop down box:
							<select id="lst_newdomain">
								<option id="new1" value="site1dc.site.com">site.com</option>
								<option id="new2" value="site2dc.d1.site.com">d1.site.com</option>
							</select>

Open in new window


so that what is in the value= property of each option is the FQDN of the domain controller for each domain.

Rob.
Avatar of DRRAM

ASKER

I  test the script on 2012-09-19 at 22:08:08ID: 38416481
my domain 1 is : d1.site.com
my domain 2 is : site.com
I have test :  the user
source user "test1" is in the domain : "d1.site.com"
Target user "test2" is in the domain : "d1.site.com"

the "MsgBox "Executing " & strQuery" done  (in attached) please look
after click ok
the error message is
line : 123 -->Set adoRecordset = adoCommand.Execute
error : reference was returned by the server

thx
error4.png
This part of the message box:
<LDAP://d1.site.com/DC=site,DC=com>

is the key part, which must bind to your domain controller in that domain.

It gets generated from the
value="d1.site.com"

part in each option in each list box.

I think you might be missing the domain controller name for that domain though.  If you had
value="domaincontroller1.d1.site.com"

It would show
<LDAP://domaincontroller1.d1.site.com/DC=d1,DC=site,DC=com>

What it does it use the value= name as the FQDN of the domain controller to bind to, and generates the DC parts as the domain suffix for the host name.

So, if you make sure that the value= name is just a DCs FQDN, it should bind to it.

Rob.
Avatar of DRRAM

ASKER

very very good
I had run the script on 2012-09-19 at 22:08:08ID: 38416481 --> and it worked

By using the script I have copied all groups of test1 (user1) to test2(user2) in the same domain"d1.site.com"

Please does this script work from one domain to another?
for example :
 I want to copy all groups of test1 (user1) to test4(user4) in the different domain ("d1.site.com" and site.com)
>> Please does this script work from one domain to another?

I think it should, but I don't have multiple domains, so I can't test it.
But if you select each corresponding domain after you put the right values in the drop down boxes, it should work.

Rob.
Avatar of DRRAM

ASKER

Perfect Rob, I executed the script I have not error
I have copied all groups of test1 (user1) to test4(user4) in the different domain ("d1.site.com" and site.com)

the last thing I ask you please,
Can you simplify the same script on 2012-09-19 at 22:08:08ID: 38416481
"""model in attached""", for I can copy all groups of test1 (user1) to test2(user2) in the same domain"d1.site.com" only..
thank you very much
model2.png
ASKER CERTIFIED SOLUTION
Avatar of RobSampson
RobSampson
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of DRRAM

ASKER

Perfect Rob,
thank you very much