我在PowerShell中的相对新手,想知道多一点功能,cmdlet,但人类可读的值。 通常对于学习新的东西,看着别人怎么做效果很好。
所以我去寻找并撞到源的获取,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工具都显示:
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对象,然后它做的是另递归目录扫描在每个文件夹,创建一个新的对象,总结性......这是可怕慢,而且会消耗大量的内存和IO相比du.exe
稍微好一点的办法
如果你想在一棵树的每个文件夹的大小,递归,做到这一点的算法正确的方式不涉及对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
}
}
}
这样一来,你不是什么上市不止一次。 不利的一面是,你必须添加了一切自己,因为你不能只使用测量-对象。
在OP中引用的脚本实际上不过很多时候它是深列出每个项目。 也就是说,如果一个文件位于C:\用户\ Jaykul \文档\ WindowsPowerShell \ Scripts中......它会在显示gci -recurse
每个父文件夹-五次如果调用根的脚本。
当然,你还为每个文件和每个目录一个DirectoryInfo,再加上我的手在脚本创建的总结PSObject创建一个FileInfo,因此,即使这是几乎一样快du.exe,那就得显著更多对记忆的影响。
然而,这是固有的权衡在PowerShell中:这是容易做到的事......因为我们有重物。 我们高兴地贸易的易用性存储器,有时甚至影响性能。 这就是说:是的,du.exe会更快,但它是一招的小马,有人专门写一个目的。 它仍然是最好的方式,如果你想要做的一切都运行它,并读取输出。 但它产生你要解析,如果你想使用它在脚本输出文本输出,这真的很难收集信息作为整体仪表板风格的监控脚本输出的一部分...
我将Get-DiskUsage脚本的创作者。 我诚实地不知道为什么它不走-Path你。 对我来说工作正常。 真是奇怪。 快速的问题虽然 - 你尝试输入路径为d:而不是d:\?
@Jaykul - 这样做的很不错的替代方式。 我必须承认,我不知道在recusion使用递归的内存命中。 我总是记缓慢的事实,即$结果没有得到输出直到所有其他caclulations齐全。 我之所以做了递归,然后再很简单 - 第一递归列出了从ROOTPATH所有文件夹(会使列表),第二个我注意到,我需要的,因为如果我不结果将是一个大小并不总是准确
我喜欢Jaykul的答案,但它在PS 2.0中的错误,当一个目录是空的,它返回错误的答案。 我还修改了它支持力控开关和深度交换机而不是递归的,类似于原来的获取,DiskUsage脚本。
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=$PWD,
# Show the size for each descendant recursively (otherwise, only immediate children)
[Int]$Depth=1,
[Switch]$Force
)
# Get the full canonical FileSystem path:
$root = Convert-Path $root
$DetailDepth = $Depth - 1
$size = 0
$files = 0
$folders = 0
$items = Get-ChildItem $root -Force:$Force
foreach($item in $items) {
if($item.PSIsContainer) {
# Clear subItem in case the directory is empty.
$subItem = @{ Folders = 0
Files = 0
Size = 0
Name = $item.FullName }
# 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($DetailDepth -ge 1) {
Get-Size $item.FullName -Depth $DetailDepth -Force:$Force | Tee-Object -Variable subItems
if($subItems.GetType().FullName -eq "System.Management.Automation.PSCustomObject") {
$subItem = $subItems
} else {
$subItem = $subItems[-1]
}
} else {
$subItem = Get-Size $item.FullName -Force:$Force | Select -Last 1
}
# The (recursive) size of all subfolders gets added
$size += $subItem.Size
$folders += $subItem.Folders + 1
$files += $subItem.Files
# avoid duplication by letting the parent report the summary values, except at the lowest detail depth
if( $DetailDepth -lt 1) {
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
}
}
}
文章来源: PowerShell Get-DiskUsage CmdLet: how to list from a different drive/directory?