Total Pageviews

Thursday, November 19, 2020

PowerShell: Calculating folder size, file/folder count and size of each folder and subfolder

We often need to find the total number of files, folders or subfolders along with the total size for a given folder or drive. The PowerShell cmdlet “Get-ChildItem” can help us accomplish. The custom function “Get-FolderSize” described below is one potential solution:

Custom function Get-FolderSize: 

################################################
# To get number of files and folder size 
# Version: 1.0
# Date: 2020-11-19
################################################
function Get-FolderSize
{
	[CmdletBinding()]
	param (
		[Parameter(Mandatory = $true)]
		[string]$FolderPath = "D:\temp",
		
		[Parameter(Mandatory = $false)]
		[Switch]$SubFolder = $false		
	)

    $result = @()

    # Calculate parent folder grand total of all folder and file size, count
    $fileCount   = (Get-ChildItem $FolderPath -recurse | where-object {-not ($_.PSIsContainer)}).Count
    $folderCount = (Get-ChildItem $FolderPath -recurse | where-object { ($_.PSIsContainer)}).Count
    $mainFolder = Get-ChildItem -Path $FolderPath -Recurse | Measure-Object -Sum Length	
    $obj ="" | select Folder, FolderCount, FileCount, Size_kb, Size_mb, Size_gb
    
    $obj.Folder       = '.. Parent Folder ['+ $FolderPath +'] '+'Summary.. '
    $obj.FolderCount  = $FolderCount;
    $obj.FileCount    = $FileCount;
    $obj.Size_kb = $([Math]::Round($mainFolder.Sum / 1kb, 2));
    $obj.Size_mb = $([Math]::Round($mainFolder.Sum / 1mb, 2));
    $obj.Size_gb = $([Math]::Round($mainFolder.Sum / 1gb, 2));
    
    $result += $obj

	if ($SubFolder)
	{
		## size of each folder and each subfolders seperarely
		$folders = Get-ChildItem -ErrorAction SilentlyContinue $FolderPath -Recurse -force | `
    		Where-Object { $_.PSIsContainer -eq $true } | Sort-Object
	}
	else
	{
		# Size of each folder only
		$folders = Get-ChildItem -ErrorAction SilentlyContinue $FolderPath -force | `
		    Where-Object { $_.PSIsContainer -eq $true } | Sort-Object
	}

	foreach ($i in $folders)
	{        
        # sum of files and folder
		$subFolders = Get-ChildItem -ErrorAction SilentlyContinue $i.FullName -Recurse -force | `
            where-object {-not ($_.PSIsContainer)} |`
		    Measure-Object -property Length -sum | Select-Object Sum		
        # file counts
		$fileCount = (Get-ChildItem -ErrorAction SilentlyContinue $i.FullName -Recurse -force | `
		    where-object {-not ($_.PSIsContainer)}).Count
        # folder counts
		$folderCount = (Get-ChildItem -ErrorAction SilentlyContinue $i.FullName -Recurse -force | `
		    where-object { ($_.PSIsContainer)}).Count
            
        # empty object creation
        $obj ="" | select Folder, FolderCount, FileCount, Size_kb, Size_mb, Size_gb

        # assign value to objects
        $obj.Folder = $i.FullName;
        $obj.FolderCount  = $FolderCount;
        $obj.FileCount    = $FileCount;
        $obj.Size_kb = $([Math]::Round($subFolders.Sum / 1kb, 2));
        $obj.Size_mb = $([Math]::Round($subFolders.Sum / 1mb, 2));
        $obj.Size_gb = $([Math]::Round($subFolders.Sum / 1gb, 2));
    
        $result += $obj
	}	
    # return the objects
    return $result

}
# end of function creation

The function has two parameters:

  • $FolderPath: A mandatory parameter; it passes the folder or the drive name that we want to evaluate.
  • $SubFolder: An optional parameter; this conditional value will indicate whether to calculate each subfolder and file inside the original folder and will print separately.

Example of using Get-FolderSize:

Suppose we have a folder “d:\temp3” and this folder has multiple files and subfolders. Each subfolder may have more subfolders and files.

1. To get only the total size of each folder and the file counts from “d:\temp3”:

$Folders = "D:\Temp3"
Get-FolderSize -FolderPath $Folders 

2. To get the total size of each folder and the file counts from “d:\temp3” and then export the result to a CSV file: 

$Folders = "D:\Temp3"
Get-FolderSize -FolderPath $Folders|`
Export-Csv "D:\Export\foldersize.csv" -NoTypeInformation 

3. To get the total size of each folder, the file counts from “d:\temp3” and each subfolder: 

$Folders = "D:\Temp3"
Get-FolderSize -FolderPath $Folders -SubFolder 

4. To get the total size of each folder, the file counts from “d:\temp3” and each subfolder sorted by name: 

$Folders = "D:\Temp3"
Get-FolderSize -FolderPath $Folders -SubFolder sort Folder 

5. To get the total size of each folder, the file counts from “d:\temp3” and each subfolder sorted by name, using a custom display format: 

$fields = "Folder", `
    @{ N = "Folder (#)"; E = { '{0:N0}' -f $_.FolderCount }; Align = "right" }, `
    @{ N = "File (#)";   E = { '{0:N0}' -f $_.FileCount };   Align = "right" }, `
    @{ N = "Size (kb)";  E = { '{0:N2}' -f $_.Size_kb };     Align = "right" }, `
    @{ N = "Size (mb)";  E = { '{0:N2}' -f $_.Size_mb };     Align = "right" }, `
    @{ N = "Size (gb)";  E = { '{0:N2}' -f $_.Size_gb };     Align = "right" }

$Folders = "D:\Temp3"

# Get folder and subfolder size and format the output
Get-FolderSize -FolderPath $Folders -SubFolder | `
    sort Folder |`
     Format-Table $fields -Auto

Screenshot for visual appealing: 

Conclusion: I hope that you find this custom function useful. You can enhance and include additional parameters for this function to accommodate custom requirements. If you implement your own parameters, please send me a copy.

No comments:

Post a Comment