Solved

Cleanup AD using vbs

Posted on 2009-07-01
15
740 Views
Last Modified: 2012-05-07
Hi,
I'm working to do an automated process that will move computers from a specific OU to another based on a set of rules.
The rules state that if a Computer is named XXX and the type of the OS is Windows XP then Move to ZZZ OU.
Thus creating a predetermined set of rules and run a schedule task.
Can it be done?
0
Comment
Question by:johnnyjonathan
  • 7
  • 6
15 Comments
 
LVL 27

Expert Comment

by:bluntTony
Comment Utility
The below vbs checks for the existence of a string in the computer name, then checks for the existence of a string in the Operating System. If both are found, then the computer is moved to the new OU.
Just change strOS, strSearch, and objOU to suit your needs (lines 9, 10 and 11)
You can schedule this vbs to run as a scheduled task if you wish. It currently has no feedback so runs silently.
Hope this helps...

Set oRootDSE = GetObject("LDAP://RootDSE")

Set objConn = CreateObject("ADODB.Connection")

Set objComm =   CreateObject("ADODB.Command")

objConn.Provider = "ADsDSOObject"

objConn.Open "Active Directory Provider"

Set objComm.ActiveConnection = objConn

objComm.Properties("Page Size") = 1000
 

strSearch = "XXXX" ' The string to search for in the computer name

strOS = "XP" ' The string to search for in Operating System

Set objOU = GetObject("LDAP://OU=someOU,DC=domain,DC=local") ' The OU to move the objects to
 

strBase   =  "<LDAP://" & oRootDSE.get("defaultNamingContext") & ">;"

strFilter = "(&(objectclass=computer)(cn=*" & strSearch & "*)(operatingSystem=*" & strOS & "*));" 

strAttrs  = "distinguishedName;"

strScope  = "subtree"
 

objComm.CommandText = strBase & strFilter & strAttrs & strScope

Set objRS = objComm.Execute
 

If objRS.RecordCount > 0 Then

	objRS.MoveFirst

	Do Until objRS.EOF

		Set objComp = GetObject("LDAP://" & Replace(objRS.Fields(0).Value,"/","\/"))

		objOU.MoveHere objComp.distinguishedName, objComp.name

		objRS.MoveNext

	Loop

End If
 

Set oRootDSE = Nothing

Set objConn = Nothing

Set objComm = Nothing

Set objOU = Nothing

Set objRS = Nothing

Set objComp = Nothing

Open in new window

0
 

Author Comment

by:johnnyjonathan
Comment Utility
hi bluntTony, is there anyway i can also exclude specific computers from this filter with that script? it seemed to remove default machines in the ou that wern't suppose to be moved
0
 
LVL 27

Expert Comment

by:bluntTony
Comment Utility
You can add these machine names to a text file. Any machines listed in this file will be excluded from processing in the following script.

You now also have strFile to designate the path to the text file.
Set oRootDSE = GetObject("LDAP://RootDSE")

Set objConn = CreateObject("ADODB.Connection")

Set objComm =   CreateObject("ADODB.Command")

Set objFso = CreateObject("Scripting.FileSystemObject")

Set objDict = CreateObject("Scripting.Dictionary")
 

Const ForReading = 1
 

objConn.Provider = "ADsDSOObject"

objConn.Open "Active Directory Provider"

Set objComm.ActiveConnection = objConn

objComm.Properties("Page Size") = 1000

 

strSearch = "XXXX" ' The string to search for in the computer name

strOS = "XP" ' The string to search for in Operating System

strFile = "c:\test.txt"

Set objOU = GetObject("LDAP://OU=someOU,DC=domain,DC=local") ' The OU to move the objects to

 

Set objTxt = objFso.OpenTextFile(strFile,ForReading)
 

While Not objTxt.AtEndOfStream

	strLine = UCase(objTxt.ReadLine)

	objDict.Add strLine, strLine

Wend
 

strBase   =  "<LDAP://" & oRootDSE.get("defaultNamingContext") & ">;"

strFilter = "(&(objectclass=computer)(cn=*" & strSearch & "*)(operatingSystem=*" & strOS & "*));" 

strAttrs  = "distinguishedName;"

strScope  = "subtree"

 

objComm.CommandText = strBase & strFilter & strAttrs & strScope

Set objRS = objComm.Execute

 

If objRS.RecordCount > 0 Then

        objRS.MoveFirst

        Do Until objRS.EOF

                Set objComp = GetObject("LDAP://" & Replace(objRS.Fields(0).Value,"/","\/"))

                If Not objDict.Exists(UCase(objComp.cn)) Then

                	objOU.MoveHere objComp.distinguishedName, objComp.name

	                objRS.MoveNext	

                End If

        Loop

End If

 

Set oRootDSE = Nothing

Set objConn = Nothing

Set objComm = Nothing

Set objOU = Nothing

Set objRS = Nothing

Set objComp = Nothing

Set objFso = Nothing

Set objTxt = Nothing

Open in new window

0
 

Author Comment

by:johnnyjonathan
Comment Utility
thank you Tony, i see the OU to move the objects to but where is the original OU where it takes the computer names from?

is it LDAP://" & oRootDSE?
0
 
