Tuesday, September 22, 2009

Windows Defrag From a Script to a Script and Back Again

Sometimes you just have to unscrew your brain, take it out, set it down on the toilet lid and say “what the hell”.  Let’s just say, let’s… that we want to run the DEFRAG command using the /A option to just analyze a volume and somehow we’d like to be able to programmatically (that’s a big word) capture that output and automate something with that mess.  Let’s just say.

The command line might look like defrag c: /a /v >defrag.txt.  But we’d like to be able to schedule this to run at a certain after-hours time and maybe do something like send an email if the results meet some weird crack-infested condition we dreamed up while eating shrimp cocktail and downing four or five cold ones.

The output of this command might look like this…

Microsoft Disk Defragmenter
Copyright (c) 2007 Microsoft Corp.

Invoking analysis on (C:)...

The operation completed successfully.

Post Defragmentation Report:

Volume Information:
Volume size = 74.40 GB
Cluster size = 4 KB
Used space = 24.78 GB
Free space = 49.61 GB

Fragmentation:
Total fragmented space = 2%
Average fragments per file = 1.08

Movable files and folders = 75092
Unmovable files and folders = 45

Files:
Fragmented files = 2197
Total file fragments = 4809

Folders:
Total folders = 15288
Fragmented folders = 14
Total folder fragments = 43

Free space:
Free space count = 1805
Average free space size = 28.14 MB
Largest free space size = 30.62 GB

Master File Table (MFT):
MFT size = 76.50 MB
MFT record count = 78335
MFT usage = 100%
Total MFT fragments = 2

Note: File fragments larger than 64MB are not included in the fragmentation statistics.

You do not need to defragment this volume.


So, how can we do this automation gyration prognostication?  Easy.  Using VBScript, FileSystemObject, the Shell object and some coffee, duct tape and a slice of cold pizza, we might arrive at this…



Const inputFile = "c:\windows\temp\defrag.txt"
Const cmd = "cmd /c defrag c: /a /v"
Const ForReading = 1
Const ForWriting = 2

Dim objFSO, objFile, strLine, objShell, parse
Dim label, data

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("Wscript.Shell")

wscript.echo "info: running defrag analysis on c: drive..."
objShell.Run cmd & " >" & inputFile, 1, True
wscript.echo "info: defrag completed"

wscript.echo "info: checking if input file was created..."

If objFSO.FileExists(inputFile) Then
wscript.echo "info: file was found, opening for input..."
Set objFile = objFSO.OpenTextFile(inputFile, ForReading)
Do Until objFile.AtEndOfStream
strLine = Trim(objFile.Readline)
If InStr(1, strLine, "=") <> 0 Then
strLine = Replace(strLine, vbTab, "")
parse = Split(strLine, "=")
label = Trim(parse(0))
data = Trim(parse(1))
wscript.echo label & vbTab & data
End If
Loop
objFile.Close
Else
wscript.echo "fail: input file not found"
End If

Set objFSO = Nothing
Set objShell = Nothing

wscript.echo "info: processing complete"


The output might look like this…



info: running defrag analysis on c: drive...
info: defrag completed
info: checking if input file was created...
info: file was found, opening for input...
Volume size 74.40 GB
Cluster size 4 KB
Used space 24.78 GB
Free space 49.61 GB
Total fragmented space 2%
Average fragments per file 1.08
Movable files and folders 75096
Unmovable files and folders 43
Fragmented files 2197
Total file fragments 4810
Total folders 15288
Fragmented folders 14
Total folder fragments 43
Free space count 1802
Average free space size 28.19 MB
Largest free space size 30.62 GB
MFT size 76.50 MB
MFT record count 78335
MFT usage 100%
Total MFT fragments 2
info: processing complete


Now you can insert some code to send email using CDOsys (or whatever you prefer) or send some info to a database table.  Then wrap all that up with a tuna sandwich, some fries and a cold drink and you’re off.  Sure, you can do a lot of this with WMI directly and that works too.  But sometimes there are command console utilities that do things WMI doesn’t do as easily (or simply), so you have options like this (capture the output and then parse back into your script to process further).



Options: You can modify this easily to output XML, INI or just about any text format you desire.  You can also pipe it into another script, or pump it into a database.  You can also wrap it into an email and send it.  Or, because you can capture each line and check the “label” string value, you can check for “Total fragmented space” and if it’s greater than some percentage value, fire an email alert.  The take away here is that you can do just about anything you want.

No comments:

Post a Comment