StorageDsc
StorageDsc copied to clipboard
DSC_Disk trigers defrag
Problem description
we use the storage dsc to configure disks. but each time it runs (Test-targetResource), it triggers a defrag. This can be seen in the eventlog.
i have traced it down to the Get-PartitionSupportedSize cmdlet. The doc at MS conform this. "This cmdlet starts the "Optimize Drive" (defragsvc) service. This could lead to longer execution time on larger fragmented drives."
This defrag makes the dsc module slow and uses a lot of disk IO.
I'm sorry, but our environment is an offline one, i cannot post much info about it.
edit: just seen it is a known problem, the fix will stil work.
Verbose logs
this is not in the log. you can see it in the application eventlog.
Get-PartitionSupportedSize -DiskNumber 0 -PartitionNumber 4 triggers it for me, but any disk/partition with a (ntfs) volume on it will do.
DSC configuration
Disk JVolume
{
DiskId = 2
DriveLetter = 'J'
FSLabel = 'Data'
}
Suggested solution
Replace
Get-PartitionSupportedSize
with $(get-partition).size in the disk resource.
on my system the results are: [math]::Truncate( $( Get-PartitionSupportedSize -DiskNumber 0 -PartitionNumber 4).SizeMax /1MB ) 129432
[math]::Truncate($(get-partition -DiskNumber 0 -PartitionNumber 4).size /1MB) 129432
When changed to MB, there is no difference between the two.
when measured : Measure-Command { [math]::Truncate( $( Get-PartitionSupportedSize -DiskNumber 0 -PartitionNumber 4).SizeMax /1024/1024 )# for MB } Days : 0 Hours : 0 Minutes : 0 Seconds : 40 Milliseconds : 54 Ticks : 400545516 TotalDays : 0.000463594347222222 TotalHours : 0.0111262643333333 TotalMinutes : 0.66757586 TotalSeconds : 40.0545516 TotalMilliseconds : 40054.5516
Measure-Command { [math]::Truncate($(get-partition -DiskNumber 0 -PartitionNumber 4).size /1024/1024) } Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 167 Ticks : 1677114 TotalDays : 1.94110416666667E-06 TotalHours : 4.65865E-05 TotalMinutes : 0.00279519 TotalSeconds : 0.1677114 TotalMilliseconds : 167.7114
From 40+ seeconds to almost instant.
The added "/1MB" and Truncate should also "fix" the size difference mentioned in #181
But this would not allow the disk to be extended.
row 812 is now:
$supportedSize = ($partition | Get-PartitionSupportedSize)
this could be:
$diskSize = [math]::Truncate($disk.size /1GB)
$totalSize = [math]::Truncate($(Get-Partition -DiskId $DiskId | measure-object -sum -Property size).Sum /1GB)
if($diskSize -gt $totalSize)
{
$supportedSize = ($partition | Get-PartitionSupportedSize)
}
else
{
$supportedSize = [pscustomobject]@{
SizeMin = $partition.Size
SizeMax = $partition.Size
}
}
This would only run the Get-PartitionSupportedSize when there is free room on the disk. When all space on the disk is used for partitions, there is no need to run the expensive get-partitionSupportedSize
Operating system the target node is running
tried this on windows 10, 2012 2016 2019
From https://docs.microsoft.com/en-us/powershell/module/storage/get-partitionsupportedsize?view=winserver2012-ps :
This cmdlet starts the "Optimize Drive" (defragsvc) service. This could lead to longer execution time on larger fragmented drives.
From https://docs.microsoft.com/en-us/powershell/module/storage/get-partitionsupportedsize?view=windowsserver2022-ps :
This cmdlet starts the "Optimize Drive" (defragsvc) service. This could lead to longer execution time on larger fragmented drives.
This is as designed. dont know why. but it is what it is........
PowerShell version and build the target node is running
5.1 6 and 7 all the same.
StorageDsc version
most recent. ( 5.01 )
Hi @Fiander - thank you for raising this. That is really useful information.
I'm thinking we could put this into a new support function Get-PartitionSupportedSizeAvoidDefrag (although I'm not a fan of the name). This would allow easier unit testing.
Happy to take a PR for this.