cheat sheet

defrag

Analyze, defragment, and optimize volumes from the command line — consolidate free space on HDDs, issue TRIM on SSDs, and schedule or review optimization tasks.

defrag — Disk Defragmenter CLI

What it is

defrag is the Windows command-line interface to the Disk Defragmenter and Storage Optimizer service (dfrgui.exe in the GUI). On HDDs it rearranges fragmented file extents to reduce seek time; on SSDs it sends TRIM commands to notify the drive of freed blocks so the firmware can optimize internally. Windows 8+ also adds slab consolidation for tiered storage and retrim for solid-state media. The GUI equivalent is dfrgui.exe; PowerShell wraps it via Optimize-Volume. Requires Administrator privileges.

Availability

defrag ships as C:\Windows\System32\defrag.exe on Windows Vista and later. SSD-specific optimization (TRIM/retrim) requires Windows 8+.

cmd
defrag /?

Output:

vbnet
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Description:
    Locates and consolidates fragmented files on local volumes to
    improve system performance.

Syntax:
    defrag <volumes> | /E <volumes> | /C | /H | /M [n]| [/U] [/V] [/I n]
        where <volumes> is a drive letter followed by :.

Parameters:
   /A         Perform analysis on the specified volumes.
   /C         Perform the operation on all volumes.
   /D         Perform traditional defrag (this is the default for HDDs).
   /E         Perform the operation on all volumes except those specified.
   /G         Optimize the storage tiers on the specified volumes.
   /H         Run the operation at normal priority (default is low).
   /I n       Tier optimization would run for at most n seconds on each volume.
   /K         Perform slab consolidation on the specified volumes.
   /L         Perform retrim on the specified volumes.
   /M [n]     Run the operation on each volume in parallel in the background.
   /O         Perform the proper optimization for each media type.
   /T         Track an operation already in progress on the specified volume.
   /U         Print the progress of the operation on the screen.
   /V         Print verbose output containing the fragmentation statistics.
   /X         Perform free space consolidation on the specified volumes.

Syntax

cmd
defrag <volume> [/A] [/C] [/D] [/H] [/K] [/L] [/O] [/U] [/V] [/X]

Output: (optimization progress and summary)

Essential options

SwitchMeaning
/AAnalyze only — report fragmentation without defragmenting
/COperate on all volumes
/DTraditional defragmentation (default for HDDs)
/OOptimal optimization per media type (HDD=defrag, SSD=retrim)
/HRun at normal priority instead of low
/KSlab consolidation (tiered storage, Windows 8+)
/LRetrim (SSDs — re-sends TRIM for all free space, Windows 8+)
/UPrint progress while running
/VVerbose — show fragmentation statistics
/XFree space consolidation (move files to one end, freeing a contiguous block)
/TTrack an already-running operation

Analyzing fragmentation

/A runs an analysis pass and prints a fragmentation report without moving any data. Use this to decide whether a full defrag is warranted before committing to the time cost.

cmd
defrag C: /A /U /V

Output:

ini
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking analysis on C: (OS (C:))...
Post Defragmentation Report:

   Volume Information:
     Volume size                 = 499 GB
     Free space                  = 451 GB
     Total fragmented space      = 2%
     Largest free space chunk    = 400 GB

   Note: On NTFS volumes, file fragments larger than 64MB are not included in the fragmentation statistics.

Windows will not defragment this drive because it is not fragmented.

Defragmenting an HDD

Traditional defragmentation relocates file fragments so each file occupies contiguous clusters, reducing rotational latency for mechanical drives. On large volumes this can take 30–60 minutes; /H elevates priority to speed it up at the cost of more I/O impact on running applications.

cmd
defrag D: /D /H /U /V

Output:

ini
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking defrag on D: (Data (D:))...

   10% complete...
   25% complete...
   ...
  100% complete...

