-
Notifications
You must be signed in to change notification settings - Fork 94
/
Copy pathGet-FolderSize.ps1
118 lines (104 loc) · 3.91 KB
/
Get-FolderSize.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# https://social.technet.microsoft.com/Forums/scriptcenter/en-US/333f63ca-a7e0-4d92-b18d-133fd4953af7/export-with-foreach-not-working-then-send?forum=ITCG
# http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/05/weekend-scripter-sorting-folders-by-size.aspx
# https://www.linkedin.com/pulse/technical-thursdays-get-directory-sizes-stupidly-fast-carlos-nunez?trk=sushi_topic_posts_guest
function Get-FolderSize {
[cmdletbinding()]
param (
$Path = $PWD,
[validateset('GCI', 'Robocopy', 'FSO', 'All')]
$Use = 'Robocopy'
)
begin {
<# Commented out because if a file is given, FSO errors into GCI which can handle files.
if ([System.IO.File]::Exists($Path)) {
if (!(Test-Path $Path -PathType Container)) {
Throw "$Path is not a directory."
}
}#>
function Resolve-FullPath ($Path = $PWD) {
if ( -not ([IO.Path]::IsPathRooted($Path)) ) {
$Path = Join-Path (Get-Location) $Path
}
[IO.Path]::GetFullPath($Path)
}
function Get-FolderSizeFSO ($Path = $PWD) {
begin {
$fso = New-Object -ComObject scripting.filesystemobject
}
process {
New-Object psobject -prop @{
Path = $Path
Count = $null
Size = $fso.GetFolder($Path).size
}
}
end {
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($fso)
[gc]::Collect()
}
}
function Get-FolderSizeGCI ($Path = $PWD) {
$items = Get-ChildItem $Path -Recurse -Force | ? {!$_.psiscontainer}
New-Object psobject -prop @{
Path = $Path
Count = $items.count
Size = ($items | Measure-Object -sum length).sum
}
}
function Get-FolderSizeRobocopy ($Path = $PWD) {
$lines = robocopy $Path NULL * /L /S /NJH /NFL /NDL /BYTES | ? {$_ -match '(?:Files|Bytes) :'}
$hash = @{
Path = $Path
Count = $null
Size = $null
}
$lines | % {
switch -Regex ($_) {
'Files :\s+(\d+)' {$hash['Count'] = $Matches[1]}
'Bytes :\s+(\d+)' {$hash['Size'] = $Matches[1]}
}
}
New-Object psobject -prop $hash
}
}
process {
$Path = Resolve-FullPath $Path
# remove trailing \
$Path = $Path -replace '\\$'
switch ($Use) {
'All' {
try {
$fso = Get-FolderSizeFSO $Path | select *, @{n='Use';e={'FSO'}}
if ($fso.size) {
$fso
} else {
1/0 # force into Robocopy
}
} catch {
try {
$robo = Get-FolderSizeRobocopy $Path | select *, @{n='Use';e={'Robocopy'}}
if ($robo.size) {
$robo
} else {
1/0 # force into GCI
}
} catch {
try {
Get-FolderSizeGCI $Path | select *, @{n='Use';e={'GCI'}}
} catch {
New-Object psobject -prop @{
Path = $Path
Count = $null
Size = $null
Use = 'Error'
}
}
}
}
}
'FSO' {Get-FolderSizeFSO $Path}
'GCI' {Get-FolderSizeGCI $Path}
'Robocopy' {Get-FolderSizeRobocopy $Path}
}
}
}