I'm sure you've run into situations where a user's hard drive is quickly running out of free drive space. This is especially true on older computers where perhaps you've done an in-place operating system upgrade. Eventually, free disk space starts running low which can lead to a number of problems. The challenge is to buy yourself a little wiggle room until a more permanent solution can be implemented. I want to demonstrate a variety of tools and techniques to put a hard drive on a crash diet. I'm going to focus on Windows 7, but many of these suggestions will work for older operating systems and servers. We'll look at a combination of graphical and command line solutions.

WARNING: A number of suggestions involve deleting files so I can't stress enough that you test these steps in a non-production environment so that you completely understand the implications. While I've personally used these techniques, this is definitely use at your own risk.

I've created a number of scripts which are mentioned throughout the article. You can download them from here.

1. Disk Clean Up Wizard

Without a doubt the first step in putting your disk on a diet is to run the Disk Clean Up Wizard. Right-Click the hard disk in Windows Explorer and select Properties. Then click on the Disk Cleanup button. You can also run Cleanmgr from a command prompt. Either way should get you to the screen in Figure 1.

Figure 1 The Disk Cleanup Wizard

Depending on your flavor of Windows 7 you might have a button labeled System Files which will bring up the More Options tab. Hopefully, this will free up enough drive space and provide a little breathing room. But if not, there are additional steps you can take.

2. Turn Off Shadow Copies

It is possible the computer is configured to maintain previous versions, also known as shadow copies. Windows maintains a copy of previously edited files in a special cache so that you can recover previous versions. Assuming space is more critical than a backup copy, you can clear this cache.

While still on the Disk Clean Up screen, click on the More Options tab which should give you something like Figure 2.

Figure 2 More Clean Up Option

Here you can click the Cleanup button to free up probably a gig or more of space.

3. Clear System Restore Points

System Restore points are another recovery feature that you may have to live without when space is at a premium. You can delete them at the same time you delete the previous versions. While there are no command line tools for deleting restore points, you can disable them using Windows PowerShell in an elevated session.

PS C:\> Disable-ComputerRestore "C:\"

When you need to re-enable it run:

PS C:\> Enable-ComputerRestore "C:\"

4. Clear Software Downloads

Windows Update downloads a lot of files, much of which can be deleted with minimal consequence. To safely delete these files, I recommend stopping the Windows Update Service either from the Services management console, or the command line.

PS C:\> Stop-Service wuauserv

Once stopped, delete the contents C:\Windows\SoftwareDistribution\Download either through Windows Explorer or the command line.

PS C:\> dir $env:windir\SoftwareDistribution\Download -Recurse | Remove-Item 'Recurse

If you are really crunched you can delete the entire SoftwareDistribution folder. When you restart the Windows Update service it will be recreated and necessary files will be re-downloaded. But don't forget to restart the service.

PS C:\> Start-Service wuauserv

5. Delete Unused Profiles

Old local user profiles can easily eat up space. Under Control Panel\System and Security\System click on the Advanced System Settings, On the Advanced tab you'll see a section for User Profiles. Click the Settings button. Now you can select any non-system profile that isn't in use and delete it.

Before Windows 7 IT Pros could use the handy DELPROF.EXE command line tool to delete user profiles from the command line. But this tool does not run under Windows 7. Instead we have to rely on Windows Management Instrumentation (WMI). Fortunately, this is very easy to use in Windows PowerShell.

I wrote a few functions you can use to identify profiles and then delete them.

PS C:\> Get-UserProfile | where {$_.LastUse -lt (Get-Date).AddDays(-90)} | remove-userprofile

This will use my functions to find all profiles that haven't' been used in the last 90 days and remove them.

6. Move the Swap File

A frequent step I take to alleviate disk bloating is to move the swap file to another drive. Sometimes you can move it to another partition. I usually plug in an external drive and move the swap file.

Under Control Panel\System and Security\System click on the Advanced System Settings, On the Advanced tab click on Settings in the Performance section. Select the Advanced tab and click on Change under Virtual Memory. You should see something like Figure 3.

Figure 3 Change Swap Filehicks_2011_07_figure_3.png

Select a new drive and configure the swap file. I typically use the System Managed size. Then on the old drive, I'm assuming C:\ set it to No Paging File. You might get a warning message but as long as you've set a new swap file it should be ok. You'll need to reboot for this change to take effect.

7. Delete the MSO Cache

If you have Microsoft Office installed, you most likely have a hidden folder on your C: drive called MSOCache. This is used to facilitate repairs and reinstallations of Microsoft Office features but it can eat up a lot of disk space. When you are on a crash diet you might have to live without it. Deleting the files requires elevated privileges. It won't affect running any Office applications, but attempts to install new features will fail.

To restore the cache later, you'll need to do a repair installation of Microsoft Office from the installation CD or DVD. I can't guarantee this tip will work for all versions of Microsoft Office but I was able to remove the cache for Microsoft Office 2010.

8. Turn off Hibernation

