{"id":3113,"date":"2013-08-03T00:01:00","date_gmt":"2013-08-03T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/08\/03\/weekend-scripter-use-powershell-to-get-folder-sizes\/"},"modified":"2013-08-03T00:01:00","modified_gmt":"2013-08-03T00:01:00","slug":"weekend-scripter-use-powershell-to-get-folder-sizes","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/weekend-scripter-use-powershell-to-get-folder-sizes\/","title":{"rendered":"Weekend Scripter: Use PowerShell to Get Folder Sizes"},"content":{"rendered":"<p><strong style=\"font-size: 12px\">Summary<\/strong><span style=\"font-size: 12px\">: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to get folder sizes.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. I was talking via Lync to my friend Rolf in Munich, Germany the other day. He said the temperatures were approaching 100 degrees Fahrenheit. We have been lucky in Charlotte, North Carolina&mdash;we have not made it out of the 90s yet. Still, anything over 80 degrees Fahrenheit is hot in my mind. Oh well, every year it is the same down here. August rolls around, and the mercury rises.<\/p>\n<p>In much the same way, certain Windows PowerShell questions keep coming around. Not exactly on a calendar type of schedule, but they do crop up again and again. These predictable questions are due to the fact that no great solution exists for the issue.<\/p>\n<p>A perfect case-in-point is the issue of determining folder sizes. There is no <strong>Get-FolderSize<\/strong> cmdlet, and <strong>Get-ChildItem<\/strong> does not return a folder size on the <strong>DirectoryInfo<\/strong> object. For the same reason that Windows Explorer is slow when showing folder size information, there is no direct way of obtaining the information. It is not cached anywhere, and therefore, it must be calculated.<\/p>\n<p><a href=\"http:\/\/social.technet.microsoft.com\/Search\/en-US?query=folder%20size&amp;beta=0&amp;rn=Hey%2c+Scripting+Guy!+Blog&amp;rq=site:blogs.technet.com\/b\/heyscriptingguy\/&amp;ac=2\" target=\"_blank\">In previous Hey, Scripting Guy! Blog posts<\/a>, I have enumerated all files in a folder, and returned the folder size information. I have also used the <strong>FileSystemObject<\/strong>. Today, I want to create a simple function that accepts pipelined input. This may prove useful for you.<\/p>\n<h2>The Scripting.FileSystemObject returns a folder size<\/h2>\n<p>One way to avoid enumerating files and adding up their sizes is to use a method that returns a folder size directly. This is where using the old-fashioned <strong>FileSystemObject <\/strong>comes into play. The reason I decided to create the function to accept pipelined input is so that I could use it directly from the command line. Here is the function:<\/p>\n<p style=\"padding-left: 30px\">Function Get-FolderSize<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;BEGIN{$fso = New-Object -comobject Scripting.FileSystemObject}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;PROCESS{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $path = $input.fullname<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $folder = $fso.GetFolder($path)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; $size = $folder.size<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; [PSCustomObject]@{&#8216;Name&#8217; = $path;&#8217;Size&#8217; = ($size \/ 1gb) } } }<\/p>\n<p>The first thing I did was create an instance of <strong>Scripting.FileSystemObject<\/strong>. I only need to do this one time, and so I place it in the BEGIN block.<\/p>\n<p>In the PROCESS block, I will process the pipelined input. The path comes from the pipeline input from the <strong>Get-ChildItem<\/strong> cmdlet. I select the <strong>FullName<\/strong> property because it provides the complete path to the folder. Now, I use the <strong>GetFolder<\/strong> method to return a folder object. The folder object has a <strong>Size<\/strong> property, and I store that in the <strong>$size<\/strong> variable. Now I create a custom object and return the folder name and size in gigabytes. That is all there is to the script.<\/p>\n<h2>Using the function<\/h2>\n<p>First I run the function in the ISE. This loads the function into memory.<\/p>\n<p>If I do not run the function with Admin rights, I will not have access to all folders, and errors arise. In fact, even if I do run the function with Admin rights, it is likely I will run into errors. So I use the <strong>ErrorAction<\/strong> parameter (<strong>EA<\/strong>) and set it to <strong>SilentlyContinue<\/strong> (<strong>0<\/strong>). I then sort by size. The command is shown here:<\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-size: 12px\">Get-ChildItem -Directory -Recurse -EA 0 | Get-FolderSize | sort size -Descending<\/span><\/p>\n<p>The command and associated output are shown in the following image:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5102.hsg-8-3-13-01.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5102.hsg-8-3-13-01.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>So how long does it take? I use the <strong>Measure-Command<\/strong> to see:<\/p>\n<p style=\"padding-left: 30px\">Measure-command {gci -Directory -Recurse -EA 0 | Get-FolderSize | sort size -Descending }<\/p>\n<p>And following are the results. A little over 30 seconds to process my entire hard drive. Not too bad, really.<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 30<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 24<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 300247135<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.000347508258101852<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.00834019819444444<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.500411891666667<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 30.0247135<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 30024.7135<\/p>\n<p>So where is the time spent? Is it getting the Directory listing? Let&rsquo;s see&hellip;<\/p>\n<p>The Directory listing only takes 5 and a half seconds as shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; Measure-command {gci -Directory -Recurse -EA 0}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 8<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 547<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 85470865<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 9.89246122685185E-05<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.00237419069444444<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.142451441666667<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 8.5470865<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 8547.0865<\/p>\n<p>Well, what about sorting? How long does that take? To figure out how long the sorting takes, I run the command without the <strong>Sort-Object<\/strong> command. I can then see the difference between the first command and the second. Without the sort, it takes a little over 29 seconds:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; Measure-command {gci -Directory -Recurse -EA 0 | Get-FolderSize}<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Days&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Hours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Minutes&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"padding-left: 30px\">Seconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 29<\/p>\n<p style=\"padding-left: 30px\">Milliseconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 154<\/p>\n<p style=\"padding-left: 30px\">Ticks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 291541682<\/p>\n<p style=\"padding-left: 30px\">TotalDays&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.000337432502314815<\/p>\n<p style=\"padding-left: 30px\">TotalHours&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0.00809838005555556<\/p>\n<p style=\"padding-left: 30px\">TotalMinutes &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: 0.485902803333333<\/p>\n<p style=\"padding-left: 30px\">TotalSeconds&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 29.1541682<\/p>\n<p style=\"padding-left: 30px\">TotalMilliseconds : 29154.1682<\/p>\n<p>With the sort, it took a little over 30 seconds. So surprisingly enough, the sort only took about a second. So, most of the time, nearly 21 seconds, was spent in making the calculation to find the folder sizes.<\/p>\n<p>Join me tomorrow for more cool Windows PowerShell stuff. Hope you have a great weekend.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to get folder sizes. Microsoft Scripting Guy, Ed Wilson, is here. I was talking via Lync to my friend Rolf in Munich, Germany the other day. He said the temperatures were approaching 100 degrees Fahrenheit. We have been lucky in Charlotte, North Carolina&mdash;we have [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[447,3,12,61,45],"class_list":["post-3113","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-directory","tag-scripting-guy","tag-storage","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to get folder sizes. Microsoft Scripting Guy, Ed Wilson, is here. I was talking via Lync to my friend Rolf in Munich, Germany the other day. He said the temperatures were approaching 100 degrees Fahrenheit. We have been lucky in Charlotte, North Carolina&mdash;we have [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3113","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=3113"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/3113\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=3113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=3113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=3113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}