LVL 27

Expert Comment

by:bluntTony
Comment Utility
Yes, at the moment, the base of the search is the top of the domain and the scope is 'subtree' which basically means look everywhere in your current domain.

If you want to narrow the search, change line 26 to to DN of the OU you want to look in e.g:

strBase   =  ";"

If you want to search all OUs beneath this one, leave line 29 as it is. If you want to search in just that OU, change line 29 to:

strScope  = "onelevel"

Hope this helps!

0
 

Author Comment

by:johnnyjonathan
Comment Utility
hi,
i get:

(39, 25) Active Directory: An invalid directory pathname was passed
0
 
LVL 27

Accepted Solution

by:
bluntTony earned 400 total points
Comment Utility
hmmm. Looks like a small error in my code. Try this:
Set oRootDSE = GetObject("LDAP://RootDSE")

Set objConn = CreateObject("ADODB.Connection")

Set objComm =   CreateObject("ADODB.Command")

Set objFso = CreateObject("Scripting.FileSystemObject")

Set objDict = CreateObject("Scripting.Dictionary")

 

Const ForReading = 1

 

objConn.Provider = "ADsDSOObject"

objConn.Open "Active Directory Provider"

Set objComm.ActiveConnection = objConn

objComm.Properties("Page Size") = 1000

 

strSearch = "XXXX" ' The string to search for in the computer name

strOS = "XP" ' The string to search for in Operating System

strFile = "c:\test.txt"

Set objOU = GetObject("LDAP://OU=someOU,DC=domain,DC=local") ' The OU to move the objects to

 

Set objTxt = objFso.OpenTextFile(strFile,ForReading)

 

While Not objTxt.AtEndOfStream

        strLine = UCase(objTxt.ReadLine)

        objDict.Add strLine, strLine

Wend

 

strBase   =  "<LDAP://" & oRootDSE.get("defaultNamingContext") & ">;"

strFilter = "(&(objectclass=computer)(cn=*" & strSearch & "*)(operatingSystem=*" & strOS & "*));" 

strAttrs  = "distinguishedName;"

strScope  = "subtree"

 

objComm.CommandText = strBase & strFilter & strAttrs & strScope

Set objRS = objComm.Execute

 

If objRS.RecordCount > 0 Then

        objRS.MoveFirst

        Do Until objRS.EOF

                Set objComp = GetObject("LDAP://" & Replace(objRS.Fields(0).Value,"/","\/"))

                If Not objDict.Exists(UCase(objComp.cn)) Then

                        objOU.MoveHere objComp.distinguishedName, objComp.name  

                End If

                objRS.MoveNext

        Loop

End If

 

Set oRootDSE = Nothing

Set objConn = Nothing

Set objComm = Nothing

Set objOU = Nothing

Set objRS = Nothing

Set objComp = Nothing

Set objFso = Nothing

Set objTxt = Nothing

Open in new window

0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:johnnyjonathan
Comment Utility
hi,
thanks for the changges but i still get:

(32, 1) Active Directory: An invalid directory pathname was passed

the only thing i'm changing is line 26
strBase   =  "<LDAP://" & oRootDSE.get("defaultNamingContext") & ">;"

to
strBase   =  "<LDAP://OU=someOU,DC=domain,DC=local & oRootDSE.get("defaultNamingContext") & ">;"

of course with my OU's details.
same goes to line 17
0
 
LVL 27

Expert Comment

by:bluntTony
Comment Utility
Sorry for the delay in replying. You need to remove the oRootDSE object completely. So line 26 should look like:
strBase   =  "<LDAP://OU=someOU,DC=domain,DC=local>;"
This will mean that the search will start at this OU downwards.
0
 

Author Comment

by:johnnyjonathan
Comment Utility
Hi Tony, no problem, i've done as you requested but now i get this error -

(39, 25) Active Directory: An invalid directory pathname was passed
but only sometimes, in other times, it works but i can't see any computers moving from an OU to OU?
 
 
0
 

Author Comment

by:johnnyjonathan
Comment Utility

I found a question that looks like mine with a solution running, however without a search for a naming based context -

http://www.experts-exchange.com/Programming/Languages/.NET/Visual_Basic.NET/Q_24102299.html?sfQueryTermInfo=1+creat+ou

can we modify it to fit my requirements?  
0
 
LVL 70

Assisted Solution

by:Chris Dent
Chris Dent earned 100 total points
Comment Utility

> objOU.MoveHere objComp.distinguishedName

This line should be:

objOU.MoveHere objComp.ADSPath, vbNullString

Or:

objOU.MoveHere "LDAP://" & objComp.distinguishedName, vbNullString

Chris
0
 
LVL 27

Expert Comment

by:bluntTony
Comment Utility
Apologies - this one seemed to have slipped though my inbox.

Thanks for the catch, Chris.
0
 

Author Closing Comment

by:johnnyjonathan
Comment Utility
Works perfect!
thank you!
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Batch, VBS, and scripts in general are incredibly useful for repetitive tasks.  Some tasks can take a while to complete and it can be annoying to check back only to discover that your script finished 5 minutes ago.  Some scripts may complete nearly …
Resolve DNS query failed errors for Exchange
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

744 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now