【问题标题】:Using PowerShell to replicate right clicking a folder and selecting properties使用 PowerShell 复制右键单击文件夹并选择属性
【发布时间】:2013-07-02 08:07:02
【问题描述】:

我正在尝试收集磁盘上的大小/大小以及非常大的文件夹树上的文件/文件夹数量。

我一直在使用如下脚本来收集其中的一些内容:

Get-ChildItem "C:\test" -recurse | Measure-Object -Sum Length | Select-Object `
  @{Name="Path"; Expression={$directory.FullName}},
  @{Name="Files"; Expression={$_.Count}},
  @{Name="Size"; Expression={$_.Sum}}

Path                                            Files                      Size
----                                            -----                      ----
C:\test                                         470                    11622961

但是当我想收集有关文件夹数量和磁盘大小的信息时,我必须运行一个单独的脚本;再次通过文件夹 tee 回避(这需要很长时间)。

是否有一种简单的方法可以访问所有这些信息,就像右键单击文件夹并选择下面显示的属性一样?

system32 中是否有任何可调用的 .exe 文件可以做到这一点?

【问题讨论】:

    标签: powershell properties directory exe


    【解决方案1】:

    根据 Technet 论坛中的this answer,您可以这样计算磁盘大小:

    $afz = [MidpointRounding]::AwayFromZero
    [math]::Round($_.Length / $clusterSize + 0.5, $afz) * $clusterSize
    

    $clusterSize 可以通过fsutil 命令确定(例如用于驱动器C:):

    PS C:\> fsutil fsinfo ntfsinfo C:\
    NTFS Volume Serial Number :       0x648ac3ae16817308
    Version :                         3.1
    Number Sectors :                  0x00000000027ccfff
    Total Clusters :                  0x00000000004f99ff
    Free Clusters  :                  0x0000000000158776
    Total Reserved :                  0x00000000000003e0
    Bytes Per Sector  :               512
    Bytes Per Physical Sector :       512
    Bytes Per Cluster :               4096
    Bytes Per FileRecord Segment    : 1024
    Clusters Per FileRecord Segment : 0
    ...

    请注意,运行fsutil 需要管理员权限。

    您可以这样收集您感兴趣的信息:

    $rootDir = "C:\test"
    
    $afz = [MidpointRounding]::AwayFromZero
    $clusterSize = fsutil fsinfo ntfsinfo (Get-Item $rootDir).PSDrive.Root `
      | Select-String 'Bytes Per Cluster' `
      | % { $_.ToString().Split(':')[1].Trim() }
    
    $stat = Get-ChildItem $rootDir -Recurse -Force `
      | select Name, Length, @{n="PhysicalSize";e={
          [math]::Round($_.Length / $clusterSize + 0.5, $afz) * $clusterSize
        }}, @{n="Folder";e={[int]($_.PSIsContainer)}},
        @{n="File";e={[int](-not $_.PSIsContainer)}} `
      | Measure-Object -Sum Length, PhysicalSize, Folder, File
    
    $folder = New-Object -TypeName PSObject -Property @{
        "FullName"   = $rootDir;
        "Files"      = ($stat | ? { $_.Property -eq "File" }).Sum;
        "Folders"    = ($stat | ? { $_.Property -eq "Folder" }).Sum;
        "Size"       = ($stat | ? { $_.Property -eq "Length" }).Sum;
        "SizeOnDisk" = ($stat | ? { $_.Property -eq "PhysicalSize" }).Sum - $clusterSize;
      }
    

    【讨论】:

    • 除了“磁盘大小”计算没有给出正确的值外,效果很好。当您手动查看文件夹属性值时,它大约是 +0.5%。
    • 看来您必须从结果中减去集群大小。您还必须将-Force 添加到Get-ChildItem 以包含隐藏文件。
    • 是的,它改进了结果,使其在手动查找的 +0.03% 范围内
    【解决方案2】:

    当您看到每个项目时,您将不得不在自定义对象中累积数据:

    $path = "C:\Users\aaron\Projects\Carbon"
    $properties = New-Object PsObject -Property @{ 'Path' = $path; 'Files' = 0; 'Folders' = 0; 'Size' = 0 }
    Get-ChildItem -Path $path -Recurse |
        ForEach-Object {
            if( $_.PsIsContainer )
            {
                $properties.Folders++
            }
            else
            {
                $properties.Size += $_.Length
                $properties.Files++
            }
        }
    $properties
    

    【讨论】:

    • +1 这项工作做得很好,你知道无论如何要获得“磁盘上的大小”吗?
    • @RichardOsborn 我不知道。我在您的未来看到另一个 Google 搜索或 StackOverflow 问题... :-)
    猜你喜欢
    • 2016-11-01
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多