Summary: Microsoft MVP, Chad Miller, provides expert commentary for 2012 Scripting Games Advanced Event 4.
Microsoft Scripting Guy, Ed Wilson, is here. Chad Miller is the expert commentator for Advanced Event 4.
Chad is a senior manager of database administration at Raymond James Financial. Chad has worked with Microsoft SQL Server since 1999, and he has been automating administration tasks by using Windows PowerShell since 2007. Chad is a Windows PowerShell MVP and the project coordinator and developer of the Windows PowerShell-based CodePlex project, SQL Server PowerShell Extensions (SQLPSX). Chad leads the Tampa PowerShell User Group, and he is a frequent speaker at users groups, SQL Saturdays, and Code Camps.
Blog: Sev17—SQL Server, PowerShell, and so on
Twitter: @cmille19
The function Get-FolderSize reports the folder size of the specified folder and all subfolders. A path (folder) must be provided to the Get-FolderSize function.
To display the folder size for the current directory, use:
Get-FolderSize
To display folder size information for a list of folders, use:
Get-FolderSize Desktop,Downloads,DropBox
or
Get-Content folders.txt | Get-FolderSize
The code for this script is shown here:
#######################
<#
.SYNOPSIS
Gets folder size.
.DESCRIPTION
The Get-FolderSize function gets the folder size at the specified location.
.EXAMPLE
Get-FolderSize .
This command gets the folder size of the current directory. The dot (.) represents the item at the current location.
.EXAMPLE
Get-FolderSize C:\Windows
This command the folder size of the Windows directory.
.INPUTS
System.String
You can pipe a string that contains a path to Get-FolderSize.
.OUTPUTS
Selected.System.Management.Automation.PSCustomObject
.NOTES
Version History
v1.0 - Chad Miller - Initial release
#>
function Get-FolderSize
{
[CmdletBinding()]
param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[ValidateNotNullorEmpty()]
[string[]]$Path
)
BEGIN {
function Format-FolderSize
{
param($Size)
if ($Size -ge 1GB) {
"{0:N2} Gigabytes" -f $($Size/1GB)
}
elseif ($Size -ge 1MB) {
"{0:N2} Megabytes" -f $($Size/1MB)
}
else {
"{0:N2} Bytes" -f $Size
}
} #Format-FolderSize
}
PROCESS {
Get-Item $Path | Foreach-Object {$_; $_ | Get-Childitem -Recurse} |
Where-Object {$_.PSIsContainer} |
Select-Object FullName, @{name='Size';expression={$(Get-ChildItem $_.FullName -Recurse | Measure-Object -Sum -Property Length).Sum}} |
Sort-Object Size -Descending |
Select-Object @{name="Folder";expression={$_.FullName}}, @{name='Size of Folder';expression={$(Format-FolderSize -Size $_.Size)}}
}
END {}
} #Get-FolderSize
The main section of script is shown here:
The approach I took to solve this problem follows the structures of the PROCESS block of the script. I would start with step one and proceed to the next steps only when the results from the previous steps have been achieved.
- Use the Get-Item cmdlet to retrieve information about the specified path. The ForEach-Object cmdlet returns the item, and Get-ChildItem is called recursively to retrieve all child items.
- Apply a filter using Where-Object, which tests whether the PSIsContainer property is true, which means the item is of type directory.
- After we have the specified directory and all subdirectories, use select-object to retrieve the FullName property, and add a Size property by using a hash table with name and expression keys. The expression uses the Measure-Object cmdlet, summing on the Length property.
- Now sort the object by the newly added Size property.
- Finally, use the Select-Object cmdlet to emit a custom object with Folder and Size of Folder properties. The Size of Folder property makes use of the function Format-FolderSize, which is defined in the BEGIN block of Get-FolderSize. The Format-FolderSize handles formatting the folder size in the appropriate unit of measurement (gigabytes, megabytes, or bytes). By defining the Format-Folder function in the BEGIN block, the function is private and not visible outside of the Get-FolderSize function.
~Chad
The 2012 Scripting Games Guest Commentator Week will continue tomorrow when we will present the scenario for Event 5.
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