# IMPORTANT: start this script in a fresh session to prevent previous exceptions from carrying over in $Error

function folderClass

{

param

(

[ Parameter ( Mandatory = $true ) ]

[ String ] $path ,

[ Parameter ( Mandatory = $true ) ]

[ double ] $origSize

)

$folderObj = @ { }

$folderObj .path = $path

$folderObj .origSize = [ math ] ::Round ( $ ( $origSize / 1024 / 1024 ) , 2 ) # all size props expressed in MB rounded to hundredths

$folderObj .currSize = [ math ] ::Round ( $ ( $origSize / 1024 / 1024 ) , 2 ) # intentional. At object creation, $orig = $curr size.

$folderObj .delta = $folderObj .currSize - $folderObj .origSize

$folderObj .isDirty = $false # toggles $true if gci throws exception (filname too long, insufficient permissions, etc.)

$folderObj .exception = "None" # holds most recent gci exception for this folder

return $folderObj

}

# config

$targetDir = "D:\Your\Target\Path\Here" # change this!

$folderObs = @ ( )

$prevErrorCount = 0

# first pass: populate an array of folder objs with the properties we need to continually calculate size diffs

$folders = gci $targetDir

$folderCount = $folders .Count

foreach ( $folder in $folders )

{

$folderSize = gci $folder .FullName -Recurse | Measure-Object -property length -sum

$currFolderObj = folderClass $folder .FullName $folderSize .Sum

# try/catch will not work for the statements above, this is the only way to do it.

if ( $ ( $Error .count ) -gt $prevErrorCount )

{

$currFolderObj .isDirty = $true

$errorIndex = $Error .Count - 1

$currFolderObj .exception = $Error [ $errorIndex ] .ToString ( )

$prevErrorCount = $Error .Count

}

$folderObs += $currFolderObj

write-host "$($currFolderObj.path), size $($currFolderObj.currSize) MB"

# $cont = read-host "any key to continue"

}

# subsequent passes: iterate over the folder objects, calculate size delta, and log out to .csv

while ( $true )

{

# new output file for each iteration, so we can delete files easily

$outFile = "$(Get-Date -f yyyy-MM-dd-HHmm).csv"

New-Item $outFile - Type file | Out-Null

"PATH,ORIG_SIZE,CURR_SIZE,DELTA,IS_DIRTY,MOST_RECENT_EXCEPTION" | Out -File $outFile -Append

foreach ( $folderObj in $folderObs )

{

$currFolderSize = gci $folderObj .path -Recurse | Measure-Object -property length -sum

$folderObj .currSize = [ math ] ::Round ( $ ( $currFolderSize .sum / 1024 / 1024 ) , 2 )

$folderObj .delta = [ math ] ::Round ( $ ( $folderObj .currSize - $folderObj .origSize ) , 2 )

# try/catch will not work for the statements above, this is the only way to do it.

if ( $ ( $Error .count ) -gt $prevErrorCount )

{

$currFolderObj .isDirty = $true

$errorIndex = $Error .Count - 1

$currFolderObj .exception = $Error [ $errorIndex ] .ToString ( )

$prevErrorCount = $Error .Count

}

write-host "$($folderObj.path), $($folderObj.origSize), $($folderObj.currSize), $($folderObj.delta), $($folderObj.isDirty), $($folderObj.exception)"

"$($folderObj.path), $($folderObj.origSize), $($folderObj.currSize), $($folderObj.delta), $($folderObj.isDirty), $($folderObj.exception)" | Out -File $outFile -Append

}