Smart Disk Defragmentation with Powershell

Published 2.23.2007 by ~mattg

As I mentioned before, I wrote a powershell script that defragments you hard drives based on a percentage. The nice thing about this is you can schedule this to run at a given interval (daily, weekly, whatever) and it will on defragment your drives as necessary. I gave a short synopsis of the process in the previous post, so I’ll just post the code here.

The main script is as such:

$dLimit = [double]$args[0]
foreach ($drive in Get-WMIObject Win32_LogicalDisk -filter “DriveType = 3″)
{
    $strDriveLetter = $drive.DeviceID
    $strReport = defrag $strDriveLetter -a
    $dFragPercent = [double] (Get-FragmentationPercent $strReport)

    if ($dFragPercent -gt $dLimit)
    {
        echo “Drive $strDriveLetter defragmenting:”
        echo “    Before:  $dFragPercent% fragmented.”
        $strDefragReport = defrag $strDriveLetter
        $dNewFrag = Get-FragmentationPercent $strDefragReport $false
        echo “    After:  $dNewFrag% fragmented.”                   
    }
    else
    {   
        echo “Drive $strDriveLetter does not need defragmented ($dFragPercent% fragmented)”
    } 
}

You may notice the Get-FragmentationPercent function. You can either put it in the same script file (before the main script), or in it’s own file with the Get-FragmentatinoPercent.ps1 filename.

function Get-FragmentationPercent
{
    param ($strReport, [bool] $bGetAnalysis=$true)
    begin
    {
        $bInAnalysis = $false
        $bInDefrag = $false
        foreach ($line in $strReport)
        {
            if ($line -match “Analysis Report”)
            {
                $bInDefrag = $false;
                $bInAnalysis = $true;
            }
            if ($line -match “Defragmentation Report”)
            {
                $bInAnalysis = $false;
                $bInDefrag = $true;
            }

            if ($line -match “(?<percentfragmented>\d+)%\sFragmented\s”)
            {
                if (($bInAnalysis -and $bGetAnalysis) -or ($bInDefrag -and !$bGetAnalysis))
                {
                    return $matches[“percentFragmented”]
                }
            }
        }
        return 0
    }
}

I’ve been using this for a couple weeks with no problems. Just throw it in a script file and run. It looks at the first argument you pass it (parsing it as a double) and compares the defragmentation percentage to that limit. If the defrag percent is greater than your defined limit, it defrags the drive.

Filed under Windows

Comments (0)

Comments RSS - Trackback - Write Comment

No comments yet

Write Comment