为什么使用 Robocopy.exe 计算文件夹大小会给出与 Get-ChildItem 不同的结果?

为什么使用 Robocopy.exe 计算文件夹大小会给出与 Get-ChildItem 不同的结果?

我有这个函数,它接受路径输入,并给你尺寸的。有 3 种不同的选项可供选择,分别是:

  1. 气相色谱'-Get-ChildItem
  2. 目录'-CMD 的 DIR 命令
  3. 机器人'-复制工具

气相色谱, 和目录几乎每次都一样,但是,机器人复制工具) 在计算不同目录的方式上存在很大不一致。

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

                }

            }
        
        }

    }

}

这是我测试的一些目录的输出:

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

我错了吗?正在计算目录大小吗?

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" }
            
        }
    }
}

请注意:我知道这不是Robocopy但我发现它很有用,因为它将时间缩短到 GCI 或 DIR 完成时间的一小部分(由于多线程)。

相关内容