Active Directory: Vbscript to enumerate all Active Directory users sorted by OU

Posted October 5th, 2011 in ou by dirk adamsky

Austin Murtha sent me an email with a script question.
His problem was a script that enumerates users and their OU’s.
I have created the script below to help him.

What the script does:

  1. create a “disconnected recordset” (for the sorting stuff)
  2. get all users from active directory with an ADO query
  3. remove undesired results (if instr…)
  4. add the rest to the disconnected recordset
  5. sort the recordset
  6. output to the screen

Follow the next steps to run the script (no admin rights needed):

  • copy and paste the script below into the editor (you can use the icons in the upper rights corner of the code)
  • save the script (for example c:\temp\usersinou.vbs)
  • open a command prompt
  • go to “c:\temp”
  • give “cscript usersinou.vbs” (without quotes) and enter

The script:

' Name : usersinou.vbs
' Description : script to enumerate all Active Directory users sorted by OU
' Author : dirk adamsky - deludi bv
' Version : 1.0
' Date : 05-10-2011

Set DataList = CreateObject("ADOR.Recordset")
DataList.Fields.Append "Name", 200, 255
DataList.Fields.Append "OU", 200, 255
DataList.Open

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

Set objRootDSE = GetObject("LDAP://RootDSE")
strBase = ""
strFilter = "(&(objectCategory=person)(objectClass=user))"
strAttributes = "name,distinguishedname"

strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

Set adoRecordset = adoCommand.Execute

Do Until adoRecordset.EOF
	If Instr(adoRecordset.Fields("distinguishedname").Value,"OU=") > 1 Then
		DataList.AddNew
		DataList("Name") = adoRecordset.Fields("name").Value
		DataList("OU") = Mid(adoRecordset.Fields("distinguishedname").Value, Instr(adoRecordset.Fields("distinguishedname").Value,"OU="))
		Datalist.Update
	End If
	adoRecordset.MoveNext
Loop

adoRecordset.Close
adoConnection.Close

Set adoRecordset = Nothing
Set objRootDSE = Nothing
Set adoConnection = Nothing
Set adoCommand = Nothing

DataList.Sort = "OU DESC"
DataList.MoveFirst

Do Until DataList.EOF
     Wscript.Echo DataList.Fields.Item("OU") & " ; " & DataList.Fields.Item("Name")
     DataList.MoveNext
Loop

Datalist.Close
Set DataList = Nothing

When you have a modified version or problems/questions that you want to share please post it at the comments below.

Happy scripting.

Dirk Adamsky

Active Directory: VBscript to enumerate the home directories and their sizes of all users in Active Directory

Posted July 12th, 2011 in home directories by dirk adamsky

Update: This script has some issues (path not found) with users with very large home folders and or homefolders with long pathnames. This is due to limitations of the Filesystem Object. I will see if i can make a “better solution”.

Dave asked me for a script to enumerate all AD users, their home directories and the size of them.
I already had the script to do that for roaming profiles.
This script is a modified version.

Follow the next steps to run the script (admin rights needed for access to the home directories):

* open your favorite text editor
* copy and paste the script into the editor
* save the script (for example c:\temp\homedirectorysize.vbs)
* open a command prompt
* go to “c:\temp”
* give “cscript homedirectorysize.vbs” (without quotes) and enter

The script:

' Name : homedirectorysize.vbs
' Description : script to enumerate the home directories and their sizes of all users in Active Directory
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 12-07-2011
' Level : intermediate

arrAttributes = Array("homeDirectory","displayname","mail") 

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

Set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">"
Set objRootDSE = Nothing

strFilter = "(&(objectCategory=person)(objectClass=user)(homeDirectory=*))"
strAttributes = Join(arrAttributes,",")
Wscript.Echo Join(arrAttributes,";") & " ; home directory size in MB"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
Do Until adoRecordset.EOF
	On Error Resume Next
	strTempOutput = ""
	For i = 0 To Ubound(arrAttributes)
		strTempOutput =  strTempOutput & " ; " & adoRecordset.Fields(arrAttributes(i)).Value
		strOutput = Mid(Ltrim(strTempOutput),3)
	Next
	Wscript.Echo strOutput & " ; " & Foldersize (adoRecordset.Fields(arrAttributes(0)).Value) & " MB"
	adoRecordset.MoveNext
Loop
adoRecordset.Close
adoConnection.Close
Set adoRecordset = Nothing
Set adoConnection = Nothing
Set adoCommand = Nothing

Function Foldersize(strPath)
	On Error Resume Next
	Set objFSO = CreateObject("scripting.filesystemobject")
	Set objFld = objFSO.GetFolder(strPath)
	Foldersize = Round(objFld.Size/1048576,2)
	Set objFld = Nothing
	Set objFSO = Nothing