Post Defragmentation Report:

   Volume Information:
     Volume size                 = 2000 GB
     Free space                  = 1200 GB
     Total fragmented space      = 0%

Windows successfully defragmented this drive.

Optimizing an SSD (TRIM/retrim)

Solid-state drives do not benefit from traditional defragmentation — shuffling data causes extra write wear. Instead, /O selects the correct optimization for the media type: on SSDs it issues a TRIM pass that notifies the drive's firmware which blocks are free so it can consolidate internally.

cmd
defrag C: /O /U

Output:

yaml
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking optimization on C: (OS (C:))...

   100% complete...

Windows successfully optimized your drive.

Optimizing all volumes at once

/C runs the optimization on every mounted volume. Combine with /O to let Windows choose the appropriate method (defrag for HDD, retrim for SSD) per drive automatically.

cmd
defrag /C /O /U

Output:

yaml
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking optimization on C: (OS (C:))...
Invoking optimization on D: (Data (D:))...

Windows successfully optimized your drives.

Free space consolidation (/X)

/X compacts all free space into a single contiguous region at the end of the volume. This is useful before shrinking a partition with diskpart or a third-party tool, because Windows can only shrink a volume up to the last used cluster.

cmd
defrag D: /X /U

Output:

c
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking free space consolidation on D: (Data (D:))...

   100% complete...

Windows successfully consolidated free space on your drive.

Running at normal priority (/H)

By default defrag runs at low I/O priority to minimize impact on other processes. /H elevates it to normal priority for a faster run — useful during a maintenance window when the machine is otherwise idle.

cmd
defrag E: /D /H /U

Output:

csharp
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking defrag on E: (Backup (E:))...

  100% complete...

Windows successfully defragmented this drive.

Complete flag reference

Every documented switch. Most were added incrementally between Windows Vista (basic defrag), Windows 8 (TRIM, slab consolidation, storage tiers), and Windows 10/11 (parallel runs, performance hint).

SwitchMeaning
/AAnalyze only — report fragmentation, no movement
/BBoot optimization — relocate boot files for faster startup performance
/COperate on all volumes
/DTraditional defragmentation (HDD default)
/EOperate on all volumes except those specified
/GOptimize storage tiers (tiered Storage Spaces)
/HRun at normal priority instead of low
/I NTier optimization runs for at most N seconds per volume
/KSlab consolidation (tiered storage / thin-provisioned LUNs)
/LRetrim — re-issue TRIM for all free space on an SSD
/M [N]Run in parallel in the background, optionally N volumes at once
/OOptimal optimization per media type (best default)
/TTrack an operation already in progress on a volume
/UPrint progress as the operation runs
/VVerbose — print full fragmentation statistics
/XFree-space consolidation (compact free space into one contiguous region)

The "optimal" pass (/O) selects:

  • HDD/D traditional defragmentation.
  • SSD/L retrim.
  • Tiered Storage Spaces/G storage-tier optimization.
  • Thin-provisioned / dedup volumes/K slab consolidation.

This makes defrag <vol> /O /U /V the single safest default invocation across mixed-media fleets.

Detecting media type before optimizing

The Optimizer chooses the right pass automatically, but in scripts it helps to know whether a volume sits on SSD or HDD before deciding to schedule, throttle, or skip.

cmd
rem Inspect a volume from cmd.exe
fsutil fsinfo sectorinfo C:

Output:

yaml
LogicalBytesPerSector :                                  512
PhysicalBytesPerSectorForAtomicity :                    4096
PhysicalBytesPerSectorForPerformance :                  4096
FileSystemEffectivePhysicalBytesPerSectorForAtomicity : 4096
Device Alignment :                                       Aligned (0x000)
Partition alignment on device :                          Aligned (0x000)
No Seek Penalty
Trim Supported

No Seek Penalty plus Trim Supported is the diagnostic fingerprint of an SSD; HDDs report Seek Penalty and lack TRIM.