This tip should primarily affect laptops, but desktop computers might also have hibernation enabled. When the computer hibernates, memory contents are written to disk. Depending on the amount of RAM this could be a hefty file.

PS C:\> dir hiberfil.sys -force
Directory: C:Mode''''''''''''''' LastWriteTime'''' Length Name
----''''''''''''''' -------------'''' ------ ----
-a-hs'''''''' 7/18/2011' 10:33 PM 6433390592 hiberfil.sys

The easiest way to trim this file away is from the command prompt using the Powercfg.exe utility.

C:\>powercfg -h off

When you want to re-enable it, run the command specifying 'On'.

9. Compress Selected Files

During the Disk Clean Up Wizard you are offered an option to compress old files. I never use this because I'll end up compressing old files that are already compressed. Instead I'd rather be a bit more selective and only compress files that are compressible and worth my time. Using WMI it is possible to compress files so I wrote a PowerShell script to do just that. This script, Compress-FileExtension.ps1 is a Windows Form script as shown in Figure 4.

Figure 4 Compress-FileExtension.ps1

When you launch the script, enter a path and a list of file extensions (no periods or wildcards). You can also add criteria such as minimal file size and a last modified date. Use the List only option to see what files would be compressed. You'll still get a warning, but no files will be modified. Then when you are ready, uncheck List only and let it rip. Expect this to take some time to complete and you will most likely see errors in the PowerShell console for system folders you can't access. This is normal. The form may also appear to stop responding but be patient. Kick this off before lunch. Compressed files still occupy space, but it might be enough to make the operating system or an application think it has a bit more disk space to work with.

10. Backup and Clear Event Logs

The last diet supplement that might eke out a bit more space is to backup and clear event logs. Windows 7 not only has the classic event logs like System and Application, but many new ones that are part of Windows Eventing as shown in Figure 5.

Figure 5 Event Logs

Now, you can select each event log in the GUI, back it up (if you want or need to) and then clear it. If you are cherry picking, fine; but otherwise, PowerShell is our friend.

I find it just as easy to use the Get-WinEvent cmdlet to report on all event logs.

PS C:\> get-winevent -listlog * | where {$_.FileSize -ge 1MB} | Sort Filesize -descending | Select LogName,FileSize,LogFilePath | format-list
LogName'''' : Security
FileSize''' : 100732928
LogFilePath : %SystemRoot%\System32\Winevt\Logs\Security.evtx
LogName'''' : System
FileSize''' : 6361088
LogFilePath : %SystemRoot%\System32\Winevt\Logs\System.evtx
LogName'''' : Microsoft-Windows-TaskScheduler/Operational
FileSize''' : 6361088
LogFilePath : %SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-TaskScheduler%4Operational.evtx
LogName'''' : Application
FileSize''' : 5312512
LogFilePath : %SystemRoot%\System32\Winevt\Logs\Application.evtx

This expression gets all event logs with a file size greater than 1MB and writes some information to the pipeline. The important information here is the log name which we'll use next.

The event log cmdlets are limited so I prefer to handle everything on my own using the System.Diagnostics.Eventing.Reader.EventLogSession class. Don't worry. I'll demonstrate the basic steps. First I'll create a session object.

$es=new-object System.Diagnostics.Eventing.Reader.EventlogSession

We can use this object to gather event log information from both classic and new logs.

PS C:\> $es.GetLogInformation("Application","Logname")
CreationTime'''''' : 4/19/2010 11:00:22 PM
LastAccessTime'''' : 4/19/2010 11:00:22 PM
LastWriteTime''''' : 7/19/2011 3:05:58 PM
FileSize'''''''''' : 5312512
Attributes'''''''' : 32
RecordCount''''''' : 6715
OldestRecordNumber : 1
IsLogFull''''''''' : False
PS C:\> $es.GetLogInformation("Microsoft-Windows-GroupPolicy/Operational","Logname")
CreationTime'''''' : 4/19/2010 11:00:23 PM
LastAccessTime'''' : 4/19/2010 11:00:23 PM
LastWriteTime''''' : 7/19/2011 12:33:54 PM
FileSize'''''''''' : 4198400
Attributes'''''''' : 32
RecordCount''''''' : 3821
OldestRecordNumber : 23654
IsLogFull''''''''' : False

Specify the log name for the first parameter value. Use 'Logname' for the second. Assuming you want to back up the event log before clearing it, here's how:

PS C:\> $es.ClearLog("Microsoft-Windows-GroupPolicy/Operational","e:\gpoops.evtx")

If you don't want to back it up first simply omit the second parameter. All you need to do is go through the list of event logs and clear them. Again, you might not regain a lot of disk space, but when you are on a diet every little bit helps.

Collectively, these steps will hopefully buy you enough time to properly address the situation with a more permanent solution. I know there are third party tools available for managing disk space and cleaning up hard drives, and they can be quite helpful. But sometimes you need to start the diet immediately and I hope this menu of tips and techniques satisfies your cravings.