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.