Sign in to follow this  
Followers 0
Ascend4nt

Drive(s) Power Status

4 posts in this topic

#1 ·  Posted (edited)

For those of us with more than one hard drive, and with power management options enabled for disks, you might find yourself in the same situation as I've been in - asking the question 'Is that drive really powered down?'. I coded up the below example to get that information to you. Note that it reads power states for ALL drives, and the status information for removable & virtual drives will either show up as 'Unknown' or Powered-On.

As a courtesy, please be sure to credit me or keep the UDF header intact if you use the code :unsure:

; ===============================================================================================================================
; <DrivesPowerStatus.au3>
;
; Reports the Power status for all drives.
;
; Functions:
;   _DriveGetPowerState()   ; Returns a boolean indicating drive status (True=active, False=low power or powered-off)
;
; Author: Ascend4nt
; ===============================================================================================================================
#include <Array.au3>
 
Local $aDrives,$aDevInfo
 
$aDrives=DriveGetDrive("ALL")   ; returns array of 'drive:' with lower-case letters
If @error Then Exit
 
; Create 2D array - 2nd column will carry the Power State info, 3rd Drive Type
Dim $aDriveStates[$aDrives[0]+1][3]
 
; Copy over drives and get Power States
For $i=1 To $aDrives[0]
    $aDriveStates[$i][0]=StringUpper($aDrives[$i])
    $aDriveStates[$i][1]=_DriveGetPowerState($aDrives[$i])
    If @error Then $aDriveStates[$i][1]="Unknown"
    $aDriveStates[$i][2]=DriveGetType($aDrives[$i])
Next
$aDriveStates[0][0]="Drive"
$aDriveStates[0][1]="Active Power State?"
$aDriveStates[0][2]="Drive Type"
_ArrayDisplay($aDriveStates,"Drives Power Status")
 
 
; ===================================================================================================================
; Func _DriveGetPowerState($sDrive)
;
; Returns a boolean representing the active power state of the given drive.
;   True = Active (powered on, active), False = Inactive (either powered off, or in a low power state)
;
; $sDrive = Drive letter, or full path (only the Drive letter is extracted from the string)
;
; Returns:
;   Success: True/False
;   Failure: -1, with @error set:
;       @error = 1 = invalid parameter
;       @error = 2 = DLLCall error. @extended contains DLLCall error code (see AutoIt Help)
;       @error = 3 = API call error. Call 'GetLastError' for more info
;
; Author: Ascend4nt
; ===================================================================================================================
 
Func _DriveGetPowerState($sDrive)
    $sDrive=StringLeft($sDrive,1)
    If StringIsAlpha($sDrive)=0 Then Return SetError(1,0,-1)
    ; Device path for logical drives: '\\.\C:'
    Local $iErr,$aRet,$hDisk,$sDevicePath='\\.\'&$sDrive&':'
#cs
    ; API call params: [0 Access (for metadata & device info),3 ShareMode for 'Read'+'Write',
    ;   0 (NULL) SecurityAttribs (i.e. none),3 CreationDisposition for 'OpenExisting',0 Flags,0 (NULL) TemplateFile]
    ; *We could also use _WinAPI_CreateFile($sDevicePath,2,8,6), but there's no guarantee that '8' as the 3rd param
    ;   will continue to work (its currently a sort of 'hack' to work around the limitations of the UDF [to force AccessMode to 0])
#ce
    $aRet=DllCall('kernel32.dll','handle','CreateFileW','wstr',$sDevicePath,'dword',0,'dword',3,'ptr',0,'dword',3,'dword',0,'ptr',0)
    If @error Then Return SetError(2,@error,-1)
    If $aRet[0]=-1 Then Return SetError(3,0,-1)
    $hDisk=$aRet[0]
;~  ConsoleWrite("Handle for Drive '"&$sDrive&":' = "&$hDisk&@CRLF)
    $aRet=DllCall('kernel32.dll','bool','GetDevicePowerState','handle',$hDisk,'bool*',0)
    $iErr=@error
    ; We don't worry about whether this is successful, since there's nothing we can do about it:
    DllCall('kernel32.dll','bool','CloseHandle','handle',$hDisk)
    ; Error with GetDevicePowerState call?
    If $iErr Then Return SetError(2,$iErr,-1)
    If Not $aRet[0] Then Return SetError(3,0,-1)
