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

Active Directory: Vbscript to enumerate all Domain Controllers

Posted April 22nd, 2010 in active directory, domaincontrollers, vbscript by dirk adamsky

Today’s script is about domain controllers.
Getting a list of them is more complicated then expected.
What we need is a list of “nTDSDSA” servers.
That list does not the servname itself, it gives the distinguished name of the “nTDSDSA” object.
The abstraction of the servername is done by connecting to the parent object of the “nTDSDSA” object.

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

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

The script:

' Name : listdomaincontrollers.vbs
' Description : script to enumerate all Domain Controllers
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 22-04-2010
' Level: intermediate

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("configurationnamingcontext") & ">"
strFilter = "(objectClass=nTDSDSA)"
strAttributes = "ADsPath"

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
	Set objDC = GetObject(GetObject(adoRecordset.Fields("ADsPath")).Parent)
	Wscript.Echo objDC.cn
	Set objDC = Nothing
	adoRecordset.MoveNext
Loop

adoRecordset.Close
adoConnection.Close

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

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

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

Active Directory: VBscript to enumerate the roaming profile size of all users in Active Directory

Posted March 15th, 2010 in roamingprofile by dirk adamsky

For a sysadmin roaming profiles are both a blessing and a curse.
In time they tend to grow and grow…
The roaming profile size problem results in: long logon and logoff times, corrupted profiles, etc.
This script enumerates the roaming profile size of all users in your Active Directory domain.
By adding extra attributes to the arrAttributes array you can change the output.

Follow the next steps to run the script (admin rights needed for access to the roaming profiles directory):

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

The script:

' Name : roamingprofilesize.vbs
' Description : script to enumerate the roaming profile size of all users in Active Directory
' Author : dirk adamsky - deludi bv
' Version : 1.10 (changed script error based on input from Jim)
' Date : 06-05-2011
' Level : intermediate

arrAttributes = Array("profilePath","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)(profilePath=*))"
strAttributes = Join(arrAttributes,",")
Wscript.Echo Join(arrAttributes,";") & " ; roaming profile 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 last logon of all AD users and a lot of user attributes

Posted February 25th, 2010 in lastlogon by dirk adamsky

! I made a new lastlogonscript, it can be found here.
This script is based on the lastlogon script by Richard L. Mueller.
Added is an enumeration of 30 user attributes.
All in all it gives you an huge load of information…..

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

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

The script:

' Name : enumerate-lastlogon-details.vbs
' Description : script to enumerate the last logon of all AD users and a lot of user attributes
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 25-02-2010
' Level : advanced

Option Explicit

Dim objRootDSE, adoConnection, adoCommand, strQuery, strMail, strDisname, strCompany, strDepartment
Dim adoRecordset, strDNSDomain, objShell, lngBiasKey
Dim lngBias, k, strDN, dtmDate, objDate, arrAttributes
Dim strBase, strFilter, strAttributes, lngHigh, lngLow, strOutput, i

arrAttributes = Array("cn","sAMAccountName","company","department","displayName",_
				"distinguishedName","lastKnownParent","mail","mailNickname","manager","physicalDeliveryOfficeName",_
				"postalCode","telephoneNumber","userPrincipalName","whenChanged","whenCreated",_
				"extensionAttribute1","extensionAttribute2","extensionAttribute3","extensionAttribute4","extensionAttribute5",_
				"extensionAttribute6","extensionAttribute7","extensionAttribute8","extensionAttribute9",_
				"extensionAttribute10","extensionAttribute11","extensionAttribute12","extensionAttribute13",_
				"extensionAttribute14,extensionAttribute15,lastLogonTimeStamp") 

' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLMSystemCurrentControlSetControlTimeZoneInformationActiveTimeBias")
If (UCase(TypeName(lngBiasKey)) = "LONG") Then
    lngBias = lngBiasKey
ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
    lngBias = 0
    For k = 0 To UBound(lngBiasKey)
        lngBias = lngBias + (lngBiasKey(k) * 256^k)
    Next
End If
Set objShell = Nothing

' Determine DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
Set objRootDSE = Nothing

' Use ADO to search Active Directory.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

' Search entire domain.
strBase = "<LDAP://" & strDNSDomain & ">"

' Filter on all user objects.
strFilter = "(&(objectCategory=person)(objectClass=user))"

' Comma delimited list of attribute values to retrieve.
strAttributes = Join(arrAttributes,",")
Wscript.Echo strAttributes
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 60
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute

' Enumerate resulting recordset.
Do Until adoRecordset.EOF
    On Error Resume Next
    Set objDate = adoRecordset.Fields("lastLogonTimeStamp").Value
    If (Err.Number <> 0) Then
        On Error GoTo 0
        dtmDate = #1/1/1601#
    Else
        On Error GoTo 0
        lngHigh = objDate.HighPart
        lngLow = objDate.LowPart
        If (lngLow < 0) Then
            lngHigh = lngHigh + 1
        End If
        If (lngHigh = 0) And (lngLow = 0 ) Then
            dtmDate = #1/1/1601#
        Else
            dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
                + lngLow)/600000000 - lngBias)/1440
        End If
    End If
    ' Display values for the user.
    strOutput = ""
	For i = 0 To (Ubound(arrAttributes) - 1)
		strOutput = strOutput & " ; " & adoRecordset.Fields(arrAttributes(i)).Value
	Next
	If (dtmDate = #1/1/1601#) Then
        Wscript.Echo strOutput & " ; Never"
    ElseIf DateDiff("d",dtmDate,Date) > 90 Then
	    Wscript.Echo strOutput & " ; " & dtmDate
    End If
    adoRecordset.MoveNext
Loop

' Clean up.
adoRecordset.Close
adoConnection.Close
Set adoRecordset = Nothing
Set objDate = Nothing
Set adoConnection = Nothing
Set adoCommand = Nothing

When you have problems/questions please post a reply.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

[adrotate group="2" banner="3"]