Automate Drive Defragment Jobs With SCCM CI & CB

Many of you would argue that in some circumstances the entire process of defragmenting a hard disk is no longer required, I have had this argument thrown up at me when it comes to virtual servers in particular.

The one thing to remember though is that fragmentation of files does occur whether your disk is virtual or not, SSD or not, and although performance degradation might not be severe, it only serves as good house keeping to keep your disks running optimally.

But I Have A Defrag Scheduled Task - Why Should I Care?

I recently discovered that although my servers had their defrag jobs scheduled and indeed the jobs were completing, when running a command-line defrag job I found that some drives had much more fragmentation of files than I would have expected. This is due to the fact that with changes to the optimisation methods in Server 2012, the default defrag option is to consolidate slabs of storage, which is effectively a light version of the full defragment process.

More information on the changes in defrag for Windows in Server 2012/R2 can be found at the following:

Fragmentation Level Discovery:

Fragmentation Post CB Remediation Script;

Using PowerShell with SCCM Configuration Baselines to Optimise Disks

So this got me thinking as to a more dynamic way to both monitor and correct the fragmentation levels on my servers. The answer I came up with was to create a Configuration Item and Baseline in SCCM to monitor for the presence of excessive file fragmentation and run through a remediation process to ensure that the drives are always at their optimal performance.


For a full walk through on setting up the configuration items and baselines visit -


Script Extract (Remediation)


     Created with:     SAPIEN Technologies, Inc., PowerShell Studio 2016 v5.3.131 
     Created on:       04/01/2017 12:00 
     Created by:       Maurice.Daly 
     Filename:         DefragmentDetection.PS1 
        Checks the fragmentation levels of all disks on a given host and reports 
        back with the drive with the highest level of fragmentation. 
        This script is designed for use with SCCM as a Configuration Item, a  
        seperate script (DegragmentDrive.PS1) should then be used as a  
        remedial action to defragment all drives above the high water mark  
        level set in your Configuration Baseline 
$MaxFragmentation = "15" 
# Defragmentation Processes 
function DefragCheck ($MaxFragmentation) 
        # Get list of Pysical Disks for determining health status and drive type 
        $Disks = New-Object -TypeName System.Collections.ArrayList 
        # Determine if the machine is virtual or physical then query disks 
        If ((Get-WmiObject -Class Win32_ComputerSystem | Select-Object -Property Model) -like "*Virtual*") 
            $VirtualDisks = (Get-Partition | Get-Disk | Get-PhysicalDisk).DeviceID | Select-Object -Unique | Sort-Object 
            # Add disk to disk array if not present 
            if ($VirtualDisks -ne $null) 
                foreach ($Disk in $VirtualDisks) 
                    if ($Disk -notin $Disks) 
                        $Disks.Add($Disk| Out-Null