I wrote a powershell script that calculates the size of subfolders in a parent dir by recursively adding the filesizes of each file inside found using gci
function.
This works for most folders, except this folder:
"\Fall Out Boy - A Little Less Sixteen Candles, A Little More [Touch Me]"
Variable $curfoldersize
should be giving a value of 23089406
(22mb), but the function Get-FolderSize
returns 0 instead. For some reason the code only breaks on this folder, other folder names seem to work fine. I'm not sure what's causing the bug here.
# Parent Directory to find folders
$dirpath = "H:\Parent Dir\"
$logpath = "$PSScriptRoot\Logs\"
$logpath = -join($logpath, ($dirpath|split-path -leaf), ".txt")
# Maximum size of each folder (empty or non-empty)
$foldermaxsize = 19 # <- max size of each folder (e.g. 10 * 1MB = 10MB, 10 * 1KB = 10KB, etc)
$sizeunit = 1MB # <- size denominator (e.g. 1KB, 1MB, 1GB, etc)
$foldermaxsize = $foldermaxsize * $sizeunit
# returns size of single folder by summing all items (recursive) inside
Function Get-FolderSize {
# allows cmd options
[cmdletbinding()]
Param (
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline = $true)]
$folderpath
)
$size = 0
# calculate folder size and recurse as needed
Foreach ($file in $(gci $folderpath -recurse -Force)){
If (-not ($file.psiscontainer)) {
$size += $file.length
}
}
# return the value and go back to caller
return $size
}
# Array containing filepaths of each directory (recursive) found within $dirpath
# gci = GetChildItem
$Folders = @(gci $dirpath -Recurse | ?{ $_.PSIsContainer } | Select-Object -ExpandProperty FullName)
# Check for null results from cgi function
if ($Folders.length -eq 0) {
write-host " no folders."
} else {
# $folder = full path of current folder
ForEach ($folder in $Folders){
# returns int size of Folder (by recursively summing all child filesize)
$curfoldersize = Get-FolderSize $folder
Write-Output $curfoldersize
}
if ($Host.Name -eq "ConsoleHost")
{
Write-Host "Press any key to continue..."
$Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null
}
}
In this expression (foreach
loop source in your function):
gci $folderpath -recurse -Force
$folderpath
is not explicitly bound to any named parameter, and PowerShell implicitly binds it to -Path
.
From the Get-ChildItem
parameter documentation (emphasis added):
-Path
Specifies a path to one or more locations. Wildcards are accepted. The default location is the current directory (.).
[Touch Me]
happens to be a wildcard escape sequence describing one character with a value of either T
,o
,u
,c
,h
,
,M
, or e
.
To suppress wildcard expansion, bind the argument to the -LiteralPath
parameter instead:
gci -LiteralPath $folderpath -recurse -Force
-LiteralPath
Specifies a path to one or more locations. The value of LiteralPath is used exactly as it's typed. No characters are interpreted as wildcards.