Flylib.com

Books Software

 
 
 

Recipe3.8.Defragmenting a Volume


Recipe 3.8. Defragmenting a Volume

Problem

You want to defragment a volume to improve disk access performance.

Solution

Using a graphical user interface

  1. Open Windows Explorer.

  2. Right-click the drive you want to defragment and select Properties .

  3. Click the Tools tab.

  4. Click the Defragment Now button. This launches the Disk Defragmenter application.

  5. Click the Analyze button to find out how badly the volume is fragmented . After the analysis is complete, Windows will inform you whether it believes you should defragment the volume.

  6. Click the View Report button to view statistics about fragmentation and to see the most fragmented files.

  7. Click the Defragment button to proceed with defragmenting the volume.

Using a command-line interface

The defrag utility is the command-line version of the Disk Defragmenter application (available on Windows XP and Windows Server 2003). Run the following command to perform an analysis of the D: drive:

> defrag d: /a

Add the /v option to see similar information to the View Report button in Disk Defragmenter:

> defrag d: /a /v

Finally, include the drive and /v (for verbose output) to perform a defragmentation of the volume:

> defrag d: /v

You can force a defragmentation even if disk space is low by including the /f option.

Using VBScript
' This code simulates the 'defrag /a /v' command except it analyzes 
' all fixed disks, not just a specific one.  
' The Win32_Volume class is new in Windows Server 2003
' ------ SCRIPT CONFIGURATION ------
strComputer = "."
' ------ END CONFIGURATION ---------
set objWMI = GetObject("winmgmts:\" & strComputer & "\root\cimv2")
set colVols = objWMI.ExecQuery("Select * from Win32_Volume where DriveType = 3")
   
for each objVol in colVols
    WScript.Echo "Analyzing volume " & objVol.DriveLetter
   
    intRC = objVol.DefragAnalysis(boolDefrag, objRpt)
    if intRC = 0 then
   
        WScript.Echo " Volume size: " & objRpt.VolumeSize       
        WScript.Echo " Cluster size: " & objRpt.ClusterSize
        WScript.Echo " Used space: " & objRpt.UsedSpace
        WScript.Echo " Free space: " & objRpt.FreeSpace
        WScript.Echo " Percent free space: " & objRpt.FreeSpacePercent
        WScript.Echo " Total fragmentation: " & _
                     objRpt.TotalPercentFragmentation
        WScript.Echo " File fragmentation: " & _
                     objRpt.FilePercentFragmentation
        WScript.Echo " Free space fragmentation: " & _
                     objRpt.FreeSpacePercentFragmentation
   
        WScript.Echo " Total files: " & objRpt.TotalFiles
        WScript.Echo " Average file size: " & objRpt.AverageFileSize
        WScript.Echo " Total fragmented files: " & objRpt.TotalFragmentedFiles
        WScript.Echo " Total excess fragments: " & objRpt.TotalExcessFragments
        WScript.Echo " Avg fragments per file: " & _
                     objRpt.AverageFragmentsPerFile
   
        WScript.Echo " Page file size: " & objRpt.PageFileSize
        WScript.Echo " Total page file fragments: " & _
                     objRpt.TotalPageFileFragments
   
        WScript.Echo " Total folders: " & objRpt.TotalFolders
        WScript.Echo " Fragmented folders: " & objRpt.FragmentedFolders
        WScript.Echo " Excess folder fragments: " & _
                     objRpt.ExcessFolderFragments
   
        WScript.Echo " Total MFT size: " & objRpt.TotalMFTSize
        WScript.Echo " MFT record count: " & objRpt.MFTRecordCount
        WScript.Echo " MFT percent in use: " & objRpt.MFTPercentInUse
        WScript.Echo " Total MFT fragments: " & objRpt.TotalMFTFragments
   
        if boolDefrag = True Then
           WScript.Echo "You should defragment this volume."
        else
           WScript.Echo "You do not need to defragment this volume."
        end if
        WScript.Echo
    else
        WScript.Echo "Error during defragmentation analysis: " & intRC
    end if
next


' This code simulates the 'defrag c:' command.
' The Win32_Volume class is new in Windows Server 2003
' ------ SCRIPT CONFIGURATION ------
strComputer = "." 
strDrive = "


<Drive>


"  ' e.g. C:
boolForce = False
' ------ END CONFIGURATION ---------
set objWMI = GetObject("winmgmts:\" & strComputer & "\root\cimv2")
set colVol = objWMI.ExecQuery("select * from Win32_Volume Where Name = '" & _
                              strDrive & "\'")
for each objVol in colVol
   intRC = objVol.Defrag(boolForce,objRpt)
   if intRC = 0 then
      WScript.Echo "Defragmentation successful."
   else
      WScript.Echo "Error defragmenting volume: " & intRC
   end if  
next

Discussion

When you save a file on a volume, Windows tries to save the file in one contiguous section on the disk. However, as the disk becomes full over time, the largest available contiguous sections of the disk become smaller and smaller. New files eventually become spread over multiple sections of the disk which is called fragmentation. This leads to decreased disk access performance because Windows has to access multiple sections of the disk to piece together a single file.

The Windows defragmentation feature helps alleviate this problem by scanning a disk and attempting to combine the sections of files in larger contiguous portions. To perform a full defragmentation on a volume, the target volume needs to have at least 15% free space. This is necessary because Windows needs some space to store file fragments it is trying to piece together. If you have less than 15% available, you'll need to free up some space first. See Recipe Recipe 3.7 for more details.

You can determine how badly a volume is fragmented by first analyzing the volume. All three solutions provide options for generating a report that provides details on the fragmentation level of a volume. The report will also recommend whether you should perform a defragmentation or not. This is useful only as a general guide because it may always recommend that you perform a defragmentation even after you've just run one.

You should consider performing periodic defragmentation on heavily used volumes that have become more than 50% utilized. As disk space decreases on a volume, the level of fragmentation generally increases as the number of contiguous sections of disk decrease. If you have really large disks that are rarely more than 25% used, performing a defragmentation will not likely be of much benefit.

Defragmenting a disk can take several minutes and even hours depending on the size of the disk and the level of fragmentation. Also, the disk will be continually busy during the defragmentation period, so do it during off-hours because disk access performance will definitely decrease.


Using VBScript

Both the Defrag and DefragAnalysis methods return a report object (objRpt in the VBScript solutions). This object contains details about the current state of fragmentation on the volume in question. In the second VBScript code sample, I did not enumerate the properties of the objRpt object, but you could use all of the WScript.Echo statements after if intRC = then from the first code sample if you want to display the analysis after defragmentation has been performed.

In the first code sample, I perform a defragmentation analysis on all local disk volumes. With the ExecQuery method, I included DriveType = 3 in the query. The DriveType property is part of the Win32_Volume class and the number 3 represents local disks. Look up Win32_Volume in MSDN for a complete listing of other values for DriveType (although none are important in this scenario).

See Also

Recipe 3.7, MS KB 283080 (Description of the New Command Line Defrag.exe Included with Windows XP), MS KB 305781 (How To Analyze and Defragment a Disk in Windows XP), MS KB 312067 (Shadow copies may be lost when you defragment a volume), and MSDN: Win32_Volume