Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Friday Fun: The Measure of a Folder

Posted on February 21, 2014

rulerLast week, I demonstrated how to measure a file with PowerShell. This week let's go a step further and measure a folder. I'm going to continue to use Measure-Object although this time I will need to use it to measure numeric property values.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

Here's the complete function after which I'll point out a few key points.

#requires -version 3.0

Function Measure-Folder {

<#
.SYNOPSIS
Measure the size of a folder.

.DESCRIPTION
This command will take a file path and create a custom measurement object that
shows the number of files and the total size. The default size will be in bytes
but you can specify a different unit of measurement. The command will format the
result accordingly and dynamically change the property name as well.

.PARAMETER Path
The default is the current path. The command will fail if it is not a FileSystem
path.

.PARAMETER Unit
The default unit of measurement is bytes, but you can use any of the standard
PowerShell numeric shortcuts: "KB","MB","GB","TB","PB"

.EXAMPLE
PS C:\> measure-folder c:\scripts 

Path            Name         Count         Size
----            ----         -----         ----
C:\scripts      scripts       2858     43800390

Measure the scripts folder using the default size of bytes.

.EXAMPLE

PS C:\> dir c:\scripts -Directory | measure-folder -Unit kb | Sort Size* -Descending | Select -first 5 | format-table -AutoSize

Path                     Name          Count          SizeKB
----                     ----          -----          ------
C:\scripts\GP            GP               40  2287.080078125
C:\scripts\Workflow      Workflow         64 1253.0185546875
C:\scripts\modhelp       modhelp           1  386.4970703125
C:\scripts\stuff         stuff             4       309.09375
C:\scripts\ADTFM-Scripts ADTFM-Scripts    76  297.7880859375

Get all the child folders under C:\scripts, measuring the size in KB. Sort the
results on the size property in descending order. Then select the first 5 objects
and format the results as a table.

.NOTES
Last Updated: 2/21/2014
Version     : 0.9

Learn more:
 PowerShell in Depth: An Administrator's Guide
 PowerShell Deep Dives 
 Learn PowerShell 3 in a Month of Lunches 
 Learn PowerShell Toolmaking in a Month of Lunches 

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

.LINK
https://jdhitsolutions.com/blog/2014/02/friday-fun-the-measure-of-a-folder

.LINK
Get-ChildItem
Measure-Object

.INPUTS
string or directory

.OUTPUTS
Custom object
#>
[cmdletbinding()]

Param(
[Parameter(Position=0,ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True)]
[ValidateScript({Test-Path $_})]
[Alias("fullname")]
[string]$Path=".",

[ValidateSet("Bytes","KB","MB","GB","TB","PB")]
[string]$Unit="Bytes"
)

Begin {
    Write-Verbose -Message "Starting $($MyInvocation.Mycommand)"  
} #begin

Process {
    $Resolved = Resolve-Path -Path $path
    $Name = Split-Path -Path $Resolved -Leaf

    #verify we are in the file system
    if ($Resolved.Provider.Name -eq 'FileSystem') {

    #define a hash table to hold new object properties
    $propHash = [ordered]@{
    Path=$Resolved.Path
    Name=$Name
    }

Write-Verbose "Measuring $resolved in $unit"

$stats = Get-ChildItem -Path $Resolved -Recurse -File | Measure-Object -sum length

Write-Verbose "Measured $($stats.count) files"

$propHash.Add("Count",$stats.count)
Switch ($Unit) {

"bytes" { $propHash.Add("Size",$stats.sum)       ; break }
"kb"    { $propHash.Add("SizeKB",$stats.sum/1KB) ; break }
"mb"    { $propHash.Add("SizeMB",$stats.sum/1MB) ; break }
"gb"    { $propHash.Add("SizeGB",$stats.sum/1GB) ; break }
"tb"    { $propHash.Add("SizeTB",$stats.sum/1TB) ; break }
"pb"    { $propHash.Add("SizePB",$stats.sum/1PB) ; break }

} #switch

#write the new object to the pipeline
New-Object -TypeName PSobject -Property $propHash

}
else {
    Write-Warning "You must specify a file system path."
}

} #process

End {
    Write-Verbose -Message "Ending $($MyInvocation.Mycommand)"
} #end

} #end function

The command will use the current path or you can pipe in a directory name, or the output of a Get-ChildItem expression as I show in the help examples. One thing I added is that I test the path to make sure it is a file system path because anything else wouldn't really work.

$Resolved = Resolve-Path -Path $path
$Name = Split-Path -Path $Resolved -Leaf

#verify we are in the file system
if ($Resolved.Provider.Name -eq 'FileSystem') {
    #define a hash table to hold new object properties
    $propHash = [ordered]@{
    Path=$Resolved.Path
    Name=$Name
    }
...
else {
        Write-Warning "You must specify a file system path."
    }

I resolve the path so that I can get the actual name of the current location (.) and then test the provider. The other interesting feature of this function is that I format the results on the fly.

The function has a Unit parameter which has a default value of bytes. But you can also specify one of the PowerShell numeric shortcuts like KB or GB. In the function I use a Switch construct to create a custom property on the fly.

Switch ($Unit) {

    "bytes" { $propHash.Add("Size",$stats.sum)       ; break }
    "kb"    { $propHash.Add("SizeKB",$stats.sum/1KB) ; break }
    "mb"    { $propHash.Add("SizeMB",$stats.sum/1MB) ; break }
    "gb"    { $propHash.Add("SizeGB",$stats.sum/1GB) ; break }
    "tb"    { $propHash.Add("SizeTB",$stats.sum/1TB) ; break }
    "pb"    { $propHash.Add("SizePB",$stats.sum/1PB) ; break }

 } #switch

Because there can only be a single value for $Unit, I'm including the Break directive so that PowerShell won't try to process any other potential matches in the Switch construct. Realistically, there's a negligible performance gain in this situation but I wanted you to see how this works.

PS C:\> dir D:\VM -Directory | measure-folder -Unit MB | Out-GridView -Title "VM Size"

measure-folder

I've taken some basic commands you could use interactively such as Get-ChildItem and Measure-Object and built a tool around them using a hashtable of properties to create a custom object. I hope you pick up a tip or two from this. If you have any questions about what I'm doing or why, please don't hesitate to ask because someone else might have the same question.

Enjoy your weekend!


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

1 thought on “Friday Fun: The Measure of a Folder”

  1. Pingback: POWERSHELL - Friday Fun: The Measure of a Folde...

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d