Scheduled automatic hard drive defragmentation for Windows Server 2003
The problem
Suppose you are the administrator of one or more servers running Windows Server 2003. You probably have a schedule of maintenance tasks you perform on a periodic basis, such as checking system logs, installing software updates, maintaining security policies, cleaning up users’ files and defragmenting the hard drives.
For the last activity, you may have opted for a third party solution such as O&O Software’s Defrag for servers. I love and trust this solution — it’s a powerful and flexible tool specialized on defragmenting drives, making this recurring activity a breeze to manage.
But what if you’re in a corporate environment that, for several reasons, will stick to the Windows built-in defragmenter? Would you spend several hours a week attending to manually defragmenting drives and be happy with it? That’s silly.
Fortunately, unlike the Windows XP counterpart, the defragmenter application in Windows Server 2003 can be started from a batch script, so you can automatize the defragmentation activity. But things get a little more complicated if you have several partitions you want to defragment or if you want to perform more advanced tasks.
The needs
Here’s what I wanted:
- Defragment all drives and partitions in the system sequentially (one after another).
- Prevent multiple instances of the defragmenter from running in parallel.
- Defragment only if there is sufficient free disk space for the defrag to work optimally (minimum 15% of disk space free).
- Defragment only if the defragmenter recommends it, so it doesn’t run on drives with a 2% fragmentation.
- Log the activity somewhere — I chose the system log for it, since I’m already checking it at least once a week, but this can be done easily in a text file.
- Prepare for possible errors and log them.
I studied several scripts for automatic defragmentation on the web and built my own, to match my needs. Credit and thanks goes to everyone else who has attempted this in the past.
The script
' Unattended defragmentation script for Windows Server 2003 ' Checks all hard drives and defragments them as necessary ' Create a BAT file with the following command: ' CSCRIPT AutoDefrag.vbs //B ' Call the BAT file from Scheduled Task, run as Administrator or another user with rights for defragmenting disk Const EVENT_SUCCESS = 0 Const EVENT_ERROR = 1 Const EVENT_WARNING = 2 Const EVENT_INFORMATION = 4 strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") Set objShell = CreateObject("Wscript.Shell") ' Check if another instance of Windows Defrag is already running Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = ' Dfrgntfs.exe'") If colProcesses.Count = 0 Then ' No other instance found ' Write information message in the system log objShell.LogEvent EVENT_INFORMATION, "Starting unattended disk defragmentation." ' Find all hard drives Set colVolumes = objWMIService.ExecQuery("Select * from Win32_Volume where DriveType = 3") For Each objVolume in colVolumes ' Analyze drive, check if it is recommended to defragment it errResult = objVolume.DefragAnalysis(blnRecommended, objReport) ' Check if the operation completed without errors If errResult = 0 Then ' Fragmentation check completed without errors ' Check if there is sufficient free space on disk for defragmentation (minimum 15%) If (objReport.FreeSpacePercent < 15 ) Then ' Drive doesn't have enough free space for an efficient defragmentation ' Write error message in the system log objShell.LogEvent EVENT_WARNING, "Drive " & objVolume.Name & " is almost full and cannot be defragmented! Drive is " & objReport.FreeSpacePercent & "% free." Else ' There is enough free space ' Is it is recommended to defragment current drive? If (blnRecommended) Then ' Yes, current drive should be defragmented ' Write information message in the system log objShell.LogEvent EVENT_INFORMATION, "Drive " & objVolume.Name & " should be defragmented: " & objReport.TotalPercentFragmentation & "% total fragmentation, " & objReport.FilePercentFragmentation & "% file fragmentation. Drive is " & objReport.FreeSpacePercent & "% free." ' Begin defragmentation errResult = objVolume.Defrag() ' Check if defragmentation completed without errors If errResult = 0 Then ' No errors, defragmentation is complete ' Write information message in the system log objShell.LogEvent EVENT_SUCCESS, "Drive " & objVolume.Name & " successfully defragmented." Else ' Error encountered ' Write error message in the system log objShell.LogEvent EVENT_SUCCESS, "Drive " & objVolume.Name & " could not be defragmented. Error code: " & errResult & "." Err.Clear End If Else ' No, current drive doesn't need to be defragmented ' Write information message in the system log objShell.LogEvent EVENT_SUCCESS, "Drive " & objVolume.Name & " does not need to be defragmented: " & objReport.TotalPercentFragmentation & "% total fragmentation, " & objReport.FilePercentFragmentation & "% file fragmentation. Drive is " & objReport.FreeSpacePercent & "% free." End If End If Else ' Fragmentation check generated an error ' Write error message in the system log objShell.LogEvent EVENT_WARNING, "Drive " & objVolume.Name & " could not be analyzed. Error code: " & errResult & "." End If Next ' Finished checking and defragmenting all hard drives in the system ' Write information message in the system log objShell.LogEvent EVENT_INFORMATION, "Unattended disk defragmentation is complete." Else ' Another instance of Windows Defrag already running ' Write error message in the system log objShell.LogEvent EVENT_ERROR, "Unattended disk defragmentation is unable to start: another instance of NTFS Defrag is already running." End If
How to use this?
- Copy and paste this text in Notepad, save the text file as autodefrag.vbs in a folder on your Windows Server 2003 machine.
- In another Notepad window, enter the command: cscript autodefrag.vbs //B and save it as autodefrag.bat in the same folder with autodefrag.vbs .
- Create a new scheduled task that runs autodefrag.bat whenever you want. Make sure you run this under an account with administrative priviledges.
Tips
- Schedule automatic defragmentation at a time when it doesn't conflict with other disk-intensive activities, such as file transfers, database backups, file archival, tape backups, other maintenance.
- Check logs to make sure the defragmentation ended without errors.
- If a partition is almost full, free up some space and defragment it manually.
- Check if partitions that were skipped by the automatic defragmenter really do not need to be defragmented.
- For optimum performance, prepare your drives before automatic defragmentation commences -- delete temporary files, archive logs and other files.
- Augment this script to write details of its actions in a separate log file you can back up or send by e-mail, as needed. On request, I could prepare a version which also uses text files for logs.
If you find this script useful, I'd really like to hear your experiences with it.



