Summary: Microsoft Scripting Guy, Ed Wilson, uses Windows PowerShell 3.0 to sort folders by size.
Microsoft Scripting Guy, Ed Wilson, is here. It is amazing how things continue to go in circles … I know I have written a script to sort folders by size many times in many different languages. I recently ran across a function written by Jeff Wouters that caused me to decide to write this script yet again.
It may be partially because, hey, it is the weekend, and on the weekends, I like to play around with Windows PowerShell (my buddy Don Jones used to write a column called PowerShell with a purpose—well, when I am playing around on the weekend, I could call it PowerShell without a purpose … but then I would never purposefully infringe on anyone’s title. (OK, so I have now given credit to Jeff and to Don … so now on with the blog post).
Use the FileSystem object to find folder sizes
I know that I knew this … but hey, I forget stuff after a while. I mean, I wrote two books on VBScript (three if you count my WMI book as well), so I am certain that I knew this. The thing is that I had forgotten about it until I saw Jeff’s script on his blog.
The old-fashioned COM object, Scripting.FileSystemObject returns a folder size. With this in mind, I need to use the New-Object cmdlet with the –comobject parameter to create an instance of the filesystemobject, as shown here.
$fso = New-Object -ComObject scripting.filesystemobject
The next thing I need to do is to get a listing of the paths to the folders I am interested in exploring. I do this by using the Windows PowerShell 3.0 syntax to return directories only. I am interested in the folders as well as the subfolders, so I use the –recurse parameter. This command is shown here.
Foreach($folder in (Get-ChildItem $path -Directory -Recurse))
I create a custom psobject that contains two properties. The first property is the path to the folder (I call it name) and the second property is the size of the folder in megabytes (stored in a property called size). The GetFoldermethod from the FileSystemObject requires a string that is the path to the folder. I use the FullNameproperty obtained by the Get-ChildItem cmdlet and turn it into a string by calling the ToStringmethod.
I then pick up the path itself from the folder object returned by the GetFolder method. I do essentially the same thing to get the folder size; that is, I pass the FullName as a string to the GetFoldermethod. I pick the sizeproperty from the returned folderobject. But I also turn it into megabytes by using the MB admin constant. The easy way to get whole numbers is to cast the returned size to an integer, and this is what I do with the [int] type accelerator. This code is shown here.
New-Object -TypeName psobject -Property @{
name=$fso.GetFolder($folder.FullName.tostring()).path;
size=[int]($fso.GetFolder($folder.FullName.ToString()).size /1MB)}
The last thing I do is sort the folders by size. I also filter the size so that only folders that are larger than 1000 MB return. This code is shown here.
$folders | sort size -Descending | ? size -gt 1000
The entire Get-FolderSizes.PS1 script is shown here.
#requires -version 3.0
$path = "c:\data"
$fso = New-Object -ComObject scripting.filesystemobject
$folders = Foreach($folder in (Get-ChildItem $path -Directory -Recurse))
{
New-Object -TypeName psobject -Property @{
name=$fso.getFolder($folder.fullname.tostring()).path;
size=[int]($fso.GetFolder($folder.FullName.ToString()).size /1MB)}
}
$folders | sort size -Descending | ? size -gt 1000
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy