Recipe 3.8. Defragmenting a Volume
Problem
You want to defragment a volume to improve disk access performance.
Solution
Using a graphical
user
interface
-
Open Windows Explorer.
-
Right-click the drive you want to defragment and select
Properties
.
-
Click the
Tools
tab.
-
Click the
Defragment Now
button. This launches the Disk Defragmenter application.
-
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.
-
Click the
View Report
button to view statistics about fragmentation and to see the most fragmented files.
-
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
|