Here's the situation:
I have a win server that runs a video streaming server. It has multiple volumes ranging in size from 850 GB to 1.7 TB. The content is stored in a sing directory on the volumes. As content is ingested into the server, the files become very fragmented. So the problem I was facing was "How can I defrag and sort the files by size on a full volume." So i wrote a little vbscript to take care of that. The procedure does require a temp storage area to move files to that has enough free space to hold 55% of the total space on the volume to be defraged. Here is the script:
' Defrag full volume, order files from smallest to largest
' Single content folder
' Set user defined variables
strSourceDrive = "Q:"
strSourcePath = "\Content\"
strTempPath = "I:\"
strJkDefrag = "C:\JKDefrag\JkDefrag.exe"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set DataList = CreateObject("ADODB.Recordset")
DataList.Fields.Append "strFileName", 200, 255
DataList.Fields.Append "strFileSize", 20
DataList.Open
' Move files to temp location until 55 percent free space on source starting with the smallest files
Set objSourceLocation = objFSO.GetFolder(strSourceDrive & strSourcePath)
For Each objFile In objSourceLocation.Files
DataList.AddNew
DataList("strFileName") = objFile.Name
DataList("strFileSize") = int(objFile.Size)
DataList.Update
Next
Set objSourceLocation = Nothing
DataList.Sort = "strFileSize ASC,strFileName"
DataList.MoveFirst
Set objSourceDrive = objFSO.GetDrive(objFSO.GetDriveName(strSourceDrive))
Do Until int((objSourceDrive.FreeSpace/objSourceDrive.TotalSize)*100) > 54
strFileName = DataList.Fields.Item("strFileName")
objFSO.MoveFile strSourceDrive & strSourcePath & strFileName, strTempPath
DataList.MoveNext
Loop
Set objSourceDrive = Nothing
DataList.Close
Set DataList = Nothing
' Force all remaining files to front of drive
Set WshShell = WScript.CreateObject("WScript.Shell")
Return = WshShell.Run(strJkDefrag & " -u DisableDefaults -f 0 -a 5 -q " & strSourceDrive, 1, true)
' Defrag and send remaining files to end of drive starting with the largest file
Set objSourceLocation = objFSO.GetFolder(strSourceDrive & strSourcePath)
Set DataList = CreateObject("ADODB.Recordset")
DataList.Fields.Append "strFileName", 200, 255
DataList.Fields.Append "strFileSize", 20
DataList.Open
For Each objFile In objSourceLocation.Files
DataList.AddNew
DataList("strFileName") = objFile.Name
DataList("strFileSize") = int(objFile.Size)
DataList.Update
Next
Set objSourceLocation = Nothing
DataList.Sort = "strFileSize DESC,strFileName"
DataList.MoveFirst
Do Until DataList.EOF
strFileName = DataList.Fields.Item("strFileName")
Return = WshShell.Run(strJkDefrag & " -u DisableDefaults -f 0 -a 6 -q " & strSourceDrive & strSourcePath & strFileName, 1, true)
DataList.MoveNext
Loop
DataList.Close
Set DataList = Nothing
' Retrieve files from temp area, one at a time, largest first, defrag and send to end of drive
Set objTempLocation = objFSO.GetFolder(strTempPath)
Set DataList = CreateObject("ADODB.Recordset")
DataList.Fields.Append "strFileName", 200, 255
DataList.Fields.Append "strFileSize", 20
DataList.Open
For Each objFile In objTempLocation.Files
DataList.AddNew
DataList("strFileName") = objFile.Name
DataList("strFileSize") = int(objFile.Size)
DataList.Update
Next
Set objTempLocation = Nothing
DataList.Sort = "strFileSize DESC,strFileName"
DataList.MoveFirst
Do Until DataList.EOF
strFileName = DataList.Fields.Item("strFileName")
objFSO.MoveFile strTempPath & strFileName, strSourceDrive & strSourcePath
Return = WshShell.Run(strJkDefrag & " -u DisableDefaults -f 0 -a 5 -q " & strSourceDrive & strSourcePath & strFileName, 1, true)
Return = WshShell.Run(strJkDefrag & " -u DisableDefaults -f 0 -a 6 -q " & strSourceDrive & strSourcePath & strFileName, 1, true)
DataList.MoveNext
Loop
DataList.Close
Set DataList = Nothing
Set WshShell = Nothing
Set objFSO = Nothing
I welcome any and all comments. I hope this examble would be useful to others out there.