Search code examples
windowspowershellget-childitem

Powershell, GCI bugging out? Non-empty Folder size returns 0


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.

Folder contents: enter image description 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
}

}

Solution

  • 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.