1

I've been scouring the web for a decent script to allow me to gather folder sizes of subfolders on Windows 7 machines. There's roughly 50 computers I want to get folder sizes on C:\Users\username\Documents and C:\Users\username\Desktop).

I have no scripting experience (will start learning because of this) and don't have enough knowledge to edit another person's script.

The script I've been working off of is below. And if anyone can point me in the right direction I would be very grateful.

' 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
Rowell
  • 703
  • 8
  • 18

1 Answers1

2

I know this won't anser your question for vbscript, but I would recommend powershell if you're open to it. It's typically much easier, just to give you an example...

Here is a link to start out with: http://technet.microsoft.com/en-us/library/ff730945.aspx

and here is a modified version of their example:

$colItems = (Get-ChildItem C:\users\username\desktop -recurse | Measure-Object -property length -sum)
"{0:N2}" -f ($colItems.sum / 1MB) + " MB"

Change the values in C:\users\username\desktop and tell me if you like the results. If you do and want help with looping and grabbing the data from remote computers, let me know.

Script v1: It's not perfect, but i think it will work for the most part. You'll need to download Quest AD CMDlets and install it on the system you're going to run this from. Also, you'll need to set your execution policy to remotesigned. Then copy this script to the local drive of this system. You'll need to edit three values, the $rootou (this is your OU that you want to search), and the two lines under #Export paths. Let me know how it works. or if you need a copy of the script uploaded.

#Script used to gather data size of remote computers user profiles by Eric C. Singer

#a generic powershell object used to group a collection of various objects into a single object 
$data = new-object psobject
$columns = @"
ComputerName
ProfileName
DocumentsSizeMB
DesktopSizeMB
"@
$columns -split "`n" |%{$data | add-member -membertype noteproperty -name $_.trim() -value $null}

#Store a list of computers that we couldn't connect to
$failedcomputers = New-Object System.Collections.ArrayList

#Store the results of the gathered data
$foldersize = New-Object System.Collections.ArrayList

#Root OU that you want to start searching for computers
$RootOU = "yourdomain.org/your ou/ your sub-ou"

#Getting a list of all computers
$allcomputers = Get-QADComputer -SearchRoot "$rootou" -SizeLimit 0

#Export paths
$failedcomputersfiles = "c:\yourpath\yourfile.csv"
$foldersizefile = "c:\yourpath\yourfile.csv"

#Looping through each computer
Foreach ($computer in $allcomputers)
    {
#Seeing if we can connect to the computer, if not, we're going to add it to the failedcomputers array.
    If (Test-Path "\\$($computer.name)\c$")
        {
#Setting the two possiable paths based on whether its Windows 7 or XP
        $Windows7ProfileRoot = "\\$($computer.name)\c$\Users"
        $WindowsXPProfileRoot = "\\$($computer.name)\c$\Documents and Settings"
#if the computer is windows 7 run this, or go to the else statement
        If ($($computer.OSName) -like "Windows 7*")
            {
#getting a list of profiles
            $allprofiles = Get-ChildItem $Windows7ProfileRoot | Where-Object {$_.PSIsContainer -eq $true}
#Looping through each profile and running the following.
            Foreach ($user in $allprofiles)
                {
                $data.ComputerName = $computer.name
                $data.ProfileName = $user.name
                $userdesktop = (Get-ChildItem "$Windows7ProfileRoot\$($user.name)\desktop" -recurse | Measure-Object -property length -sum).sum / 1MB
                $userdocuments = (Get-ChildItem "$Windows7ProfileRoot\$($user.name)\documents" -recurse | Measure-Object -property length -sum).sum / 1MB
                $data.DesktopSizeMB = $userdesktop
                $data.DocumentsSizeMB = $userdocuments
                $data | Select-Object * | ForEach-Object {$foldersize.Add($_)}
                }
            }
        Else
            {
            $allprofiles = Get-ChildItem $WindowsXPProfileRoot | Where-Object {$_.PSIsContainer -eq $true}
            Foreach ($user in $allprofiles)
                {
                $data.ComputerName = $computer.name
                $data.ProfileName = $user.name
                $userdesktop = (Get-ChildItem "$WindowsXPProfileRoot\$($user.name)\desktop" -recurse | Measure-Object -property length -sum).sum / 1MB
                $userdocuments = (Get-ChildItem "$WindowsXPProfileRoot\$($user.name)\my documents" -recurse | Measure-Object -property length -sum).sum / 1MB
                $data.DesktopSizeMB = $userdesktop
                $data.DocumentsSizeMB = $userdocuments
                $data | Select-Object * | ForEach-Object {$foldersize.Add($_)}
                $data
                }
            }
        }
    Else
        {
        $failedcomputers.Add("$($computer.name)")
        }
    }

$failedcomputers | Export-Csv $failedcomputersfiles -NoTypeInformation
$foldersize | Export-Csv $foldersizefile -NoTypeInformation
Eric C. Singer
  • 2,319
  • 15
  • 17
  • +1 VBS will be around for a while, but Powershell is the clear path forward. – jscott Jan 28 '12 at 01:16
  • This script worked well on my local computer. I'll look over that link to see how I can apply this to all the computers in my office to generate one csv file. – Rowell Feb 01 '12 at 00:15
  • If you want to grab the data from one server, that would help a lot, but at the same time it will take much longer. I would reccomend getting the quest AD CMDLests (they're free) and look into looping (ie foreach $i in $array do "x") If you tell me how you want to gather the data, i might be able to get you the skeleton of a script. – Eric C. Singer Feb 01 '12 at 00:35
  • I would like to gather the data from computers in the office and put it on one csv file which will list the computer name, user and total data storage on i.e. Desktop and Documents folder. I hope that is enough information. I just got a hold of a PowerShell book to help me understand this. – Rowell Feb 01 '12 at 18:37
  • Ok, it'll take me a day or two to get it to you. – Eric C. Singer Feb 02 '12 at 01:12
  • Just letting you know the script is posted – Eric C. Singer Feb 04 '12 at 17:26
  • Your script worked out perfectly. Thank you so much! – Rowell Feb 06 '12 at 18:35