End Function

When you have problems/questions please post a reply. Also can alo give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

Active Directory: VBscript to enumerate the local profile size of all computers and users in Active Directory

Posted June 28th, 2011 in localprofiles by dirk adamsky

This script is made for Mike.
He asked for a script to enumerate all local profiles and their size of the computers in his network.
Complicating factor is the use of both Windows XP and Windows 7 clients.
As you probably know that they have different local profile paths:

Windows XP – “c:\documents and settings”

Windows 7 – “c:\users”

The script has to do:

  • get all Windows XP and Windows 7 clients from Active Directory
  • check if they are online
  • get the local profiles and their sizes from each machine
  • write the values to a central logfile

Follow the next steps to run the script (local admin rights needed for access to the target pc’s):

* open your favorite text editor
* copy and paste the script into the editor
* change the logfile location in line 73 (now c:\temp)
* save the script (for example c:\temp\localprofiles.vbs)
* open a command prompt
* go to “c:\temp”
* give “cscript localprofiles.vbs” (without quotes) and enter

The script:

' Name : localprofiles.vbs
' Description : script to enumerate the local profile size of all computers and users in Active Directory
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 28-06-2011

Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
Set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">"
strFilter = "(&(objectCategory=computer)(|(operatingSystem=Windows XP Professional)(operatingSystem=Windows 7*)))"
strAttributes = "name, operatingSystem"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

Set adoRecordset = adoCommand.Execute

Do Until adoRecordset.EOF
	strHostname = adoRecordset.Fields("name").Value
	If CheckStatus(strHostname) = True Then
		If Instr(adoRecordset.Fields("operatingSystem").Value, "XP") > 0 Then
			strLocalProfilePath = "\Documents and Settings\"
		ElseIf Instr(adoRecordset.Fields("operatingSystem").Value, "7") > 0 Then
			strLocalProfilePath = "\users\"
		End If
		GetLocalProfileSize strHostname, "\\" & strHostname & "\c$" & strLocalProfilePath
	End If
	adoRecordset.MoveNext
Loop

adoRecordset.Close
adoConnection.Close

Set adoRecordset = Nothing
Set objRootDSE = Nothing
Set adoConnection = Nothing
Set adoCommand = Nothing

Function CheckStatus(strAddress)
	Dim objPing, objRetStatus
	Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
      ("select * from Win32_PingStatus where address = '" & strAddress & "'")
	For Each objRetStatus In objPing
        If IsNull(objRetStatus.StatusCode) Or objRetStatus.StatusCode <> 0 Then
			CheckStatus = False
        Else
			CheckStatus = True
        End If
    Next
	Set objPing = Nothing
End Function

Function GetLocalProfileSize(strTargetMachine, strFolder)
	Set objFSO = CreateObject("Scripting.FileSystemObject")
	Set objFolder = objFSO.GetFolder(strFolder)
	For Each SubFolder in objFolder.SubFolders
		Logprint strTargetMachine & " ; " & SubFolder.Name & " ; " & SubFolder.Path & " ; " & Round(SubFolder.Size/1048576,2) & " MB"
	Next
	Set objFolder = Nothing
	Set objFSO = Nothing
End Function

Function LogPrint(Message)
Const ForAppending = 8
strDate = Replace(Date,"/","-")
Set ObjFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = ObjFSO.OpenTextFile("c:\temp\" & strDate & "-localprofiles.csv", ForAppending, True)
    objTextFile.WriteLine Message
    objTextFile.Close
Set objTextFile = Nothing
Set ObjFSO = Nothing
End Function

When you have problems/questions please post a reply. Also can also give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

Various: Delete a vb script after running (this script will self destruct in xx seconds)

Posted September 8th, 2010 in Various, vbscript by dirk adamsky

Yesterday I did some work on VMware VDI.

I had a problem with the clones joining the 2003 domain.
The joining fails for 5% of the new cloned Win XP machines.
VMware VDI uses sysprep to rename, join domain, etc.
The sysprep inf file is generated by a customization specification.
Also in the customization specification I had a small afterjob that
moves the computer account to the right AD container (I used the Dsmod utility),
this afterjob also failed in 5% of the cases.

I decided to do some scripting.
The script to join the domain I already had, I only had to add 2 parts:

  1. Something to remove the script after running (because it contains admin credentials)
  2. Something to reboot the machine after running the job

For the destruction of the script after running I found this code:

Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile(Wscript.ScriptFullName)
Set objFSO = Nothing

Cut and paste this code at the end of your script.
Normally the script code is parsed before running so there should be no File Locking problem removing the script.

Tomorrow I will post the completed script with:

  • Join domain
  • Add the right container
  • Remove the script file
  • Reboot the machine

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

[adrotate group="3"]