FacebooktwitterredditlinkedinmailFacebooktwitterredditlinkedinmail

A common request when creating automated desktop builds or custom maintenance tools is the ability detect if the main system drive is an SSD disk or not. This information can be used to configure a system in a particular way. For example, to run (or not run) certain maintenance tasks or to optimally configure the system settings or services to take advantage of the way SSD disks perform.

Recent versions of Windows, like Windows 8, automatically optimise certain tasks if an SSD is detected, but earlier versions of Windows commonly used in corporate environments lack this functionality so it must be done manually. This kind of process is prone to errors as it relies on having the engineer decide if the disk is an SSD as some sort of build parameter. In other cases I’ve seen people maintain lists of drive vendors and models that are entered into .txt files and used by scripts and WMI calls to look for a match.

I recently released an updated version of the AutoIt scripting language and as part of the update I wanted to update the DriveGetType function to provide a solution to this problem. I added the ability to detect the bus and SSD status of a drive. The basis of the method I used is that described in this TechNet blog post about how the Windows defragmenter determines SSD drives. The main tests it performs are:

  • Disks whose driver reports “no seek penalty”.
  • Disks that report a nominal media rotation rate of 1.

Mostly all modern SSD drives are populating these values so it’s a better way of detection than checking WMI for vendor strings.

Here is a basic AutoIt script that will output a simple onscreen message showing the type, bus and SSD status of a given drive letter.  Remember to download AutoIt to run it.

; Some constants
Const $DT_DRIVETYPE = 1
Const $DT_SSDSTATUS = 2
Const $DT_BUSTYPE = 3
 
; Drive letter to check
Const $DriveLetter = "C:"
 
; Get drive type and verify it exists
$type = DriveGetType($DriveLetter, $DT_DRIVETYPE)
If @error Then
    MsgBox(4096, "Error", "Invalid drive requested")
    Exit
EndIf
 
; Get SSD status (blank return is non-SSD)
$ssd = DriveGetType($DriveLetter, $DT_SSDSTATUS)
If $ssd = "" Then $ssd = "Non SSD"
 
; Get Bus type
$bus = DriveGetType($DriveLetter, $DT_BUSTYPE)
 
; Create output message
$output = "Type: " & $type & @CRLF
$output &= "SSD: " & $ssd & @CRLF
$output &= "Bus: " & $bus
MsgBox(4096, "Drive Info", $output)
; Some constants
Const $DT_DRIVETYPE = 1
Const $DT_SSDSTATUS = 2
Const $DT_BUSTYPE = 3

; Drive letter to check
Const $DriveLetter = "C:"

; Get drive type and verify it exists
$type = DriveGetType($DriveLetter, $DT_DRIVETYPE)
If @error Then
	MsgBox(4096, "Error", "Invalid drive requested")
	Exit
EndIf

; Get SSD status (blank return is non-SSD)
$ssd = DriveGetType($DriveLetter, $DT_SSDSTATUS)
If $ssd = "" Then $ssd = "Non SSD"

; Get Bus type
$bus = DriveGetType($DriveLetter, $DT_BUSTYPE)

; Create output message
$output = "Type: " & $type & @CRLF
$output &= "SSD: " & $ssd & @CRLF
$output &= "Bus: " & $bus
MsgBox(4096, "Drive Info", $output)

The above script will just output a message with some info – which is great for testing the functionality. However, here is how you take take that script and turn it into something useful in a scripting environment or from a ConfigMgr or MDT Task Sequence.

Using AutoIt compile the following script as IsSSD.exe.

; Some constants
Const $DT_DRIVETYPE = 1
Const $DT_SSDSTATUS = 2
Const $DT_BUSTYPE = 3
 
; Check command line params
If $CmdLine[0] <> 1 Then
    MsgBox(4096, "Usage", "Usage:" & @CRLF & "IsSSD.exe ")
    Exit
EndIf
 
; Drive letter to check is the first parameter
$DriveLetter = $CmdLine[1]
 
; Get SSD info
$ssd = DriveGetType($DriveLetter, $DT_SSDSTATUS)
 
; Return 1 if it is an SSD, otherwise 0
If $ssd = "SSD" Then
    Exit 1
Else
    Exit 0
EndIf
; Some constants
Const $DT_DRIVETYPE = 1
Const $DT_SSDSTATUS = 2
Const $DT_BUSTYPE = 3

; Check command line params
If $CmdLine[0] <> 1 Then
	MsgBox(4096, "Usage", "Usage:" & @CRLF & "IsSSD.exe ")
	Exit
EndIf

; Drive letter to check is the first parameter
$DriveLetter = $CmdLine[1]

; Get SSD info
$ssd = DriveGetType($DriveLetter, $DT_SSDSTATUS)

; Return 1 if it is an SSD, otherwise 0
If $ssd = "SSD" Then
	Exit 1
Else
	Exit 0
EndIf

When compiled, the above script can be run along with the required drive letter as follows:

IsSSD.exe C:
IsSSD.exe C:

It will return 1 if the specified drive was SSD, or 0 if it is not SSD or it cannot be determined. This return value can be accessed using the standard ERRORLEVEL variable from a batch file or used by a Task Sequence in ConfigMgr or MDT.

If you don’t want to compile the script, you could run it directly with the AutoIt3.exe interpreter as well:

AutoIt3.exe IsSSD.au3 C:
AutoIt3.exe IsSSD.au3 C:

I’ve created a .zip file with these scripts and the final IsSSD.exe file which can be downloaded here: IsSSD.zip.

 

FacebooktwitterredditlinkedinmailFacebooktwitterredditlinkedinmail