{"id":68773,"date":"2005-10-11T09:42:00","date_gmt":"2005-10-11T09:42:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2005\/10\/11\/how-can-i-determine-which-users-are-using-the-most-disk-space-on-a-drive\/"},"modified":"2005-10-11T09:42:00","modified_gmt":"2005-10-11T09:42:00","slug":"how-can-i-determine-which-users-are-using-the-most-disk-space-on-a-drive","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/how-can-i-determine-which-users-are-using-the-most-disk-space-on-a-drive\/","title":{"rendered":"How Can I Determine Which Users are Using the Most Disk Space on a Drive?"},"content":{"rendered":"<p><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"> \n<P>Hey, Scripting Guy! How can I determine which users are using the most disk space on a drive?<BR><BR>&#8212; PW<\/P><IMG border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\"><IMG class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\"><A href=\"http:\/\/go.microsoft.com\/fwlink\/?linkid=68779&amp;clcid=0x409\"><IMG class=\"farGraphic\" title=\"Script Center\" border=\"0\" alt=\"Script Center\" align=\"right\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/ad.jpg\" width=\"120\" height=\"288\"><\/A> \n<P>Hey, PW. Interesting question. In <I>theory<\/I>, you could probably do this by retrieving a collection of all the files on a drive, checking the owner, determining the file size, and then keeping a running tally of the amount of disk space charged to each user. Like we said, in theory that would work, but it would be a complicated little script, and, depending on the number of files on the drive, you might bring your computer to its knees while the script performs all its machinations.<\/P>\n<P>Therefore, we decided to go with an approach that is much easier, much faster, and much less resource-intensive. The catch? (Oh, come on: you knew there <I>had<\/I> to be a catch here.) You\u2019ll have to enable disk quotas on the drive in question in order for this to work.<\/P>\n<P>We won\u2019t spend much time talking about enabling and disabling disk quotas in today\u2019s column. If you\u2019re running Windows XP or Windows Server 2003, you can find a fairly extensive article on disk quotas in our <A href=\"http:\/\/null\/technet\/scriptcenter\/topics\/win2003\/quotas.mspx\"><B>Scripting for Windows Server 2003<\/B><\/A> center. If you\u2019re running Windows 2000, the <A href=\"http:\/\/null\/technet\/scriptcenter\/guide\/sas_fsd_jmqe.mspx\" target=\"_blank\"><B>Microsoft Windows 2000 Scripting Guide<\/B><\/A> includes information on using scripts to enable and disable disk quotas. Keep in mind that when we say you have to enable disk quotas on the drive, that doesn\u2019t mean you have to <I>enforce<\/I> those quotas: you can enable disk quotas and allow the operating system to tally up the amount of disk space charged to each user without restricting access to the drive in any way. And, of course, you can always enable disk quotas, run your script, and then disable disk quotas again.<\/P>\n<TABLE id=\"ESD\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<THEAD><\/THEAD>\n<TBODY>\n<TR class=\"record\" vAlign=\"top\">\n<TD>\n<P class=\"lastInCell\"><B>Note<\/B>. If you decide to do the old enable\/disable trick, keep in mind that it will likely take several minutes &#8211; at least &#8211; for the operating system to tally up disk space use after quotas have been enabled. In other words, don\u2019t enable disk quotas and then immediately run the script to determine disk space usage; that\u2019s probably not going to work.<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<DIV class=\"dataTableBottomMargin\"><\/DIV>\n<P>Assuming you have enabled disk quotas on drive C of a computer, and assuming you\u2019re running Windows XP or Windows Server 2003, here\u2019s a script that will return the amount of disk space currently charged to each user:<\/P><PRE class=\"codeSample\">strComputer = &#8220;.&#8221;<\/p>\n<p>Set objWMIService = GetObject(&#8220;winmgmts:\\\\&#8221; &amp; strComputer &amp; &#8220;\\root\\cimv2&#8221;)<\/p>\n<p>strDrive = &#8220;Win32_LogicalDisk.DeviceID=&#8221; &amp; chr(34) &amp; &#8220;C:&#8221; &amp; chr(34)<\/p>\n<p>Set colQuotas = objWMIService.ExecQuery _\n    (&#8220;Select * from Win32_DiskQuota Where QuotaVolume = &#8216;&#8221; &amp; strDrive &amp; &#8220;&#8216;&#8221;)<\/p>\n<p>For Each objQuota in colQuotas\n    Wscript.Echo &#8220;User: &#8220;&amp; objQuota.User      \n    Wscript.Echo &#8220;Disk Space Used: &#8220;&amp; objQuota.DiskSpaceUsed\nNext\n<\/PRE>\n<P>As you can see, the script begins simply enough, setting a variable named strComputer to a dot (WMI notation for the local computer) and then connecting to the WMI service. (Although this example connects to the WMI service on the local computer, you can retrieve disk quota information for a remote computer simply by assigning the name of that computer to the variable strComputer.) We then have this interesting line of code:<\/P><PRE class=\"codeSample\">strDrive = &#8220;Win32_LogicalDisk.DeviceID=&#8221; &amp; chr(34) &amp; &#8220;C:&#8221; &amp; chr(34)\n<\/PRE>\n<P>As it turns out, the <B>Win32_DiskQuota<\/B> class &#8211; the class we\u2019ll be working with to retrieve information about disk space usage &#8211; is a bit different than most WMI classes. For one thing, the <B>QuotaVolume<\/B> property &#8211; which indicates the drive we\u2019re working with &#8211; isn\u2019t a typical WMI property; instead, it\u2019s actually an embedded instance of the <B>Win32_LogicalDisk<\/B> class. That\u2019s fine, but it does make it a bit awkward to include QuotaVolume in a Where clause; that\u2019s because the value of QuotaVolume will look something like this:<\/P><PRE class=\"codeSample\">Win32_LogicalDisk.DeviceID=&#8221;C:&#8221;\n<\/PRE>\n<P>Inside a Where clause, it\u2019s tricky to deal with the double quote marks around the drive letter. Because of that, we use the preceding line of code to create a string value equivalent to <B>Win32_LogicalDisk.DeviceID=&#8221;C:&#8221;<\/B>, using Chr(34) as a way to add in the double quotes. It\u2019s an extra line of code, but it\u2019s much easier to put the variable strDrive into the Where clause than it is to put <B>Win32_LogicalDisk.DeviceID=&#8221;C:&#8221;<\/B>.<\/P>\n<P>Trust us; it is.<\/P>\n<P>Speaking of which, the next thing we do is call the <B>ExecQuery<\/B> method to return a collection of all the disk quota entries for drive C:<\/P><PRE class=\"codeSample\">Set colQuotas = objWMIService.ExecQuery _\n    (&#8220;Select * from Win32_DiskQuota Where QuotaVolume = &#8216;&#8221; &amp; strDrive &amp; &#8220;&#8216;&#8221;)\n<\/PRE>\n<P>From there we set up a For Each loop to walk through the collection, echoing back the user name and the amount of disk space (for drive C) currently charged to the user.<\/P>\n<P>Now, that works great on Windows XP or Windows Server 2003, but it won\u2019t do you much good on Windows 2000; that\u2019s because Windows 2000 doesn\u2019t support the Win32_DiskQuota class. So are you out of luck if you\u2019re running Windows 2000? Of course not; you can just use the <B>DiskQuota<\/B> object instead:<\/P><PRE class=\"codeSample\">Set colDiskQuotas = CreateObject(&#8220;Microsoft.DiskQuota.1&#8221;)\ncolDiskQuotas.Initialize &#8220;C:\\&#8221;, True<\/p>\n<p>For Each objUser in colDiskQuotas\n    Wscript.Echo &#8220;Logon name: &#8221; &amp; objUser.LogonName\n    Wscript.Echo &#8220;Quota used: &#8221; &amp; objUser.QuotaUsed\nNext\n<\/PRE>\n<P>As you can see, here we create an instance of the <B>Microsoft.DiskQuota.1<\/B> object, then use the <B>Initialize<\/B> method to return the collection of disk quota entries for <B>C:\\<\/B>. (Don\u2019t leave off the <B>\\<\/B>; it\u2019s required.) We then set up a For Each loop and, for each quota entry, echo the values of the <B>LogonName<\/B> and the <B>QuotaUsed<\/B> properties.<\/P>\n<P>And you\u2019re right: this script <I>is<\/I> a lot easier than the one we showed you for Windows XP and Windows Server 2003. So why didn\u2019t we just show you this script and call it good? Well, the catch here &#8211; oh, come on: you knew there had to be a catch here, too &#8211; is that the DiskQuota object can\u2019t be created remotely; that means the latter script can run only on the local computer. The WMI script might be a tad bit more complicated, but it has the advantage of working against remote computers as well.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! How can I determine which users are using the most disk space on a drive?&#8212; PW Hey, PW. Interesting question. In theory, you could probably do this by retrieving a collection of all the files on a drive, checking the owner, determining the file size, and then keeping a running tally of [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[216,3,12,5],"class_list":["post-68773","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-disk-drives-and-volumes","tag-scripting-guy","tag-storage","tag-vbscript"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! How can I determine which users are using the most disk space on a drive?&#8212; PW Hey, PW. Interesting question. In theory, you could probably do this by retrieving a collection of all the files on a drive, checking the owner, determining the file size, and then keeping a running tally of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68773","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=68773"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/68773\/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=68773"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=68773"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=68773"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}