Using VBScript to Check Partitions for Advanced Format (4K / 512e) Sector Alignment

As you may know Dell recently announced that they will start shipping Advanced Format (4k/512e) drives in their enterprise systems in May 2011.  For those not wanting to follow the links, the cliff’s notes version is that Advanced Format drives use a 4096 byte (4k) sector rather than a 512 byte sector.  This allows higher bit densities by reducing the amount of space tied up in ECC and sector gap.

Old and New Sector Formats Credit: Dougolsen / Wikimedia Commons
Old and New Sector Formats Credit: Dougolsen / Wikimedia Commons

So what’s the big deal then?  Well in order to make the transition, 4K/512e advanced format drives still present themselves externally as a 512 byte per sector drive, and internally lump reads and writes into eight logical 512 byte sectors to match up with their physical 4096 byte sectors.  This has the unfortunate side effect that if your partitions are not aligned to a 4K boundary the disk may have to perform a Read-Modify-Write across two physical sectors.  This process can incur extra latency waiting for an additional rotation of the disk platters which drastically impacts performance.  Further compounding the matter Windows XP/2003 operating systems and most disk management tools create the first partition on the disk starting at LBA sector 63 which if you do your math correctly is not 4K aligned.

Recently the question came up as to whether or not it was possible to use a script to detect partitions that were not 4K aligned and therefore may be causing performance issues, or to perhaps use in an OSD task sequence to halt the OS install if the partition is not correctly aligned.  After some browsing through the WMI classes I found what I was looking for.  The Win32_DiskPartion class has a property StartingOffset that, according to MSDN is in fact the “starting offset (in bytes) of the partition”.  A little modulus division later and you have a simple way to determine if your partition is 4K sector aligned.

Option Explicit

Dim strComputer: strComputer = "."
Dim objWMIService: Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Dim colPartitions: Set colPartitions = objWMIService.ExecQuery("Select * from Win32_DiskPartition",,48)

Dim objPartition
For Each objPartition In colPartitions
    Dim iResult: iResult = objPartition.StartingOffset / 4096
    If iResult = Fix(iResult) Then
        WScript.Echo objPartition.Caption & " is 4K/512e sector aligned."
    Else
        WScript.Echo objPartition.Caption & " is NOT 4K/512e sector aligned."
    End If
Next

There is one caveat I should mention if you’re planning to use this in an OSD task sequence from WinPE.  It seems that the Win32_DiskPartition class has been removed from WinPE 3.x.  Luckily others already have a solution for you.

UPDATE: 5/26/11

Per the request by Eric in the comments I’ve updated the script to show the drive letter associated with the partition. 

Option Explicit

Dim strComputer: strComputer = "."
Dim objWMIService: Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Dim colPartitions: Set colPartitions = objWMIService.ExecQuery("Select * from Win32_DiskPartition",,48)

Dim objPartition

For Each objPartition In colPartitions
    Dim strDriveLetter: strDriveLetter = PartitionToDrive(objWMIService, objPartition.DeviceID)
    Dim iResult: iResult = objPartition.StartingOffset / 4096
    If iResult = Fix(iResult) Then
        WScript.Echo "(" & strDriveLetter & ") " & objPartition.Caption & " is 4K/512e sector aligned."
    Else
        WScript.Echo "(" & strDriveLetter & ") " & objPartition.Caption & " is NOT 4K/512e sector aligned."
    End If
Next

Private Function PartitionToDrive(objWMIService, DeviceID)
    Dim objLogcialDisks: Set objLogcialDisks = objWMIService.ExecQuery( _
    "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" & DeviceID & _
    "'} WHERE AssocClass = Win32_LogicalDiskToPartition")

    Dim objLogicalDisk
    For Each objLogicalDisk In objLogcialDisks
        PartitionToDrive = objLogicalDisk.DeviceID
        Exit Function
    Next

    PartitionToDrive = ""
End Function
Advertisements