Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for gethddstatus.ps

(view source code of gethddstatus.ps as plain text)

  1. param(
  2. 	[parameter( ValueFromRemainingArguments = $true )]
  3. 	[string[]]$Args # Leave all argument validation to the script, not to PowerShell
  4. )
  5.  
  6. Clear-Host
  7. Write-Host
  8.  
  9. if ( $args.Length -gt 0 ) {
  10. 	Write-Host "GetHDDStatus.ps1,  Version 2.01"
  11. 	Write-Host "Get the SMART status for all local harddisks"
  12. 	Write-Host
  13. 	Write-Host "Usage:    " -NoNewline
  14. 	Write-Host "powershell  ./GetHDDStatus.ps1" -ForegroundColor White
  15. 	Write-Host
  16. 	Write-Host "Notes:    This script requires elevated privileges."
  17. 	Write-Host "          In Linux, the output does not include disk indexes."
  18. 	Write-Host "          The result is shown in the console and in a desktop notification."
  19. 	Write-Host
  20. 	Write-Host "Credits:  Windows disk check based on code by Geoff @ UVM:"
  21. 	Write-Host "          www.uvm.edu/~gcd/2013/01/which-disk-is-that-volume-on" -ForegroundColor DarkGray
  22. 	Write-Host "          System Tray ToolTip Balloon code by Don Jones:"
  23. 	Write-Host "          http://blog.sapien.com/current/2007/4/27" -ForegroundColor DarkGray
  24. 	Write-Host "          /creating-a-balloon-tip-notification-in-powershell.html" -ForegroundColor DarkGray
  25. 	Write-Host
  26. 	Write-Host "Written by Rob van der Woude"
  27. 	Write-Host "http://www.robvanderwoude.com"
  28. 	Write-Host
  29.  
  30. 	exit 1
  31. }
  32.  
  33. $rc = 0
  34.  
  35. if ( $HOME[0] -eq '/' ) {
  36. 	# Linux: lshw/smartctl/df/notify-send commands
  37.  
  38. 	$notify = @( )
  39.  
  40. 	Write-Host "Volume   `tStatus`tCapacity`tModel" -ForegroundColor White
  41. 	Write-Host "======   `t======`t========`t=====`n" -ForegroundColor White
  42.  
  43. 	( . lshw -short -class disk ) -match "/dev/" | ForEach-Object {
  44. 		$disk = ( $_.trim( ) -split '\s+',  3 )[1]
  45. 		$name = ( $_.trim( ) -split 'disk', 2 )[1].trim( )
  46. 		if ( $disk -notmatch "(/cd|/dvd|/sr)" ) {
  47. 			try {
  48. 				$size = 0
  49. 				$size = ( ( ( . df -l --output=source,size ) -match $disk ) -split '\s+', 2 )[1] / 1MB
  50. 				if ( $size -gt 0 ) {
  51. 					$test = ( ( ( . smartctl -H $disk ) -match "SMART [^\n\r]+: ([A-Z]+)" ) -split ":" )[1].trim( )
  52. 					Write-Host "$disk`t" -ForegroundColor White -NoNewline
  53. 					if ( $test -eq "PASSED" ) {
  54. 							$fgc = "Green"
  55. 					} else {
  56. 						$fgc = "Red"
  57. 						$rc = 1
  58. 						$notify += $disk
  59. 					}
  60. 					Write-Host "$test`t" -ForegroundColor $fgc -NoNewline
  61. 					Write-Host ( "{0,5:N0} GB`t$name" -f $size ) -ForegroundColor White
  62. 				}
  63. 			}
  64. 			catch {
  65. 				# ignore errors from USB sticks etc.
  66. 			}
  67. 		}
  68. 	}
  69.  
  70. 	# desktop notification
  71. 	if ( $rc -eq 1 ) {
  72. 		$icon = "error"
  73. 		$urgency = "critical"
  74. 		$message = "Please check disk(s) " + ( $notify -join " " )
  75. 	} else {
  76. 		$icon = "info"
  77. 		$urgency = "normal"
  78. 		$message = "Disk(s) OK"
  79. 	}
  80. 	. notify-send -i $icon -u $urgency $message
  81. } else {
  82. 	# Windows: WMI and System.windows.Forms.NotifyIcon
  83.  
  84. 	# based on code by Geoff @ UVM
  85. 	# https://www.uvm.edu/~gcd/2013/01/which-disk-is-that-volume-on/
  86.  
  87. 	[Reflection.Assembly]::LoadWithPartialName( "System.Windows.Forms" ) > $null 2>&1
  88. 	[Reflection.Assembly]::LoadWithPartialName( "System.Drawing" ) > $null 2>&1
  89. 	Add-Type -AssemblyName System.Windows.Forms
  90.  
  91. 	[System.Collections.SortedList]$volumedetails = New-Object System.Collections.SortedList
  92. 	[System.Collections.SortedList]$volumestatus  = New-Object System.Collections.SortedList
  93.  
  94. 	# query status for all local disk drives
  95. 	$diskdrives = Get-WmiObject -Namespace "root/CIMV2" -Class Win32_DiskDrive
  96. 	foreach ( $disk in $diskdrives ) {
  97. 		$diskindex  = $disk.Index
  98. 		$diskmodel  = $disk.Model
  99. 		$disksize   = "{0,5:F0} GB" -f ( $disk.Size / 1GB )
  100. 		$diskstatus = $disk.Status
  101. 		$part_query = 'ASSOCIATORS OF {Win32_DiskDrive.DeviceID="' + $disk.DeviceID.replace('\','\\') + '"} WHERE AssocClass=Win32_DiskDriveToDiskPartition'
  102. 		$partitions = @( Get-WmiObject -Query $part_query | Sort-Object StartingOffset )
  103. 		foreach ( $partition in $partitions ) {
  104. 			$vol_query = 'ASSOCIATORS OF {Win32_DiskPartition.DeviceID="' + $partition.DeviceID + '"} WHERE AssocClass=Win32_LogicalDiskToPartition'
  105. 			$volumes   = @( Get-WmiObject -Query $vol_query )
  106. 			foreach ( $volume in $volumes ) {
  107. 				# DriveType 3 means harddisks only
  108. 				# 0 = Unknown; 1 = No Root Directory; 2 = Removable Disk; 3 = Local Disk; 4 = Network Drive; 5 = Compact Disc; 6 = RAM Disk
  109. 				if ( $volume.DriveType -eq 3 ) {
  110. 					if ( -not $volumedetails.Contains( $volume.Name ) ) {
  111. 						$volumedetails.Add( $volume.Name, "[Disk $diskindex]  $disksize  $diskmodel" )
  112. 						$volumestatus.Add( $volume.Name, $diskstatus )
  113. 					}
  114. 				}
  115. 			}
  116. 		}
  117. 	}
  118.  
  119. 	# console output table header
  120. 	Write-Host "Volume  Status  Disk#     Capacity  Model" -ForegroundColor White
  121. 	Write-Host "======  ======  =====     ========  =====`n" -ForegroundColor White
  122.  
  123. 	# write table console output
  124. 	$volumedetails.Keys | ForEach-Object {
  125. 		$fgc = "Green"
  126. 		$status = ( $volumestatus[$_] )
  127. 		if ( $status -ne "OK" ) {
  128. 			$fgc = "Red"
  129. 			$rc  = 1
  130. 		}
  131. 		Write-Host ( "$_      " ) -ForegroundColor White -NoNewline
  132. 		Write-Host ( "$status      ".Substring( 0, 6 ) + "  " ) -ForegroundColor $fgc -NoNewline
  133. 		Write-Host ( $volumedetails[$_] ) -ForegroundColor White
  134. 	}
  135.  
  136. 	# system tray balloon tip output
  137. 	[System.Windows.Forms.ToolTipIcon]$icon = [System.Windows.Forms.ToolTipIcon]::Info
  138. 	$title = "HDD Status OK"
  139. 	$systraymessage = ""
  140. 	$volumedetails.Keys | ForEach-Object {
  141. 		$status = ( $volumestatus[$_] )
  142. 		if ( $status -ne "OK" ) {
  143. 			$icon = [System.Windows.Forms.ToolTipIcon]::Error
  144. 			$title = "Warning: HDD Errors"
  145. 		}
  146. 		$systraymessage = $systraymessage + "$_`t$status`n"
  147. 	}
  148.  
  149. 	# Extract system tray icon from Shell32.dll
  150. 	# C# code to extract icons from Shell32.dll by Thomas Levesque
  151. 	# http://stackoverflow.com/questions/6873026
  152. 	$signature = @'
  153. 	[DllImport( "Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall )]
  154. 	private static extern int ExtractIconEx( string sFile, int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int amountIcons );
  155.  
  156. 	public static Icon Extract( string file, int number, bool largeIcon )
  157. 	{
  158. 		IntPtr large;
  159. 		IntPtr small;
  160. 		ExtractIconEx( file, number, out large, out small, 1 );
  161. 		try
  162. 		{
  163. 			return Icon.FromHandle( largeIcon ? large : small );
  164. 		}
  165. 		catch
  166. 		{
  167. 			return null;
  168. 		}
  169. 	}
  170. '@
  171.  
  172. 	$iconextractor = Add-Type -MemberDefinition $signature -Name IconExtract -Namespace IconExtractor -ReferencedAssemblies System.Windows.Forms,System.Drawing -UsingNamespace System.Windows.Forms,System.Drawing -PassThru
  173.  
  174. 	# icon depends on status
  175. 	if( $title -eq "HDD Status OK" ) {
  176. 		$systrayicon = $iconextractor::Extract( "C:\Windows\System32\shell32.dll", 223, $true )
  177. 	} else {
  178. 		$systrayicon = $iconextractor::Extract( "C:\Windows\System32\shell32.dll", 53, $true )
  179. 	}
  180.  
  181. 	# show system tray icon and balloon tip
  182. 	$notify = New-Object System.windows.Forms.NotifyIcon
  183. 	$notify.BalloonTipText = $systraymessage
  184. 	$notify.BalloonTipTitle = $title
  185. 	$notify.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]$icon
  186. 	$notify.Icon = $systrayicon
  187. 	$notify.Visible = $true
  188. 	$notify.ShowBalloonTip( 30000 )
  189. }
  190.  
  191. Write-Host
  192.  
  193. exit $rc
  194.  

page last uploaded: 2019-01-21, 22:48