;~  ConsoleWrite("$aRet[2]="&$aRet[2]&@CRLF)
    Return ($aRet[2]<>0)
EndFunc
Edited by Ascend4nt

Share this post


Link to post
Share on other sites



Cool script :unsure:

[0]|Drive|Active Power State?|Drive Type

[1]|A:|True|Removable

[2]|C:|True|Fixed

[3]|D:|True|Fixed

[4]|E:|True|Fixed

[5]|F:|True|Fixed

[6]|G:|True|Fixed

[7]|H:|True|Fixed

[8]|I:|True|CDROM

[9]|J:|True|Removable

[10]|K:|True|Removable

[11]|L:|True|Removable

[12]|M:|True|Removable

[13]|O:|True|CDROM

[14]|Q:|True|CDROM

Also, I'm gonna run out of letters soon :>

Share this post


Link to post
Share on other sites

Agreed nice Function.


_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

Thx guys. I noticed an issue with a 4-bay external enclosure where it reports 'False' for active power state, no matter if the drives in the enclosure were powered up or down.. perhaps its just not possible to detect power states in those situations. (I've noticed S.M.A.R.T. info is unavailable through USB also)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • Synapsee
      By Synapsee
      ;RemoteDriveInfo ;v0.0.0.1 ;Ressource ;Smart Temp : https://www.autoitscript.com/forum/topic/91067-drive-temperature/?do=findComment&comment=1091961 ;GetPNPDeviceID From DriveLetter : https://www.autoitscript.com/forum/topic/57202-need-help-get-pnp-device-id-for-usb-drive/?do=findComment&comment=433346 ;Get Disk Space Info : https://www.autoitscript.com/forum/topic/148390-wmi-query-how-to-get-data-from-object/?do=findComment&comment=1055088 ;For A to Z : https://www.autoitscript.com/forum/topic/4804-fornext-loop-with-letters/?do=findComment&comment=30417 ;Include #include <Array.au3> #include <String.au3> ;Sample 1 ;$sComputerName $sComputerName = "PC1" ;$sComputerName = "PC2" ;$sComputerName = @ComputerName ;$sDrive ;$sDrive = "system" ;$sDrive = "D:" $sDrive = "" $DriveInfo = _GetDriveInfo($sComputerName, $sDrive) _ArrayDisplay($DriveInfo) ;Sample 2 $DriveInfo = _GetDriveInfo($sComputerName, "system") If $DriveInfo[0][0] = "DriveLeter" Then If $DriveInfo[1][6] <> "" Then MsgBox(0, "", $DriveInfo[1][6] & "° - " & $DriveInfo[1][4] & "% ( " & Round($DriveInfo[1][2]/1024^3) & "Go / " & Round($DriveInfo[1][3]/1024^3) & "Go )" & @CRLF) Else MsgBox(0, "", $DriveInfo[1][4] & "% ( " & Round($DriveInfo[1][2]/1024^3) & "Go / " & Round($DriveInfo[1][3]/1024^3) & "Go )" & @CRLF) EndIf Else MsgBox(0, "", $DriveInfo[0][0] & @CRLF) EndIf ;Function Func _GetSystemDriveLtr($sComputerName) $objWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputerName & "\root\cimv2") $colTemp = $objWMI.ExecQuery("SELECT SystemDrive FROM Win32_OperatingSystem") If IsObj($colTemp) then For $objItem In $colTemp $sSystemDriveLtr = $objItem.systemdrive Next EndIf Return $sSystemDriveLtr EndFunc ;==> _GetSystemDriveLtr Func _GetPNPDeviceID($drive_letter, $sComputerName) Local $drive_letter_found, $drive_letter_found $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" $objWMIService = ObjGet("winmgmts:\\" & $sComputerName & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_LogicalDiskToPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $LogicalDiskToPartitionAntecedent = _StringBetween($objItem.Antecedent, '"', '"') $LogicalDiskToPartitionDependent = _StringBetween($objItem.Dependent, '"', '"') ;ConsoleWrite(@CR & $LogicalDiskToPartitionAntecedent[0] & " - " & $LogicalDiskToPartitionDependent[0]) $drive_statistics = $LogicalDiskToPartitionAntecedent[0] $drive_letter_found = $LogicalDiskToPartitionDependent[0] If $drive_letter = $drive_letter_found Then ExitLoop EndIf Next Else MsgBox(0, "WMI Output", "No WMI Objects Found for class: " & "Win32_LogicalDiskToPartition") EndIf If $drive_letter <> $drive_letter_found Then Return 0 ; If drive letter isn't function returns 0 $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDriveToDiskPartition", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $DiskDriveToDiskPartitionAntecedent = _StringBetween($objItem.Antecedent, '"', '"') $DiskDriveToDiskPartitionDependent = _StringBetween($objItem.Dependent, '"', '"') ;ConsoleWrite(@CR & $DiskDriveToDiskPartitionAntecedent[0] & " - " & $DiskDriveToDiskPartitionDependent[0]) $drive_statistics_found = $DiskDriveToDiskPartitionDependent[0] $drive_physical = StringTrimLeft($DiskDriveToDiskPartitionAntecedent[0], StringInStr($DiskDriveToDiskPartitionAntecedent[0], "\", 1, -1)) ;MsgBox(0,"TEST", $drive_physical) If $drive_statistics = $drive_statistics_found Then ExitLoop EndIf Next Else MsgBox(0, "WMI Output", "No WMI Objects Found for class: " & "Win32_DiskDriveToDiskPartition") EndIf $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems ;MsgBox(0,324234, $objItem.DeviceID) $DeviceID = StringTrimLeft($objItem.DeviceID, StringInStr($objItem.DeviceID, "\", 1, -1)) $PNPDeviceID = $objItem.PNPDeviceID ;MsgBox(0,122, $DeviceID) If $drive_physical = $DeviceID Then Return $PNPDeviceID EndIf Next Else MsgBox(0, "WMI Output", "No WMI Objects Found for class: " & "Win32_DiskDrive") EndIf EndFunc ;==> _GetPNPDeviceID Func _GetSmartTemp($InstanceName, $sComputerName) $objWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputerName & "\root\WMI") $colTemp = $objWMI.ExecQuery("SELECT * FROM MSStorageDriver_ATAPISmartData") $s = "" If IsObj($colTemp) and $InstanceName <> "" then For $objItem In $colTemp If StringInStr(StringUpper($objItem.InstanceName), StringUpper($InstanceName)) <> 0 Then $strVendorSpecific = $objItem.VendorSpecific For $i = 2 To UBound($strVendorSpecific) - 1 Step 12 If $strVendorSpecific[$i] = 0xC2 Then; find Vendor Parameter #194 - Temperatur $s &= " " & $strVendorSpecific[$i + 5]; Raw/Value celsuis ContinueLoop 2 EndIf Next For $i = 2 To UBound($strVendorSpecific) - 1 Step 12 If $strVendorSpecific[$i] = 0xBE Then; find Vendor Parameter #190 - Airflow Temperatur (if no tempetature is found) $s &= " " & $strVendorSpecific[$i + 5]; Raw/Value celsuis ContinueLoop 2 EndIf Next EndIf Next $s = StringTrimLeft($s, 1) Else $s = "" EndIf Return $s EndFunc ;==> _GetSmartTemp ;MainFunction Func _GetDriveInfo($sComputerName, $sDrive = "") Local $DriveArray[1][7] = [["DriveLeter", "FreespaceByte", "UsedspaceByte", "SizeByte", "UsedPercent", "IsSystem", "Temp"]] If Ping($sComputerName) = 0 Then Local $DriveArray[1][1] $DriveArray[0][0] = $sComputerName & " seems not online" Return $DriveArray EndIf If $sDrive = "" Then For $i = 65 To 90;For A to Z $sDriveLtr = Chr($i)&":" $DriveArray = _GetOneDriveInfo($sComputerName, $sDriveLtr, $DriveArray) Next ElseIf $sDrive = "system" Then $DriveArray = _GetOneDriveInfo($sComputerName, _GetSystemDriveLtr($sComputerName), $DriveArray) Else $DriveArray = _GetOneDriveInfo($sComputerName, $sDrive, $DriveArray) EndIf Return $DriveArray EndFunc ;==> _GetDriveInfo Func _GetOneDriveInfo($sComputerName, $sDriveLtr, $DriveArray) $objWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sComputerName & '\root\cimv2:Win32_LogicalDisk="' & $sDriveLtr & '"') If IsObj($objWMI) Then $UsedPercent = Round(100 / $objWMI.Size * ($objWMI.Size - $objWMI.FreeSpace)) If $UsedPercent <> -9223372036854775807 then $current_line = Ubound($DriveArray)+1 ReDim $DriveArray[$current_line][7] $DriveArray[$current_line-1][0] = $sDriveLtr $FreespaceByte = $objWMI.FreeSpace $DriveArray[$current_line-1][1] = $FreespaceByte $SizeByte = $objWMI.Size $DriveArray[$current_line-1][3] = $SizeByte $UsedspaceByte = $objWMI.Size - $objWMI.FreeSpace $DriveArray[$current_line-1][2] = $UsedspaceByte $UsedPercent = Round(100 / $objWMI.Size * ($objWMI.Size - $objWMI.FreeSpace)) $DriveArray[$current_line-1][4] = $UsedPercent If _GetSystemDriveLtr($sComputerName) = $sDriveLtr Then $IsSystem = 1 Else $IsSystem = 0 EndIf $DriveArray[$current_line-1][5] = $IsSystem $InstanceName = _GetPNPDeviceID($sDriveLtr, $sComputerName) $Temp = _GetSmartTemp($InstanceName, $sComputerName) $DriveArray[$current_line-1][6] = $Temp EndIf EndIf Return $DriveArray EndFunc  
      Ressource

      Smart Temp :
      GetPNPDeviceID From DriveLetter :
      Get Disk Space Info :
      For A to Z :
       
    • Wicked_Caty
      By Wicked_Caty
      I've written a small surveillance tool for one of my programs. It shows the time that has already passed, the estimated time until the end, the average time of the steps, and the progress in %.
      It works pretty well, but I want to add some stats. That'd be the usages of the CPU, RAM, network and hard-drive of all threads in %. Basically what you see in the taskmanager, but without the list of every single process.
      I'm aware that there's no in-built function for that, and that I'd need an additional library. Are there any for that? Simply functions that return the stats mentioned above. Thanks!
      Edit:   I run an ASUS R752M with an Intel BayTrail M3540 on Windows 10 64-bits.
    • Danyfirex
      By Danyfirex
      Well Another Function. For Get de Drive  letter marked as write enabled.
      Global Const $sCLSID_CDBurn = "{fbeb8a05-beee-4442-804e-409d6c4515e9}" Global Const $sIID_ICDBurn = "{3d73a659-e5d0-4d42-afc0-5121ba425c8d}" Global Const $sTagCDBurn = "GetRecorderDriveLetter hresult(wstr;uint); Burn hresult(hwnd); HasRecordableDrive hresult(bool*)" MsgBox(0, "", _GetRecorderDriveLetter()) Func _GetRecorderDriveLetter() Local $sDriveLetter = "" Local $HasRecordableDrive = False Local $oCDBurn = ObjCreateInterface($sCLSID_CDBurn, $sIID_ICDBurn, $sTagCDBurn) If Not IsObj($oCDBurn) Then Return $sDriveLetter If SUCCEEDED($oCDBurn.HasRecordableDrive($HasRecordableDrive)) Then $oCDBurn.GetRecorderDriveLetter($sDriveLetter, 4) EndIf Return $sDriveLetter EndFunc ;==>_GetRecorderDriveLetter Func SUCCEEDED($hr) Return ($hr >= 0) EndFunc ;==>SUCCEEDED  
    • sathish
      By sathish
      Hi Forum,
      I am just a beginner in AUTOIT,
      Just wanted to know, Is it possible to download a folder from my Google Drive automatically using AUTOIT,
      I googled to see some logic or guide to complete my task, but haven't succeded,
      Please guide me
      Thanks in Advance
      Sathish V.