Assigning size quotas to folders on Windows

May 16th, 2011

I was recently given a task where I needed to assign quotas to folders on a Windows system. Preferably without creating multiple users. This could be a very useful feature in budgeting disk space to various users or applications. Now if you do some quick searches on Google you will quickly realise that this specific feature is not supported by any version of Windows. Well that’s a shame! But that does not mean that there is no work around. The solution in one line is to create a virtual disk (vdisk) and mount this vdisk onto a path on the system. All applications will see this path as an ordinary folder but will be restricted by the virtual drive’s size.

On Windows 7 and Windows Server 2008

For those who are not sure how this can be done, the answer is a less well known command line utility called diskpart.exe. Diskpart is able to run scripts using the /s switch. Scripts are nothing but text files with a series of diskpart commands. So the script we need to create will need to do the following…

  1. Create a virtual disk
  2. Create a partition on this virtual disk
  3. Format the virtual disk
  4. Map the virtual disk on to a path

The script to do this is as follows. If you prefer, you can start diskpart and type these command in line by line.

create vdisk file=c:\myDisk.vhd maximum=2048  type=expandable
select vdisk file=c:\myDisk.vhd
attach vdisk
create partition primary
format fs=ntfs quick
assign mount="c:\my folder"

A line by line explanation of the script is doing is this

Line 1: Creates a vdisk which will be saved as a file at c:\myDisk.vhd with a size of 2048Mb. The type=expandable part makes sure the size of file depends on the amount of data saved in your vdisk. If you skip this parameter the file will take up the entire 2048Mb of space, even if you have not saved a single byte.
Line 2: makes the vdisk current. This way all future operations will target this vdisk.
Line 3: So far we have only created a vdisk. Think of this command as  connecting the vdisk to your computer (virtually) just as you would connect a USB storage device to a USB port.
Line 4: Creates a partition on the vdisk
Line 5: Format the new partition using NTFS
Line 6: Map the vdisk on to a folder. In this case it is c:\my folder, but you can change this to whatever you like.

So that’s it. I have made a small batch to automate the process for Windows 7. Get it from the link below.

[compress Download quota.bat]

On older versions of Windows

If you are using something older than XP, then I’m afraid you need to WAKE UP and realise we are in 2011. The stuff mentioned in this section will work only on Windows XP and newer versions.

The problem on older versions of Windows is that diskpart does not support virtual disks. We just need to use different tools to do the same thing, so if you skipped the previous section I suggest you go back and read it again. The bad news is that you will need to download some additional software. The good news is that all these tools are free. These are the tools you will need…

  1. vhdtool.exe (From here)
  2. vhdmount by installing Microsoft Virtual Server 2005. Note: When installing use the custom install option and only select vhdmount from the list. The other components are not needed unless you want to play with them.

As mentioned previously, the process is the same one as we did for Windows 7. The step by step process is as follows.

Step 1: Create a vdisk using vhdtool.exe using the following command line.
VhdTool.exe /create c:\myDisk.vhd 2147483648
There are two differences here. 1 – The size we enetered here is in bytes, so we need to multiply the number of bytes we want with 1048576 and 2- We don’t have the option of creating an expandable drive. So the vdisk file will take up all the space requested regardless of how much is actually stored in it.

Step 2: Connect the vdisk (only virtually of course) using vhdmount.exe
vhdmount.exe /p /f c:\myDisk.vhd

Step 3: Create a partition on the drive using diskpart. But before we do this, we must first start diskpart
1. Identify the disk number using the diskpart LIST command
LIST DISK
Make a note of the disk number. In my case it is 1.
2. Select the disk using the command
SELECT DISK 1
3. Create the partition like we did before using the CREATE command
CREATE PARTITION PRIMARY

Step 4: Unfortunately old versions of diskpart don’t have a format command, so we must do this using the good old format.com. But format.exe only works on drive letters, so that is what we need to do using the ASSIGN command
ASSIGN letter=x
Now, you will need to exit diskpart temporarily using the EXIT command and format the drive using good old format.com. If you have never done this or have gotn’ used to the GUI, this is how it is done from the command line…
format.com x: /Q /FS:NTFS

Step 5: Now if you don’t mind using the drive, you can stop here. Otherwise head back into diskpart to un-mount the volume. Unfortunately since we exited diskpart, we need to reselect the right volume. Get a list of volume using the LIST command as follows
LIST volume
Make a note of the volume number.  It will have the drive letter mentioned under the Ltr column. In this case it is x. Then select it using…
SELECT volume 2
Then remove the drive letter mapping using the REMOVE command as follows
REMOVE letter=x
And finally map it on to your folder using…
ASSIGN mount=”c:\my folder”

And so that is it. Although you may be able to automate the process using a combination of batch files and grep, I successfully implemented a command line PHP script to automate the process on Windows XP as well. You can also probably use a VB script, but that is not something I am very familiar with. The problem is identifying the disk number in step 3 and volume number in step 5. I used the following process to determine the disk number automatically.

  1. Make a list of disks before plugging in the vdisk in step 2.
  2. Use a regex pattern match and extract a list of disk numbers.
  3. Mount the vdisk.
  4. Make another list of disks. This time, the list will have the vdisk that you just mounted.
  5. Identify the disk that is in the second list but not in the first one.

Identifying the volume number in step 5 if much simpler. Just use a regex pattern to identify the line which has the drive letter x. The number to the left of it will be the volume number.

There are a lot of other cool things you can do using diskpart that is not available via a GUI. If you don’t mind getting your hands dirty using the command line, then this is a good place to get started.

Leave a Reply

You must be logged in to post a comment.