Solved

need scripting assistance moving computers to a specific OU

Posted on 2011-02-28
17
509 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
[X]
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
  • 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
Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
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

Is Your AD Toolbox Looking More Like a Toybox?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

Windows 10 came with  a lot of built in applications, Some organisations leave them there, some will control them using GPO's. This Article is useful for those who do not want to have any applications in their image (example:me).
This article demonstrates probably the easiest way to configure domain-wide tier isolation within Active Directory. If you do not know tier isolation read https://technet.microsoft.com/en-us/windows-server-docs/security/securing-privileged-access/s…
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 …
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

696 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