2

I have this Function that takes a path input, and gives you the size of it. There are 3 different options you can choose from which are:

  1. 'GCI' - Get-ChildItem
  2. 'DIR' - CMD's DIR command
  3. 'ROBO' - Robocopy.exe

GCI, and DIR are identical almost everytime but, ROBO (Robocopy.exe) is so inconsistent on how it calculates different directories.

Function Get-DirectorySize {
    Param (
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [ValidateScript({Test-Path -Path $_})]
        [Alias('Location')]
        [String[]]$FilePath,


        [Parameter(Mandatory=$false)]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('GCI','DIR','ROBO')]
        [String]$Option

    )

    Process {
        Foreach ($Path in $FilePath) {
            Try {

                if ($PSBoundParameters.ContainsKey('Option')) {

                    if ($PSBoundParameters.ContainsValue('GCI')){

                        $Start_Time = Get-Date -Format G
                        $File_Count = (Get-ChildItem $Path -Recurse -force -erroraction SilentlyContinue | Measure-Object length -Sum).sum

                    }
                    elseif ($PSBoundParameters.ContainsValue('DIR')) {

                        $Start_Time = Get-Date -Format G
                        $File_Count = ((cmd /c dir $Path /-C /S /A:-D-L)[-2] -split '\s+')[3]


                    }
                    elseif ($PSBoundParameters.ContainsValue('ROBO')){

                        $Start_Time = Get-Date -Format G
                        $File_Count = (robocopy.exe $Path C:\FakePath /L /XJ /R:2 /W:1 /NP /E /BYTES /NFL /NDL /NJH /J /MT:128)[-4] -replace '\D+(\d+).*','$1'

                    }
                    

                }
                else {

                    $Start_Time = Get-Date -Format G
                    $File_Count = (Get-ChildItem $Path -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object length -Sum).sum

                }

            }
            Catch {
                
                $Error[0].Exception.Message.Split('.')[1].Trim()


            }
            Finally {

                [PSCustomObject]@{
                    
                    'File Path'  = $Path 
                    'File Size'  = Get-Size -ProcessBytes $File_Count
                    'Start Time' = $Start_Time
                    'End Time'   = Get-Date -Format G

                }

            }
        
        }

    }

}

This is the output of some of the Directories I tested:

PS C:\WINDOWS\system32> Get-DirectorySize -FilePath C:\ -Option GCI

File Path File Size Start Time           End Time            
--------- --------- ----------           --------            
C:\       210.84 GB 6/26/2021 5:29:58 PM 6/26/2021 5:30:39 PM



PS C:\WINDOWS\system32> Get-DirectorySize -FilePath C:\ -Option DIR

File Path File Size Start Time           End Time            
--------- --------- ----------           --------            
C:\       210.84 GB 6/26/2021 5:30:42 PM 6/26/2021 5:31:00 PM



PS C:\WINDOWS\system32> Get-DirectorySize -FilePath C:\ -Option ROBO

File Path File Size Start Time           End Time            
--------- --------- ----------           --------            
C:\       213.24 GB 6/26/2021 5:31:06 PM 6/26/2021 5:31:11 PM



PS C:\WINDOWS\system32> Get-DirectorySize -FilePath C:\Users -Option GCI

File Path File Size Start Time           End Time            
--------- --------- ----------           --------            
C:\Users  137.63 GB 6/26/2021 5:31:21 PM 6/26/2021 5:31:27 PM



PS C:\WINDOWS\system32> Get-DirectorySize -FilePath C:\Users -Option DIR

File Path File Size Start Time           End Time            
--------- --------- ----------           --------            
C:\Users  137.63 GB 6/26/2021 5:31:35 PM 6/26/2021 5:31:37 PM



PS C:\WINDOWS\system32> Get-DirectorySize -FilePath C:\Users -Option ROBO

File Path File Size Start Time           End Time            
--------- --------- ----------           --------            
C:\Users  133.21 GB 6/26/2021 5:31:41 PM 6/26/2021 5:31:41 PM

Am I in the wrong here on how I am calculating the directory sizes?

Function Get-Size{
    [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$false,
                       ValueFromPipeline=$true,
                       ValueFromPipelineByPropertyName=$true)]
            [Int64]$ProcessBytes    
            )
    Process{
        Switch ($ProcessBytes){
            {$ProcessBytes -lt 1MB}                             { "$([Math]::Round($ProcessBytes / 1KB, 2)) KB" }
            {$ProcessBytes -ge 1MB -and $ProcessBytes -lt 1GB}  { "$([Math]::Round($ProcessBytes / 1MB, 2)) MB" }
        Default                                                 { "$([Math]::Round($ProcessBytes / 1GB, 2)) GB" }
            
        }
    }
}

Please Note: I am aware this isn't the purpose of Robocopy but, I find it useful how it cuts the time to a fraction of the time it would've taken GCI, or DIR to complete (due to multi-threading).

2
  • 1
    Just curious, when executing these do you get any errors?, also I am not overly familiar with the parameters you are passing to robocopy but is it possible that files that are less than 4kb are actually being calculated as 4kb?
    – CraftyB
    Commented Jun 27, 2021 at 20:53
  • No errors, just some skipped files. The byte size is calculated at the end as a whole, don't think that would effect it. Just so odd to me, would be cool if I can figure it out tho, took me 5 seconds to calculate my C:\ using RoboCopy lol Commented Jun 27, 2021 at 21:18

0

You must log in to answer this question.

Browse other questions tagged .