I recently picked up Windows PowerShell in Action, Second Edition by Bruce Payette.  I had kept running into situations where I was hearing “oh, you can do that with PowerShell”.  So I finally started learning it … and boy am I glad I did.

The book arrived Monday, but I didn’t get a chance to open it until Friday afternoon.  Spent maybe an hour reading, and once Bruce started giving examples, I started seeing places to use it.

Background: My new file server uses “File Server Resource Manager” … it’s awesome enough that it’ll get it’s own post eventually.  That aside, one of the cool things it does for me is alert me when one of my users redirected mydocs folder goes over 1GB.

Great … they’ve got over 1GB … but how do I help my user address that?  Is that a legitimate use or is that stuff a massive itunes library?

Intro this script

$totals=@{“”=0}
$a = dir -recurse |
ForEach-Object {
if ($totals.containskey($_.Extension))
{$totals.set_item($_.Extension,$totals.($_.Extension)+($_.length/1024/1024))}
else
{$totals.add($_.Extension,($_.length/1024/1024))}
}
$totals.GetEnumerator() | sort-object value -descending

I navigate to the directory in question, run the script, and it spits out a list of each extension and how many MB of space.  So, it could return something like this:

Name                           Value
—-                           —–
.mov                           2141.24276733398
.exe                           1412.19039440155
.jpg                           124.121984481812
.pdf                           115.56226348877
.pptx                          90.9763250350952
.rtf                           89.3738861083984
.wmv                           84.065318107605
.tif                           70.1723976135254
.ppt                           47.2802734375
.bmp                           30.1264171600342
.doc                           27.3607778549194
.msi                           19.47216796875
.xls                           13.798828125
.pub                           11.45751953125
.docx                          6.17255210876465
.xlsx                          3.0872917175293

This is incredibly helpful to me.  2,141 MB in .mov files?

In powershell I type

dir -recurse -filter “*.mov”

And it shows me a list of all those MOV files, where they are, and how big each is.

If I do that for a few file type, I can now sit down with my user and help them clean up their data.

So, how the heck does that script work?

$totals=@{“”=0}

This just initializes a hash table … an array that stores pairs of key/value.  In this example, the key is the extension, and the value is the size.

$a = dir -recurse | ForEach-Object {

Recurse through all subdirectories, stick it in a variable “a”, and then for each file…

if ($totals.containskey($_.Extension))

if I’ve already found a file with this extension …

$totals.set_item($_.Extension,$totals.($_.Extension)+($_.length/1024/1024))

Then just add the size of the file (converted into MB) to the total so far

else

However, if this is the first file with this extension

$totals.add($_.Extension,($_.length/1024/1024))

Then create a new key/value pair for that extension type (with that file’s size).

$totals.GetEnumerator() | sort-object value -descending

And when we’re done, spit out all the key/value pairs, sorted by the size, largest first.