我是PowerShell的相对新手,想进一步了解函数,CmdLet和人类可读的值。通常是为了学习新事物,看别人做的好。
因此,我去寻找了一个Get-DiskUsage CmdLet的源。
我可以 。将其来源到PowerShell中,然后调用该函数。
无论如何,它总是使用当前目录来获取结果,无论我如何称呼它。
我缺少它不会采用给定的-Path参数吗?
PS D:\bin> . .\DiskUsage.ps1
PS D:\bin> Get-DiskUsage -Path D:\ -h
Size Folder
---- ------
405M
PS D:\bin> Get-DiskUsage -Path C:\ -h
Size Folder
---- ------
405M
PS D:\bin> C:
PS C:\> Get-DiskUsage -Path C:\ -h
Size Folder
---- ------
18G
PS C:\>
脚本输出不正确,因为SysInternals DiskUsage工具du显示如下:
D:\bin>du C:\
Du v1.4 - report directory disk usage
Copyright (C) 2005-2011 Mark Russinovich
Sysinternals - www.sysinternals.com
Files: 93367
Directories: 22541
Size: 21.817.875.778 bytes
Size on disk: 22.127.992.832 bytes
D:\bin>du D:\
Du v1.4 - report directory disk usage
Copyright (C) 2005-2011 Mark Russinovich
Sysinternals - www.sysinternals.com
Files: 132832
Directories: 15125
Size: 130.137.231.457 bytes
Size on disk: 54.992.396.288 bytes
D:\bin>du D:\bin
Du v1.4 - report directory disk usage
Copyright (C) 2005-2011 Mark Russinovich
Sysinternals - www.sysinternals.com
Files: 3118
Directories: 222
Size: 424.866.944 bytes
Size on disk: 288.858.112 bytes
最佳答案
Get-DiscUsage C:\ # NOT RECOMMENDED
Get-DiskUsage -Path C:\Users\JBennett\SkyDrive\WindowsPowershell\Scripts\IO\
Size Folder
---- ------
223424B C:\Users\JBennett\SkyDrive\WindowsPowershell\Scripts\IO\DU
两种方法都对我有效(如您所说,在首先对脚本进行点源采购之后)。
不过,我不得不说,我不会使用它…使用PowerShell进行递归目录扫描,生成(数千个)DirectoryInfo对象,然后在每个文件夹上进行另一个递归目录扫描,创建一个新对象并求和属性...与du.exe相比,它速度慢得令人难以置信,并且会消耗大量内存和IO
更好的方法
当您要递归地希望树中每个文件夹的大小时,这样做的算法正确方法不涉及Get-ChildItem的-Recurse标志。您可能会执行以下操作:
function Get-Size {
#.Synopsis
# Calculate the size of a folder on disk
#.Description
# Recursively calculate the size of a folder on disk,
# outputting it's size, and that of all it's children,
# and optionally, all of their children
param(
[string]$root,
# Show the size for each descendant recursively (otherwise, only immediate children)
[switch]$recurse
)
# Get the full canonical FileSystem path:
$root = Convert-Path $root
$size = 0
$files = 0
$folders = 0
$items = Get-ChildItem $root
foreach($item in $items) {
if($item.PSIsContainer) {
# Call myself recursively to calculate subfolder size
# Since we're streaming output as we go,
# we only use the last output of a recursive call
# because that's the summary object
if($recurse) {
Get-Size $item.FullName | Tee-Object -Variable subItems
$subItem = $subItems[-1]
} else {
$subItem = Get-Size $item.FullName | Select -Last 1
}
# The (recursive) size of all subfolders gets added
$size += $subItem.Size
$folders += $subItem.Folders + 1
$files += $subItem.Files
Write-Output $subItem
} else {
$files += 1
$size += $item.Length
}
}
# in PS3, use the CustomObject trick to control the output order
if($PSVersionTable.PSVersion -ge "3.0") {
[PSCustomObject]@{
Folders = $folders
Files = $Files
Size = $size
Name = $root
}
} else {
New-Object PSObject -Property @{
Folders = $folders
Files = $Files
Size = $size
Name = $root
}
}
}
这样一来,您列出的内容不会超过一次。缺点是您必须自己添加所有内容,因为您不能仅使用Measure-Object。
实际上,OP中引用的脚本会列出每个项目,无论深度如何。也就是说,如果文件位于C:\ Users \ Jaykul \ Documents \ WindowsPowerShell \ Scripts ...中,则它将在每个父文件夹的
gci -recurse
中显示-如果您在根目录上调用该脚本,则会显示五次。当然,您仍在为每个文件创建一个FileInfo,为每个目录创建DirectoryInfo,再加上我在脚本中手动创建的摘要PSObject,因此,即使它的速度几乎与du.exe一样快,它的性能也会大大提高。对内存的影响。
但是,这是PowerShell中固有的权衡:做事更容易...因为我们有沉重的物体。我们很高兴将易用性换成内存,有时甚至会降低性能。就是说:是的,du.exe会更快,但是这是一个单招小马,有人必须专门为某个目的编写。如果您只想运行它并读取输出,那仍然是最好的方法。但是它会产生文本输出,如果您想在脚本中使用它,则必须解析该文本输出,并且实际上很难将这些信息收集为整个仪表板样式的监视脚本的输出的一部分...
关于powershell - PowerShell Get-DiskUsage CmdLet:如何从其他驱动器/目录列出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16178919/