Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

need scripting assistance moving computers to a specific OU

Posted on 2011-02-28
17
503 Views
Last Modified: 2012-05-11
hello, looking for a  script that will accomplish the following:

- ping all of the computers in the default "Corp Computers" OU, and based on their IP address move the computer objects to the appropriate OU.

for example, we have broken down our Computer object structure to be: EMEA / NASA / APEC etc
i have a list of subnets defined in sites and services, the script logic would need to reference an list that would determine what regional OU to move the computer to.

currently this is a manual process. thanks in advance,

S.
0
Comment
Question by:siber1
  • 8
  • 8
17 Comments
 
LVL 12

Expert Comment

by:Navdeep
ID: 35002461
Hi,

what are the network subnet that you are using?
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 35002560
Hi, this should work for you.  I don't know how to read the subnets from the Sites and Services, but if you replicate the structure in the arrSubnets array in this code, it should still work.

Make sure all of your OU paths are correct, and you don't need to specify the DC parts.

Regards,

Rob.
Set objSubnets = CreateObject("Scripting.Dictionary")

strOU = "OU=Corp Computers"
objSubnets.Add "192.168.10.", "OU=EMEA,OU=Corp Computers,"
objSubnets.Add "192.168.20.", "OU=NASA,OU=Corp Computers,"
objSubnets.Add "192.168.30.", "OU=APEC,OU=Corp Computers,"

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 

Set objRootDSE = GetObject("LDAP://RootDSE")
strDomain = objRootDSE.Get("defaultNamingContext")

If strOU <> "" Then
	If Right(strOU, 1) <> "," Then strOU = strOU & ","
End If

objCommand.CommandText = "SELECT adsPath,name FROM 'LDAP://" & strOU & strDomain & "' WHERE objectClass='computer'"  

Set objRecordSet = objCommand.Execute

While Not objRecordSet.EOF
	strIP = ResolveIP(objRecordSet.Fields("name").Value)
	If InStr(strIP, ".") > 0 Then
		strSubNet = Left(strIP, InStrRev(strIP, "."))
		If objSubnets.Exists(strSubNet) = True Then
			On Error Resume Next
			Set objDestinationOU = GetObject("LDAP://" & objSubnets(strSubNet) & strDomain)
			If Err.Number = 0 Then
				intReturn = objOU.MoveHere(objRecordSet.Fields("adsPath").Value, vbNullString)
				If Err.Number <> 0 Or intReturn <> 0 Then
					MsgBox "Error moving " & objRecordSet.Fields("name").Value & " to LDAP://" & objSubnets(strSubNet) & strDomain & VbCrLf & "Error " & Err.Number & ": " & Err.Description
				End If
			Else
				MsgBox "Error binding to LDAP://" & objSubnets(strSubNet) & strDomain & VbCrLf & "Error " & Err.Number & ": " & Err.Description
			End If
			Err.Clear
			On Error GoTo 0
		End If
	End If
	objRecordSet.MoveNext
Wend

Function ResolveIP(computerName)
	Set objShell = CreateObject("WScript.Shell")
	Set objExec = objShell.Exec("ping " & computerName & " -n 1")
	strOutput = objExec.StdOut.ReadAll
	Set RegEx = New RegExp
	RegEx.Pattern = "\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]"
	RegEx.Global = True
	If RegEx.Test(strOutput) Then
		ResolveIP = RegEx.Execute(strOutput)(0).Submatches(0)
	Else
		ResolveIP = "IP Address could not be resolved"
	End If
End Function

Open in new window

0
 

Author Comment

by:siber1
ID: 35002619
thanks Rob! this is fantastic. I will test this later this afternoon in our lab to validate.
0
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
LVL 65

Expert Comment

by:RobSampson
ID: 35002771
Sure.  Let me know how you go.

Regards,

Rob.
0
 

Author Comment

