How to Defrag Drives using Powershell in Windows Server 2012
I’ve written about how you can use PowerShell to repair disk volumes, but another common server maintenance task is identifying and defragmenting drives. There are a number of enterprise solutions available on the market which might make sense for many organizations. But if you lack the budget, run a smaller shop, or prefer to do your own thing, managing this task is a little more difficult. There has been the command line tool, defrag.exe, but it needs to be combined with other techniques to handle remote systems.
With Windows Server 2012 and Windows 8, we have some new tools at our disposal for managing the defrag task using PowerShell v3. I should point out that even though you need PowerShell v3, this is operating system-specific, as it uses the new Storage module that is only available on Windows Server 2012 and Windows 8. Don’t have that? I’ll offer you an Powershell alternative later in the article.
Defrag Drives with Optimize-Volume
The new cmdlet we will use is called Optimize-Volume. It is part of the Storage module which utilizes the new CIM infrastructure. You can use this cmdlet to analyze and defrag all types of volumes.
Passwords Haven’t Disappeared Yet
123456. Qwerty. Iloveyou. No, these are not exercises for people who are brand new to typing. Shockingly, they are among the most common passwords that end users choose in 2021. Research has found that the average business user must manually type out, or copy/paste, the credentials to 154 websites per month. We repeatedly got one question that surprised us: “Why would I ever trust a third party with control of my network?
We’ll focus on logical drives like C:.
How to Run an Analysis
To run an analysis all you need to do is run a command like this:
PS C:\> Optimize-Volume G –Analyze
But for some reason unknown to me, the cmdlet doesn’t write any sort of result to the pipeline! Instead you have to use the –Verbose parameter.
PS C:\> Optimize-Volume G –Analyze -verbose
You should get something like Figure 2:
So you can get the information you need, but it takes an extra step. If you want to save the results, you’ll need to redirect the verbose output.
PS C:\> Optimize-Volume G –Analyze –verbose 4>c:\work\GDrive.txt
On the positive side, you can specify a remote computer using –CIMSession. The remote computer must be running Windows Server 2012 or Windows 8.
PS C:\> Optimize-Volume C –Analyze –Cimsession CHI-DC03 –verbose 4>c:\work\dc03-c.txt
You can either specify a computer name, as I’ve done here, or an existing CIM session object. This makes it (sort of) easy to analyze the same drive across multiple computers.
How to Defrag a Drive
When the time comes to perform the defrag, we can use the same cmdlet, but without the –Analyze parameter.
PS C:\> Optimize-Volume d -Verbose -CimSession novo8
Again, I used –Verbose so I can see what happened in Figure 3.
Optimize-Volume will automatically perform additional operations such as trimming, depending on the drive type. So for an SSD drive the cmdlet should automatically retrim, but you can specify –Retrim if you want.
Defragmenting Drives: A PowerShell Alternative
Now, you could set up a scheduled task to use Optimize-Volume to defrag key volumes on your servers on a regular basis, regardless of whether they need them, but personally, I’d like a bit more control. And what if you don’t have Windows Server 2012? Either way, you’ll need an alternative.
I wrote a PowerShell function called Get-DefragAnalysis that works with PowerShell v2. You can download the Get-DefragAnalysis function. Once loaded into your PowerShell session, you can specify a drive and computers to scan.
PS C:\> $analysis = Get-DefragAnalysis -Driveletter C: -Computername chi-dc01,chi-dc02,chi-dc03
The function writes an object like this to pipeline:
AverageFileSize : 64 AverageFragmentsPerFile : 1 AverageFreeSpacePerExtent : 17002496 ClusterSize : 4096 ExcessFolderFragments : 0 FilePercentFragmentation : 0 FragmentedFolders : 0 FreeSpace : 161816576 FreeSpacePercent : 77 FreeSpacePercentFragmentation : 29 LargestFreeSpaceExtent : 113500160 MFTPercentInUse : 100 MFTRecordCount : 511 PageFileSize : 0 TotalExcessFragments : 0 TotalFiles : 182 TotalFolders : 11 TotalFragmentedFiles : 0 TotalFreeSpaceExtents : 8 TotalMFTFragments : 1 TotalMFTSize : 524288 TotalPageFileFragments : 0 TotalPercentFragmentation : 0 TotalUnmovableFiles : 4 UsedSpace : 47894528 VolumeName : VolumeSize : 209711104 Driveletter : E: DefragRecommended : False Computername : NOVO8
This gives you information that you can base management decisions on. It also means I can take my results and get a quick report of where I need to defrag.
PS C:\> $analysis | Select Computername,Driveletter,FreespacePercent,DefragRecommended Computername Driveletter FreeSpacePercent DefragRecommended ------------ ----------- ---------------- ----------------- CHI-DC01 C: 19 False CHI-DC02 C: 29 True CHI-DC03 C: 68 True
You can easily defrag volumes remotely with a command like this:
PS C:\> Get-WmiObject win32_volume -filter "driveletter='c:'" -ComputerName chi-dc02 | Invoke-WmiMethod -Name Defrag
PowerShell continues to be a blessing for IT pros, especially when it comes to managing Windows Server 2012. Granted, there are some limitations with Optimize-Volume, at least the way I would expect to use it, but it is a relatively easy way to get a handle on what volumes need to be defragged. It also handles the variety of storage types you most likely have in your environment. For everything else, I hope my Get-DefragAnalysis tool helps fill in the gaps.