Yes, you read that right. I WANT to fragment a hard drive. I want to do it well. I want it relatively quickly (one day vs. three years). And, you know what, it isn't as easy as you might expect.
I mean, I could install a Windows XP virtual machine, and then update it. But, it is use over time that causes fragmentation. The writing and deleting of files. The intermix of small and large files. Unless you have an old server sitting around you don't have it.
Oh, and I want to do this in a virtual machine. Hmm...So that means I can only go backward about six years at the very most. And who has had a single virtual machine running for six years? (at least that I can get my hands on..)
Needless to say, I have been busy the past couple days with PowerShell.
My theory is this: Write a bunch of little files. Randomly delete them. Write some big files. Randomly delete them and check the result.
My results have been promising. I may need to tweak it a bit to be sure to break near non-standard disk sizing increments. But for a first try it was not too bad. On a side note. Nothing can simulate fragmentation like a PC that has been running in continuous service for many years, without a good 3rd party defragmentation.
Here is my PowerShell script:
# This is a script designed to highly fragment a system disk in one pass.
# The theory is to nearly fill the disk with 128kb files, then to delete
# one-half of those files, then populate the disk with 2Mb files, then remove a portion of those.
#
# I am going to use randomization in the delete functions, therefore it is unknown exactly
# how many files might be deleted, because an empty array location might be chosen.
# Initiate the random number function
$Random=New-Object System.Random (get-date).millisecond
# Get the System Disk
$systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive}
# determine 10%
$tenPercent = $systemDisk.Size / 10
# Move to to the system Temp folder where we will do the workset-Location $Env:Temp
################################################################################ Write lots of 128kb files
###############################################################################
write-host "Write lots of 128kb files"
# An array for the names
$128kNames = @()
#Create the sample 128k file
$fileToCopy = "128kSample.txt"
for ( $i = 0; $i -lt 21843; $i++) { "1" | Out-File $fileToCopy -append }
While ($systemDisk.FreeSpace -gt $tenPercent) { Clear-Host Write-Host "Writing small files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Cycle: " $128kNames.Count
# Set the file name
$file = [string]$systemDisk.FreeSpace +".txt" copy $fileToCopy $file
# Write the file name to the array
$128kNames = $128kNames + $file
# Requery the disk $systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive} }
################################################################################ Delete half of the 128kb files
###############################################################################
write-host "Delete half of the 128kb files"
# 1/2 of names in the array
$half = $128kNames.Count / 2
While ($half -gt 0) {
Clear-Host Write-Host "Deleting small files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Countdown: " $half
$rndName = $128kNames[$Random.Next(0, $128kNames.Count)]
Remove-Item $rndName $half-- }
# Requery the disk
$systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive}
# Clear the small name array
$128kNames = 0
################################################################################ Write lots of 2Mb files
###############################################################################
write-host "Write lots of 2Mb files"
# An array for the names
$2mbNames = @()
#Create the sample 2Mb file
$fileToCopy = "2MbSample.txt"
for ( $i = 0; $i -lt 349512; $i++) { "0" | Out-File $fileToCopy -append }
While ($systemDisk.FreeSpace -gt $tenPercent) {
Clear-Host Write-Host "Writing large files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Cycle: " $2MbNames.Count
# Set the file name
$file = [string]$systemDisk.FreeSpace +"2mb.txt" copy $fileToCopy $file
# Write the file name to the array
$2mbNames = $2mbNames + $file
# Requery the disk
$systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive} }
################################################################################ Delete half of the 2Mb files
###############################################################################
write-host "Delete half of the 2Mb files"
# 1/2 of names in the array
$half = $2mbNames.Count / 2
While ($half -gt 0) {
Clear-Host Write-Host "Deleting large files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Countdown: " $half
$rndName = $2mbNames[$Random.Next(0, $2mbNames.Count)]
Remove-Item $rndName $half-- }
Clear-HostWrite-Host "Finally done"
# What is the damage?
# THIS DOES NOT WORK ON WIN XP AND EARLIER - THIS CLASS IS NOT AVAILABLE
# $sysVolume = get-wmiObject win32_volume | where {$_.DriveLetter -eq $Env:SystemDrive}
# $sysVolume.DefragAnalysis
I mean, I could install a Windows XP virtual machine, and then update it. But, it is use over time that causes fragmentation. The writing and deleting of files. The intermix of small and large files. Unless you have an old server sitting around you don't have it.
Oh, and I want to do this in a virtual machine. Hmm...So that means I can only go backward about six years at the very most. And who has had a single virtual machine running for six years? (at least that I can get my hands on..)
Needless to say, I have been busy the past couple days with PowerShell.
My theory is this: Write a bunch of little files. Randomly delete them. Write some big files. Randomly delete them and check the result.
My results have been promising. I may need to tweak it a bit to be sure to break near non-standard disk sizing increments. But for a first try it was not too bad. On a side note. Nothing can simulate fragmentation like a PC that has been running in continuous service for many years, without a good 3rd party defragmentation.
Here is my PowerShell script:
# This is a script designed to highly fragment a system disk in one pass.
# The theory is to nearly fill the disk with 128kb files, then to delete
# one-half of those files, then populate the disk with 2Mb files, then remove a portion of those.
#
# I am going to use randomization in the delete functions, therefore it is unknown exactly
# how many files might be deleted, because an empty array location might be chosen.
# Initiate the random number function
$Random=New-Object System.Random (get-date).millisecond
# Get the System Disk
$systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive}
# determine 10%
$tenPercent = $systemDisk.Size / 10
# Move to to the system Temp folder where we will do the workset-Location $Env:Temp
################################################################################ Write lots of 128kb files
###############################################################################
write-host "Write lots of 128kb files"
# An array for the names
$128kNames = @()
#Create the sample 128k file
$fileToCopy = "128kSample.txt"
for ( $i = 0; $i -lt 21843; $i++) { "1" | Out-File $fileToCopy -append }
While ($systemDisk.FreeSpace -gt $tenPercent) { Clear-Host Write-Host "Writing small files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Cycle: " $128kNames.Count
# Set the file name
$file = [string]$systemDisk.FreeSpace +".txt" copy $fileToCopy $file
# Write the file name to the array
$128kNames = $128kNames + $file
# Requery the disk $systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive} }
################################################################################ Delete half of the 128kb files
###############################################################################
write-host "Delete half of the 128kb files"
# 1/2 of names in the array
$half = $128kNames.Count / 2
While ($half -gt 0) {
Clear-Host Write-Host "Deleting small files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Countdown: " $half
$rndName = $128kNames[$Random.Next(0, $128kNames.Count)]
Remove-Item $rndName $half-- }
# Requery the disk
$systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive}
# Clear the small name array
$128kNames = 0
################################################################################ Write lots of 2Mb files
###############################################################################
write-host "Write lots of 2Mb files"
# An array for the names
$2mbNames = @()
#Create the sample 2Mb file
$fileToCopy = "2MbSample.txt"
for ( $i = 0; $i -lt 349512; $i++) { "0" | Out-File $fileToCopy -append }
While ($systemDisk.FreeSpace -gt $tenPercent) {
Clear-Host Write-Host "Writing large files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Cycle: " $2MbNames.Count
# Set the file name
$file = [string]$systemDisk.FreeSpace +"2mb.txt" copy $fileToCopy $file
# Write the file name to the array
$2mbNames = $2mbNames + $file
# Requery the disk
$systemDisk = get-wmiObject win32_LogicalDisk | where {$_.DeviceId -eq $Env:SystemDrive} }
################################################################################ Delete half of the 2Mb files
###############################################################################
write-host "Delete half of the 2Mb files"
# 1/2 of names in the array
$half = $2mbNames.Count / 2
While ($half -gt 0) {
Clear-Host Write-Host "Deleting large files" Write-Host "Remaining free space is: " $systemDisk.FreeSpace Write-Host "Countdown: " $half
$rndName = $2mbNames[$Random.Next(0, $2mbNames.Count)]
Remove-Item $rndName $half-- }
Clear-HostWrite-Host "Finally done"
# What is the damage?
# THIS DOES NOT WORK ON WIN XP AND EARLIER - THIS CLASS IS NOT AVAILABLE
# $sysVolume = get-wmiObject win32_volume | where {$_.DriveLetter -eq $Env:SystemDrive}
# $sysVolume.DefragAnalysis