powershell
# PowerShell equivalent — returns media type directly
Get-PhysicalDisk | Select FriendlyName, MediaType, BusType, Size, HealthStatus

Output:

diff
FriendlyName             MediaType BusType         Size HealthStatus
------------             --------- -------         ---- ------------
Samsung SSD 990 PRO 2TB  SSD       NVMe   2000398934016 Healthy
WDC WD40EFRX-68N32N0     HDD       SATA   4000787030016 Healthy
powershell
# Map disk -> volume so you can decide per-letter
Get-Partition |
    Where-Object DriveLetter |
    ForEach-Object {
        $disk = Get-PhysicalDisk -DeviceNumber $_.DiskNumber
        [PSCustomObject]@{
            Drive     = $_.DriveLetter
            DiskNum   = $_.DiskNumber
            Media     = $disk.MediaType
            Friendly  = $disk.FriendlyName
        }
    }

Output:

markdown
Drive DiskNum Media Friendly
----- ------- ----- --------
    C       0   SSD Samsung SSD 990 PRO 2TB
    D       1   HDD WDC WD40EFRX-68N32N0

Optimize-Volume — the PowerShell equivalent

Optimize-Volume (Storage module, Windows 8 / Server 2012+) is the modern wrapper around defrag.exe. Like Repair-Volume it returns objects, accepts pipelines, and is the right call in scripts.

powershell
# Analyze a volume — equivalent to defrag C: /A /V
Optimize-Volume -DriveLetter C -Analyze -Verbose

Output:

vbnet
VERBOSE: Invoking analysis on (C:)...
VERBOSE: Pre-Optimization Report:
VERBOSE:   Volume Information:
VERBOSE:     Volume size                 = 475.00 GB
VERBOSE:     Free space                  = 234.78 GB
VERBOSE:     Total fragmented space      = 1%
VERBOSE:     Largest free space chunk    = 187.32 GB
VERBOSE: Note: File fragments larger than 64MB are not included in the fragmentation statistics.
VERBOSE: It is not necessary to defragment this volume.
powershell
# Optimal optimization (HDD => defrag, SSD => retrim)
Optimize-Volume -DriveLetter D -Defrag -Verbose

# Retrim an SSD
Optimize-Volume -DriveLetter C -ReTrim -Verbose

# Slab consolidation (thin-provisioned / dedup)
Optimize-Volume -DriveLetter E -SlabConsolidate -Verbose

# Tier optimization (Storage Spaces with SSD + HDD tier)
Optimize-Volume -DriveLetter F -TierOptimize -Verbose

# Pipeline form: optimize every fixed NTFS volume
Get-Volume | Where-Object { $_.DriveType -eq 'Fixed' -and $_.FileSystemType -eq 'NTFS' } |
    Optimize-Volume -ReTrim -Verbose

Output:

vbnet
VERBOSE: Invoking retrim on (C:)...
VERBOSE: Invoking retrim on (D:)...
VERBOSE: Performing pass 1:
VERBOSE: Retrim:  100% complete.
VERBOSE: Post Defragmentation Report:
VERBOSE:   Volume Information:
VERBOSE:     Volume size                 = 475.00 GB
VERBOSE:     Free space                  = 234.78 GB

Optimize-Volume recognizes the same set of media-aware flags as defrag: -Analyze, -Defrag, -ReTrim, -SlabConsolidate, -TierOptimize, -NormalPriority, and -PartialRetrim (Windows 10+).

Reading the Storage Optimizer schedule

Windows 8 and later schedule a weekly Optimizer task at \Microsoft\Windows\Defrag\ScheduledDefrag. The schedule is what dfrgui.exe calls "Optimization on" in the GUI.

cmd
rem View the scheduled task
schtasks /Query /TN "\Microsoft\Windows\Defrag\ScheduledDefrag" /V /FO LIST

Output:

