Wednesday, September 5, 2012

get size of directories with powershell, the stupid but fast way

All those ways to get the size of directories with powershell are extremely slow. Especially on network shares.
e.g.

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

Currently i’m harvesting through roughly 40TB of data and it’s taking me daaaaaaaaaays!
So i’m in desperate need of something faster.
Then i thought about robocopy. Robocopy gives great statistics. So if i do a “dry-run” (list-only, not really copy), i might get the information i need by parsing the output.

Choice of switches:

  • /b = backup mode. Supposed to give me access to every file
  • /l = list only/dry-run, not really doing the copy
  • /mir = action what you would normally do when you would copy the data. This also dives into all subdirectories.
  • /r:0 = no retries
  • /w:0 = don’t wait on anything
  • /ns /nc /nfl /ndl /njh = no logging of any kind. We only want the summary.

Then we get this piece of code (it could be a lot shorter, but i’m keeping it readable):

function get_size_of_dir_in_bytes_with_robocopy ($directory)
{
  write-host "- $directory" -foreground "GREEN"
  [string]$result = robocopy /b /l /mir "$directory" "c:\whatever" /r:0 /w:0 /ns /nc /nfl /ndl /njh /bytes
  if (!($lastexitcode -eq 16))
  {
    $pos = ($result).indexof("Bytes : ")
    $start = $pos + 8
    $length = $result.length
    $end = $length - $start
    $newstring = ($result).substring($start,$end)
    $newstring = $newstring.trim()
    echo $newstring.split()[0]
  }
  else
  {
    echo "CANNOT ACCESS"
  }
}