by:siber1
ID: 35003646
Hi Rob, just ran the script in my lab. [after substituting in my lab OU's]
the error i get is:
Error moving LabPC01
LDAP path
Error 424: Object required

0
 
LVL 65

Expert Comment

by:RobSampson
ID: 35003685
Oh....typo....please change this line:
                        intReturn = objOU.MoveHere(objRecordSet.Fields("adsPath").Value, vbNullString)

to this
                        intReturn = objDestinationOU.MoveHere(objRecordSet.Fields("adsPath").Value, vbNullString)


Regards,

Rob.
0
 

Author Comment

by:siber1
ID: 35003702
Hi Rob, made the change, now getting this error:
Error 450: Wrong number of arguments or invalid property assignment
0
 

Author Comment

by:siber1
ID: 35003716
Rob, although it generates this error 450 as stated above, it does move the first Computer in that OU. then skips the rest.
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 35003725
Hmmm, I can't test it at the moment.  See if this works better.

Regards,

Rob.
Set objSubnets = CreateObject("Scripting.Dictionary")

strOU = "OU=Corp Computers"
objSubnets.Add "192.168.10.", "OU=EMEA,OU=Corp Computers,"
objSubnets.Add "192.168.20.", "OU=NASA,OU=Corp Computers,"
objSubnets.Add "192.168.30.", "OU=APEC,OU=Corp Computers,"

Const ADS_SCOPE_SUBTREE = 2

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE 

Set objRootDSE = GetObject("LDAP://RootDSE")
strDomain = objRootDSE.Get("defaultNamingContext")

If strOU <> "" Then
	If Right(strOU, 1) <> "," Then strOU = strOU & ","
End If

objCommand.CommandText = "SELECT adsPath,name FROM 'LDAP://" & strOU & strDomain & "' WHERE objectClass='computer'"  

Set objRecordSet = objCommand.Execute

While Not objRecordSet.EOF
	strIP = ResolveIP(objRecordSet.Fields("name").Value)
	If InStr(strIP, ".") > 0 Then
		strSubNet = Left(strIP, InStrRev(strIP, "."))
		If objSubnets.Exists(strSubNet) = True Then
			On Error Resume Next
			Set objDestinationOU = GetObject("LDAP://" & objSubnets(strSubNet) & strDomain)
			If Err.Number = 0 Then
				intReturn = objDestinationOU.MoveHere(objRecordSet.Fields("adsPath").Value)
				If Err.Number <> 0 Or intReturn <> 0 Then
					MsgBox "Error moving " & objRecordSet.Fields("name").Value & " to LDAP://" & objSubnets(strSubNet) & strDomain & VbCrLf & "Error " & Err.Number & ": " & Err.Description
					Err.Clear
				End If
			Else
				MsgBox "Error binding to LDAP://" & objSubnets(strSubNet) & strDomain & VbCrLf & "Error " & Err.Number & ": " & Err.Description
				Err.Clear
			End If
			On Error GoTo 0
		End If
	End If
	objRecordSet.MoveNext
Wend

Function ResolveIP(computerName)
	Set objShell = CreateObject("WScript.Shell")
	Set objExec = objShell.Exec("ping " & computerName & " -n 1")
	strOutput = objExec.StdOut.ReadAll
	Set RegEx = New RegExp
	RegEx.Pattern = "\[(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]"
	RegEx.Global = True
	If RegEx.Test(strOutput) Then
		ResolveIP = RegEx.Execute(strOutput)(0).Submatches(0)
	Else
		ResolveIP = "IP Address could not be resolved"
	End If
End Function

Open in new window

0
 

Author Comment

by:siber1
ID: 35003782
same error on that one, however the computer object is not moved. The first revision would give the error: wrong number of arguments or invalid property assignment, however it does cycle through and move the computers.

thx

0
 
LVL 65

Accepted Solution

by:
RobSampson earned 500 total points
ID: 35003804
Ok, I've dug up old code, and instead of this:

                        intReturn = objDestinationOU.MoveHere(objRecordSet.Fields("adsPath").Value)
                        If Err.Number <> 0 Or intReturn <> 0 Then

I have used
                        objDestinationOU.MoveHere objRecordSet.Fields("adsPath").Value, vbNullString
                        If Err.Number <> 0 Then


Try that.

Regards,

Rob.
0
 

Author Comment

by:siber1
ID: 35003808
Actually Rob, is there a way to supress that pop-up error, the earlier revision with that line you had me correct, actually does work perfectly, except for that error pop-up that i keep getting after each computer in encounters.
0
 

Author Closing Comment

by:siber1
ID: 35003833
That did the trick Rob. BRILLIANT!
thanks so much. Full points, wish i had more to give  : )
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 35003835
Sure, if you want to, just change
MsgBox "Error moving "
to
'MsgBox "Error moving "

by putting an apostrophe in front of it, and it won't show up.

Make sure you do proper testing though....it's odd that the error occurs and the objects are still moved...

Regards,

Rob.
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 35003837
Thanks for the grade.

Regards,

Rob.
0
 

Author Comment

by:siber1
ID: 35004297
Hi Rob, sorry one last thing i forgot to ask you.
The subnets that i need to define in the script that you provided are mostly class B subnets, for example 10.140.0.0 /16
how can i input these subnets into the script?

thanks in advance,

S.
0
 
LVL 65

Expert Comment

by:RobSampson
ID: 35005072
Hi, so, you want to check just the first two octets?  My subnetting theory isn't that great.....

So, the array could look like this:
strOU = "OU=Corp Computers"
objSubnets.Add "192.168.", "OU=EMEA,OU=Corp Computers,"
objSubnets.Add "192.168.", "OU=NASA,OU=Corp Computers,"
objSubnets.Add "192.168.", "OU=APEC,OU=Corp Computers,"

and then you can change this:
            strSubNet = Left(strIP, InStrRev(strIP, "."))


to this:
            strSubNet = Left(Left(strIP, InStrRev(strIP, ".") - 1), InStrRev(Left(strIP, InStrRev(strIP, ".") - 1), "."))


to put xxx.xxx. as the comparison.

Regards,

Rob.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article outlines the process to identify and resolve account lockout in an Active Directory environment.
This article describes my battle tested process for setting up delegation. I use this process anywhere that I need to setup delegation. In the article I will show how it applies to Active Directory
This tutorial will walk an individual through the steps necessary to join and promote the first Windows Server 2012 domain controller into an Active Directory environment running on Windows Server 2008. Determine the location of the FSMO roles by lo…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question