yaml
HostName:                             MYHOST
TaskName:                             \Microsoft\Windows\Defrag\ScheduledDefrag
Task To Run:                          %windir%\system32\defrag.exe -c -h -o -$
Status:                               Ready
Next Run Time:                        5/26/2026 1:00:00 AM
Schedule Type:                        Weekly
Start Time:                           01:00:00
powershell
# PowerShell view — richer fields
Get-ScheduledTask -TaskPath '\Microsoft\Windows\Defrag\' |
    Select-Object TaskName, State, @{n='LastRun';e={(Get-ScheduledTaskInfo $_).LastRunTime}}

Output:

diff
TaskName        State  LastRun
--------        -----  -------
ScheduledDefrag Ready  5/19/2026 1:00:08 AM
cmd
rem Run the scheduled optimization right now (does not change the schedule)
schtasks /Run /TN "\Microsoft\Windows\Defrag\ScheduledDefrag"

Output:

vbnet
SUCCESS: Attempted to run the scheduled task "\Microsoft\Windows\Defrag\ScheduledDefrag".

Inspecting the last optimization

Each volume records the timestamp of its last successful optimization in the registry. The Optimizer GUI reads this; Get-WmiObject and Get-Volume expose it programmatically.

powershell
# Last-optimization data, per volume
Get-Volume | Where-Object DriveLetter | ForEach-Object {
    $stats = (defrag $_.DriveLetter": /A /V 2>&1)
    [PSCustomObject]@{
        Drive    = "$($_.DriveLetter):"
        SizeGB   = [math]::Round($_.Size / 1GB, 1)
        FreeGB   = [math]::Round($_.SizeRemaining / 1GB, 1)
        Report   = ($stats -join "`n")
    }
} | Format-Table Drive, SizeGB, FreeGB -AutoSize

Output:

yaml
Drive SizeGB FreeGB
----- ------ ------
C:     475.0  234.8
D:    1862.4  843.2
powershell
# Operational event log (Windows 8+) — exact run history
Get-WinEvent -LogName Microsoft-Windows-Defrag/Operational -MaxEvents 5 |
    Select TimeCreated, Id, LevelDisplayName, Message

Output:

csharp
TimeCreated         Id LevelDisplayName Message
-----------         -- ---------------- -------
5/19/2026 1:00:08 AM 258 Information      The storage optimizer successfully completed defragmentation on D:.
5/19/2026 1:00:02 AM 258 Information      The storage optimizer successfully completed retrim on C:.

Slab consolidation and storage tiering

Slab consolidation (/K) is for thin-provisioned and deduplicated volumes — it coalesces tiny "slabs" of allocation so the underlying storage layer can release unused space. Tier optimization (/G) moves the hottest data into the SSD tier of a Storage Spaces virtual disk.

cmd
rem Slab consolidation on a dedup volume
defrag X: /K /U /V

Output:

csharp
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking slab consolidation on X: (Dedup (X:))...

   100% complete...

Windows successfully completed slab consolidation on your drive.
cmd
rem Storage-tier optimization on a tiered volume — cap at 30 minutes
defrag F: /G /I 1800 /U

Output:

r
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking tier optimization on F: (Tiered (F:))...

   100% complete...

Windows successfully optimized the storage tiers on your drive.
powershell
# PowerShell equivalents — Storage Spaces-aware
Get-VirtualDisk | Where-Object ResiliencySettingName -eq 'Mirror' |
    Get-Disk | Get-Partition | Where-Object DriveLetter |
    Select DriveLetter, Size

Optimize-Volume -DriveLetter F -TierOptimize -Verbose
Optimize-Volume -DriveLetter X -SlabConsolidate -Verbose

Output:

vbnet
DriveLetter         Size
-----------         ----
F           4398046511104

VERBOSE: Invoking tier optimization on (F:)...
VERBOSE: Tier optimization:  100% complete.
VERBOSE: Windows successfully optimized the storage tiers on your drive.

Parallel runs in the background (/M)

/M [N] farms each volume out to a background worker. Without N the Optimizer picks a sensible parallelism (one per physical disk); supplying N caps the concurrency.

cmd
rem Optimize all volumes, up to 4 in parallel, low priority
defrag /C /O /M 4

Output:

yaml
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking optimization on C: in the background...
Invoking optimization on D: in the background...
Invoking optimization on E: in the background...
Invoking optimization on F: in the background...
cmd
rem Track a background run's progress
defrag D: /T

Output:

scss
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Tracking operation in progress on D: (Data (D:))...
   45% complete...

Boot-time defragmentation

Windows performs limited boot-time defragmentation through the Prefetcher, which contiguously lays out frequently-loaded boot files. This is on by default; verify and adjust via the registry. defrag /B triggers a one-shot boot-optimization pass that relocates the boot files into the contiguous prefetch layout without waiting for the next idle-task run.

cmd
rem One-shot boot optimization (Vista+; useful after major Windows updates)
defrag C: /B /U

Output:

csharp
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking boot optimization on C: (OS (C:))...
   100% complete...
Windows successfully optimized the boot files on your drive.
cmd
rem Confirm boot-time defragmentation is enabled
reg query "HKLM\SOFTWARE\Microsoft\Dfrg\BootOptimizeFunction" /v Enable

Output:

css
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Dfrg\BootOptimizeFunction
    Enable    REG_SZ    Y
cmd
rem Trigger a manual boot-file relocation (idle task ID 56)
rundll32.exe advapi32.dll,ProcessIdleTasks

Output:

ini
(no output — exits 0; the boot Prefetcher schedules layout work for idle time)

The legacy registry path under HKLM\SOFTWARE\Microsoft\Dfrg is also where Storage Spaces saves its optimizer policy; modify it only when fully aware of the implications.

Exclusions — keeping a volume out of the schedule

Add a volume to the Optimizer exclusion list when scheduled defrag does more harm than good — for example, a SAN LUN that thin-provisions and prefers its own optimization.

cmd
rem GUI path:
rem dfrgui.exe → Change settings → Choose → Uncheck volume

rem CLI: defrag has no built-in exclusion list, but the scheduled task can be edited
schtasks /Change /TN "\Microsoft\Windows\Defrag\ScheduledDefrag" /TR "%windir%\system32\defrag.exe -c -h -o -$ /E F:"

Output:

vbnet
SUCCESS: The parameters of scheduled task "\Microsoft\Windows\Defrag\ScheduledDefrag" have been changed.
powershell
# Run defrag for all volumes except E: and F: — handy in maintenance windows
defrag /E E: F: /O /H /U

Output:

yaml
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking optimization on C: (OS (C:))...
Invoking optimization on D: (Data (D:))...
   100% complete...
Windows successfully optimized your drives.

NTFS vs ReFS: defrag relevance

ReFS does not need a traditional defragmentation pass — metadata is stored as a B+ tree that does not fragment in the same way, and integrity streams handle integrity rather than contiguity. The Optimizer reports ReFS volumes as Not available for defrag and Available for retrim.

cmd
rem Analyze a ReFS volume
defrag R: /A /V

Output:

yaml
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking analysis on R: (ReFS (R:))...

Post Defragmentation Report:

   Volume Information:
     Volume size                 = 4096 GB
     Free space                  = 2200 GB
     Defragmentation is not available for this volume.
powershell
# ReFS still benefits from retrim if backed by SSDs
Optimize-Volume -DriveLetter R -ReTrim -Verbose

Output:

less
VERBOSE: Invoking retrim on (R:)...
VERBOSE: Retrim:  100% complete.

Cross-references: where defrag fits in the toolchain

ToolWhen to use
defrag / Optimize-VolumePer-volume defragmentation, retrim, slab consolidation.
chkdsk / Repair-VolumeFile-system integrity. See sections/windows/chkdsk.
fsutil fsinfoPer-volume media properties (TRIM, seek penalty). See sections/windows/fsutil.
diskpart shrinkResize a partition after /X consolidates free space. See sections/windows/diskpart.
Get-PhysicalDisk / Get-DiskInventory media type and disk health.
Get-StorageTier / Optimize-StoragePoolStorage Spaces-level tier optimization.
dism /Online /Cleanup-Image /StartComponentCleanupReclaim WinSxS space before/after defrag. See sections/windows/dism.
df / du / duf (Linux)Cross-platform space accounting via WSL. See sections/linux/df-du-duf.
powershell
# Compose: clean up component store, then optimize C: in one go
dism /Online /Cleanup-Image /StartComponentCleanup
Optimize-Volume -DriveLetter C -ReTrim -Verbose

Output:

vbnet
[==========================100.0%==========================]
The operation completed successfully.
VERBOSE: Invoking retrim on (C:)...
VERBOSE: Retrim:  100% complete.

Common pitfalls

  1. Never defrag an SSD with /D — traditional defragmentation increases write cycles without improving performance; use /O or /L instead.
  2. /X must precede a diskpart shrink — shrink only reclaims space past the last used cluster; consolidating free space first maximises how much can be reclaimed.
  3. Requires elevation — running without Administrator returns "Access denied"; right-click cmd.exe → Run as administrator.
  4. /A on SSDs always reports near-zero fragmentation — this is correct; NTFS stores SSD files contiguously by default; the metric is meaningful only for HDDs.
  5. Low priority by default means it yields to other I/O — on a busy server, a defrag pass at low priority can stall for hours; use /H with a planned maintenance window.
  6. Disabling the scheduled task hurts SSDs — the weekly Optimizer task is the only thing that issues retrim on SSDs; disabling it lets stale TRIM data accumulate.
  7. Tier optimization without SSD tier is wasted work/G only makes sense on tiered Storage Spaces virtual disks; on a single-tier pool it returns immediately.
  8. Slab consolidation requires dedup or thin-provisioning/K on a normally-allocated NTFS volume is a no-op.
  9. defrag cannot operate on a BitLocker volume that's locked — unlock first with manage-bde -unlock; the Optimizer fails silently otherwise.
  10. VSS shadow copies can be deleted by defragmentation — Windows tries to preserve them, but heavy defrag on an HDD with shadow copies in the differential area can evict the oldest snapshots; verify with vssadmin list shadows before/after.
  11. Mounted ISOs report as fixed disks — running defrag against a mounted ISO succeeds nominally but does nothing useful; check Get-Volume DriveType first.
  12. Optimize-Volume -ReTrim does not free deleted-file space on encrypted SSDs — for Self-Encrypting Drives (SEDs) under BitLocker, retrim still works because BitLocker passes the TRIM command through, but on third-party software-encrypted volumes TRIM may be blocked.
  13. /V output is localizedTotal fragmented space becomes Insgesamt fragmentierter Speicherplatz on German Windows; prefer Optimize-Volume -Verbose (returns enum-driven output) for parsing.

Real-world recipes

Analyze all drives and print a report

cmd
defrag /C /A /U /V

Output:

csharp
Microsoft Drive Optimizer
Copyright (c) 2013 Microsoft Corp.

Invoking analysis on C: (OS (C:))...
   Total fragmented space = 0%
Windows will not defragment this drive because it is not fragmented.

Invoking analysis on D: (Data (D:))...
   Total fragmented space = 12%
Windows recommends defragmenting this drive.

Prepare a volume for shrinking

cmd
@echo off
echo Consolidating free space on D: before partition shrink...
defrag D: /X /H /U
echo Done. You can now shrink D: in diskpart.

Output:

python-repl
Consolidating free space on D: before partition shrink...
Microsoft Drive Optimizer
...
  100% complete...
Done. You can now shrink D: in diskpart.

Nightly optimization of all volumes via scheduled task

cmd
schtasks /Create /TN "Maintenance\NightlyDefrag" /TR "defrag /C /O /H" /SC DAILY /ST 02:00 /RU SYSTEM /F

Output:

vbnet
SUCCESS: The scheduled task "Maintenance\NightlyDefrag" has successfully been created.

Media-aware fleet sweep with PowerShell

Run the correct optimization pass for each volume's media type across a fleet, with timestamps and rollup.

powershell
$hosts = Get-Content C:\Ops\hostlist.txt
$report = foreach ($host in $hosts) {
    Invoke-Command -ComputerName $host -ErrorAction SilentlyContinue -ScriptBlock {
        Get-Partition | Where-Object DriveLetter | ForEach-Object {
            $disk    = Get-PhysicalDisk -DeviceNumber $_.DiskNumber
            $action  = if ($disk.MediaType -eq 'SSD') { 'ReTrim' } else { 'Defrag' }
            try {
                Optimize-Volume -DriveLetter $_.DriveLetter -$action -Verbose -ErrorAction Stop
                $result = 'OK'
            } catch { $result = "FAILED: $($_.Exception.Message)" }
            [PSCustomObject]@{
                Host   = $env:COMPUTERNAME
                Drive  = "$($_.DriveLetter):"
                Media  = $disk.MediaType
                Action = $action
                Result = $result
            }
        }
    }
}
$report | Format-Table -AutoSize
$report | Export-Csv C:\Ops\defrag_sweep.csv -NoTypeInformation

Output:

yaml
Host    Drive Media Action Result
----    ----- ----- ------ ------
MYHOST  C:    SSD   ReTrim OK
MYHOST  D:    HDD   Defrag OK
SRV01   C:    SSD   ReTrim OK
SRV02   C:    HDD   Defrag FAILED: Access is denied.

Shrink-prep wrapper

Run /X then drop into diskpart to shrink — the standard pre-shrink choreography in one script.

cmd
@echo off
set DRIVE=D:
set SHRINK_MB=51200

echo Step 1/3: Consolidating free space on %DRIVE%...
defrag %DRIVE% /X /H /U

echo Step 2/3: Disabling hibernation (to free hiberfil.sys at end of volume)...
powercfg /h off

echo Step 3/3: Shrinking %DRIVE% by %SHRINK_MB% MB...
(echo select volume %DRIVE:~0,1%
 echo shrink desired=%SHRINK_MB%
 echo exit) | diskpart

echo Done.

Output:

vbnet
Step 1/3: Consolidating free space on D:...
   100% complete...
Step 2/3: Disabling hibernation (to free hiberfil.sys at end of volume)...
Step 3/3: Shrinking D: by 51200 MB...
DiskPart successfully shrunk the volume by:  51200 MB
Done.

Skip the Optimizer for thin-provisioned volumes

Disable the schedule for a single volume by changing the scheduled task arguments. This is the supported way to exclude a volume from the global weekly task.

powershell
$task = Get-ScheduledTask -TaskPath '\Microsoft\Windows\Defrag\' -TaskName ScheduledDefrag
$task.Actions[0].Arguments = '-c -h -o -$ /E F: G:'
Set-ScheduledTask -InputObject $task

Output:

diff
TaskPath              TaskName        State
--------              --------        -----
\Microsoft\Windows\Defrag\ ScheduledDefrag Ready

Sources

Microsoft Learn — defrag command — Full switch reference including /B boot optimization, supported file systems (NTFS, ReFS, FAT, FAT32), the 15% free-space requirement, scheduled task behaviour, and the SSD policy of running traditional defragmentation only once per month from the scheduled task.

Microsoft Learn — Optimize-Volume cmdlet — PowerShell wrapper with -Analyze, -Defrag, -ReTrim, -SlabConsolidate, -TierOptimize, and -BootOptimize parameters; the modern equivalent of defrag.exe for script automation.