jrara
jrara

Reputation: 16981

How to recurse through folders and determine the folder size?

I have a slightly modified version of a script presented in "Windows PowerShell Tip of the Week". The idea is to determine the size of a folder and its subfolders:

$startFolder = "C:\Temp\"

$colItems = (Get-ChildItem $startFolder | Measure-Object | Select-Object -ExpandProperty count)
"$startFolder -- " + "{0:N2}" -f ($colItems.sum / 1MB) + " MB"

$colItems = (Get-ChildItem $startFolder -recurse | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object)
foreach ($i in $colItems)
    {
        $subFolderItems = (Get-ChildItem $i.FullName | Measure-Object -property length -sum)
        $i.FullName + " -- " + "{0:N2}" -f ($subFolderItems.sum / 1MB) + " MB"
    }

This script runs fine but with certain folders I get an error saying:

Measure-Object : Property "length" cannot be found in any object(s) input.
At line:10 char:70
+         $subFolderItems = (Get-ChildItem $i.FullName | Measure-Object <<<<  -property length -sum)
    + CategoryInfo          : InvalidArgument: (:) [Measure-Object], PSArgumentException
    + FullyQualifiedErrorId : GenericMeasurePropertyNotFound,Microsoft.PowerShell.Commands.MeasureObjectCommand

What is the reason for this error and how to refine the script to overcome?

Upvotes: 2

Views: 7847

Answers (2)

POLLOX
POLLOX

Reputation: 302

I'm running it on Windows 7, and it works (cutting and pasting your code). Maybe there is a file with a "not good name" in your path?

Upvotes: -1

Joey
Joey

Reputation: 354406

You can use the -ErrorAction parameter for Measure-Object:

$subFolderItems = (Get-ChildItem $i.FullName | Measure-Object -property length -sum -ErrorAction SilentlyContinue)

or its alias -ea with a numeric value, which is nice for quickly adding it in interactive experimentation:

$subFolderItems = (Get-ChildItem $i.FullName | Measure-Object -property length -sum -ea 0)

In my humble opinion the script on Technet is very poor PowerShell code, though.

As a very quick and dirty (and slow) solution you can also use the following one-liner:

# Find folders
Get-ChildItem -Recurse | Where-Object { $_.PSIsContainer } |
# Find cumulative size of the directories and put it into nice objects
ForEach-Object {
    New-Object PSObject -Property @{
        Path = $_.FullName
        Size = [Math]::Round((Get-ChildItem -Recurse $_.FullName | Measure-Object Length -Sum -ErrorAction SilentlyContinue).Sum / 1MB, 2)
    }
} |
# Exclude empty directories
Where-Object { $_.Size -gt 0 } |
# Format nicely
Format-Table -AutoSize

Or actually as a one-liner:

gci -r|?{$_.PSIsContainer}|%{New-Object PSObject -p @{Path=$_.FullName;Size=[Math]::Round((gci -r $_.FullName|measure Length -s -ea 0).Sum/1MB,2)}}|?{$_.Size}|ft -a

Upvotes: 4

Related Questions