[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 533
  • Last Modified:

need scripting assistance moving computers to a specific OU

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
siber1
Asked:
siber1
  • 8
  • 8
1 Solution
 
NavdeepCommented:
Hi,

what are the network subnet that you are using?
0
 
RobSampsonCommented:
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
 
siber1Author Commented:
thanks Rob! this is fantastic. I will test this later this afternoon in our lab to validate.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
RobSampsonCommented:
Sure.  Let me know how you go.

Regards,

Rob.
0
 
siber1Author Commented:
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
 
RobSampsonCommented:
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
 
siber1Author Commented:
Hi Rob, made the change, now getting this error:
Error 450: Wrong number of arguments or invalid property assignment
0
 
siber1Author Commented:
Rob, although it generates this error 450 as stated above, it does move the first Computer in that OU. then skips the rest.
0
 
RobSampsonCommented:
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
 
siber1Author Commented:
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
 
RobSampsonCommented:
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
 
siber1Author Commented:
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
 
siber1Author Commented:
That did the trick Rob. BRILLIANT!
thanks so much. Full points, wish i had more to give  : )
0
 
RobSampsonCommented:
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
 
RobSampsonCommented:
Thanks for the grade.

Regards,

Rob.
0
 
siber1Author Commented:
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
 
RobSampsonCommented:
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 8
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now