' DESCRIPTION: This script runs the command-line defragmenter (defrag.exe) found on Windows XP/2003 systems on all fixed drives on a local computer. It will ' analyze each fixed drive and defragment it only if needed, recording each action, results and possible errors in a text file (defrag-result.txt). ' ' NEW: You can now adjust the fragmentation threshold by modifying the FragThreshold constant. A drive will be defragmented only if it's fragmentation percentage ' is determined to be equal to or greater than the FragThreshold value. ' ' ARGUMENTS: The script accepts a single argument: 1 - path on the remote system where the results file will be written. ' ' REQUIREMENTS: The script has to be executed locally on only XP or Server 2003 systems and under account with permissions to defragment local fixed drives. ' ' ' Set this to the fragmentation percentage threshold over which drives will be defragmented Const FragThreshold = 1 Const ForReading = 1 Const FixedDrive = 2 Const Overwrite = TRUE Const GENERAL_FAILURE = 2 Const DEFRAG_EXE = "defrag.exe" Const ResultFile = "defrag-result.txt" Const DumpFile = "defrag-dump.txt" Const WaitOnReturn = TRUE ' Grab the result file path argument Set ArgObj = WScript.Arguments ' Make sure only one argument is given If ArgObj.Count <> 1 Then Wscript.Echo "Incorrect number of arguments provided. I need only one." & VbCrLf Wscript.Echo "Aborting..." Wscript.Quit(GENERAL_FAILURE) End If ' Set up our path strings resultPath = argObj(0) resultFullPath = resultPath & "\" & ResultFile dumpFullPath = resultPath & "\" & DumpFile ' Set up some objects Set objFSO = CreateObject("Scripting.FileSystemObject") Set Command = WScript.CreateObject("WScript.Shell") Set oWshNet = CreateObject("Wscript.Network") localComputer = oWshNet.ComputerName ' Open result output text file, quit on error On Error Resume Next Set objResultFile = objFSO.CreateTextFile(resultFullPath, Overwrite) If Err.Number <> 0 Then Wscript.Echo "Error " & Err.Number & " opening " & Ucase(dumpFullPath) & ": " & Err.Description Wscript.Echo "Aborting..." Wscript.Quit(Err.Number) Else objResultFile.WriteLine "Running defrag on " & localComputer & " on " & Date() & " at " & Time() & VbCrLf & VbCrLf End If On Error Goto 0 ' Get a collection of local drives, determine which drives are fixed Set localDrives = objFSO.Drives For Each localDrive in localDrives If localDrive.DriveType = FixedDrive Then objResultFile.WriteLine "Analyzing drive " & localDrive.DriveLetter & ":..." & VbCrLf ' Build and execute defrag analysis command defragAnalyzeCommand = "%comspec% /c " & DEFRAG_EXE & " " & localDrive.DriveLetter & ":" & " -a -f > " & dumpFullPath ReturnCode = Command.Run(defragAnalyzeCommand,7,WaitOnReturn) ' Catch any errors, record and continue If ReturnCode <> 0 Then objResultFile.WriteLine "Error " & ReturnCode & " returned by " & DEFARG_EXE & " when analyzing drive " & localDrive.DriveLetter & ":" Else ' Append to results file, get fragmentation percentage fragLine = RecordResults(2) ' Check if drive needs to be defragmented If fragLine >= FragThreshold Then objResultFile.WriteLine VbCrLf & "Fragmentation over the threshold (" & FragThreshold & "%), defragmenting drive " & localDrive.DriveLetter & ":..." & VbCrLf ' Build and execute defrag drive command defragDriveCommand = "%comspec% /c " & DEFRAG_EXE & " " & localDrive.DriveLetter & ":" & " -f > " & dumpFullPath ReturnCode = Command.Run(defragDriveCommand,7,WaitOnReturn) ' Catch any errors, record and continue If ReturnCode <> 0 Then objResultFile.WriteLine "Error " & ReturnCode & " returned by " & DEFRAG_EXE & " when defragmenting drive " & localDrive.DriveLetter & ":" Else lastLine = RecordResults(6) End If Else End If End If objResultFile.WriteLine VbCrLf End If Next ' Clean up objResultFile.WriteLine "Defrag finished on " & localComputer & " on " & Date() & " at " & Time() objResultFile.Close Set objDumpFile = objFSO.GetFile(dumpFullPath) objDumpFile.Delete ' Copy recent results to our results file Function RecordResults(skippedLines) frag = FALSE On Error Resume Next Set objDumpFile = objFSO.OpenTextFile(dumpFullPath, ForReading) If Err.Number <> 0 Then objResultFile.WriteLine "Error " & Err.Number & " opening " & Ucase(dumpFullPath) & ": " & Err.Description objResultFile.WriteLine "Aborting..." objResultFile.Close Wscript.Quit(Err.Number) End If On Error Goto 0 For i=1 To skippedLines currentLine = objDumpFile.ReadLine Next wscript.echo statusLine Do Until objDumpFile.AtEndOfStream currentLine = objDumpFile.ReadLine ' Retrieve fragmentation percentage If InStr(currentLine, "Fragmented") Then statusArray = Split(currentLine,",") subStatusArray = Split(statusArray(2)," ") fragNum = CInt(Left(subStatusArray(2),Len(subStatusArray(2))-1)) If fragNum >= FragThreshold Then frag = TRUE End If End If ' Suppress last line if defrag thinks that drive is fine but our threshold says otherwise If (frag = TRUE) AND (StrComp(Left(currentLine,42),"You do not need to defragment this volume.") = 0) Then Else objResultFile.WriteLine currentLine End If Loop objDumpFile.Close RecordResults = fragNum End Function