Monday, 5 October 2009

Get-FolderSize.ps1

  1. <#
  2. .SYNOPSIS
  3. This script displays the size of a folder
  4. .DESCRIPTION
  5. This script is a rewrite of an MSDN sample. It
  6. uses System.IO namespace to determine the size
  7. of a folder and its subfolders, then displays it.
  8. Note that the Get-DirSize function is recursive!
  9. .NOTES
  10. File Name : Get-FolderSize.ps1
  11. Author : Thomas Lee - tfl@psp.co.uk
  12. Requires : PowerShell V2
  13. .LINK
  14. This script posted to: http://pshscripts.blogspot.com/2009/10/get-foldersizeps1.html
  15. MSDN Sample posted at: http://msdn.microsoft.com/en-us/library/system.io.directory.aspx

  16. .EXAMPLE
  17. PSH [C:\foo]: .Get-FolderSize c:\foo
  18. The size of C:\Foo and its subdirectories is 17,577,318 bytes
  19. #>

  20. param (
  21. $folder = "C:\Foo"
  22. )

  23. ##
  24. # Helper Function Get-DirSize
  25. ##
  26. function Get-DirSize {
  27. param ([system.IO.DirectoryInfo] $d)
  28. [long] $Size = 0;

  29. # Add file sizes.
  30. $fis = $d.GetFiles();
  31. foreach ($fi in $fis){
  32. $size += $fi.Length;
  33. }
  34. # Add subdirectory sizes recursively.
  35. $dis = $d.GetDirectories()
  36. foreach ($di in $dis) {
  37. $Size += Get-DirSize($di)
  38. }
  39. return $Size
  40. }

  41. ## End of Get-DirSize helper function

  42. ##
  43. # Start of Script
  44. $d = New-Object system.IO.DirectoryInfo $folder
  45. $size= Get-Dirsize $d
  46. "The size of {0} and its subdirectories is {1} bytes" -f $d,$size.ToString("###,###")

8 comments:

garth arnold said...

Note - declare $Size as long if >2GB of files per folder.

Thomas said...

Garth - great catch - sample updated to reflect this!

Larry__Weiss said...

Is line 31 correct? Currently
n] $Size = 0;

Thomas said...

Larry - a typo that must have sneaked in after I created the sample. Thanks for the catch.

Garth said...

Hmm, did that 'correction' remove the [long] declaration for $Size that you added on October 6?

Thomas said...

Garth - well caught. Not my day I guess. But thanks for the catch and this is fixed.

microsoft.public said...

Hi Thomas,

How different is the below code from yours? I saw we could do recoursion through inbuilt PS command get-childitem rather than creating a function.

Param ($folder = "C:\test")

Function Get-Files()
{
param ([System.IO.DirectoryInfo] $d)

$files = dir $d -Recurse -Force | ?{$_.attributes -ne "Directory"}
return $files;

}

$xyz = New-Object System.IO.DirectoryInfo $folder

$files = Get-Files $xyz

[long]$size = 0;

foreach ($fi in $files) { $size += $fi.length}
"Total number of files are {0} and total size of the folder is {1} Bytes " -f $files.length, $size.tostring('##,##');

MAD said...

Thanks :-) this helped a lot :-)

I've tweaked it and the following would display the size of all profiles installed on a workstation:

param (
$folder = "C:\Documents and settings"
)

##
function Get-DirSize {
param ([system.IO.DirectoryInfo] $d)
[long] $Size = 0;


# Add file sizes.
$fis = $d.GetFiles();
foreach ($fi in $fis){
$size += $fi.Length;
}
# Add subdirectory sizes recursively.
$dis = $d.GetDirectories()
foreach ($di in $dis) {
$Size += Get-DirSize($di)
}
return $Size
}

# Start of Script

$a = New-Object system.IO.DirectoryInfo $folder
$aa = $a.GetDirectories()
foreach ($ab in $aa) {
$subf = $folder + "\" + $ab.Name

$d = New-Object system.IO.DirectoryInfo $subf
$size= Get-Dirsize $d
"{0} : {1:N2} " -f $d,($size / 1MB) + "MB"
}