Marco Burmeister

  private Homepage



S.M.A.R.T. Fehler-Status für Festplatten automatisiert bei Windows oder Linux anzeigen (SMART)



Da ich letztens wieder einmal den Fall hatte, dass bei meinem alten Rechner eine Festplatte ausgefallen ist, ohne dass ich davon vorher eine Vorwarnung wahrgenommen habe, habe ich mich entschlossen, automatisiert festzustellen, wie der Status eine Festplatte ist.
Mein Problem bei meiner anschließenden Recherche war, dass ich kein Programm gefunden habe, welches mich automatisiert bei einer Anmeldung warnt.
Ich wollte nicht interaktiv abfragen. Das funktioniert natürlich, aber als Nutzer muss ich auch daran denken.
Im Ergebnis habe ich mich dann ein wenig mit dem S.M.A.R.T. System beschäftigt (Wikipedia: Self-Monitoring, Analysis and Reporting Technology).

Die Seite ist in die folgenden Bereiche eingeteilt:

Hinweis:
Die Nutzung der hier geschilderten Anleitung geschieht auf eigene Gefahr!




top Erklärung

Bei der Recherche zum Auslesen der S.M.A.R.T. - Werte von Festplatten (SSD und HDD) habe ich kein Tool gefunden, welches mir gleich nach der Anmeldung eine Info ausgibt, wie der Zustand der Festplatte ist.
Deshalb habe ich dann recherchiert, wie ich mit Powershell für Windows und Linux bash-Befehlen für Linux an die notwendigen Informationen komme, um sie dann anzuzeigen.
Im Ergebnis habe ich nun für Windows und Linux Scripte erstellt, die mir nach der Anmeldung die Information ohne eigenes Zutun anzeigt.

top Windows

Voraussetzungen

Die Scripte wurden unter Windows 10 Professional entwickelt.
Ich arbeite mit unterschiedlichen OS Nutzern. Für die tägliche Arbeit benutze ich einen Benutzer aus der Gruppe Hauptbenutzer bzw. Benutzer und für Administrationsarbeiten mit einem OS Nutzer, der in der Gruppe der Administratoren zugeordnet ist.

Für die Scripte werden die Verzeichnisse
c:\Scripts\SMART_check
und
c:\Scripts\SMART_check\log
benötigt. Die müssen von Hand angelegt werden.

Umsetzung

Die Problematik im Windows-Umfeld für mich war, dass ich die S.M.A.R.T.-Werte nur mit Berechtigungen eines Benutzers aus der Administratorengruppe erhalten kann, aber selbst selten mit einem solchen Benutzer arbeite.

Herausgekommen ist damit eine Script-Sammlung, die es ermöglicht manuell die Auswertung zu starten. Außerdem wird im Unterverzeichnis log dann immer vom letzten Lauf das Ergebnis abgelegt.

Es wird nach Anmeldung des normalen Benutzers oder des Benutzers auf der Administratorengruppe zeitversetzt das Script gestartet. Wird ein Problem gefunden, so wird in den Windows Benachrichtigungen eine entsprechende Information angezeigt.

Scripte

Die Scripte liegen alle im Verzeichnis c:\Scripts\SMART_check. Die .bat Scripte dienen nur dazu, dass die Scripte auch auf Systemen ausgeführt werden müssen, die das Ausführen von Powershell Scripten verhindern / untersagen.

Script SMART_check_disks.bat

Das Script SMART_check_disks.bat ist nur ein Hilfsscript, damit das Powershell-Script ausgeführt werden kan.

  1. @echo off
  2. @REM
  3. @REM - ausfuehren als Administrator!
  4. @REM
  5. powershell -ExecutionPolicy RemoteSigned -File c:\Scripts\SMART_check\SMART_check_disks.ps1


Script SMART_just_read_and_send_message.bat

Das Script SMART_just_read_and_send_message.bat ist nur ein Hilfsscript, damit das Powershell-Script ausgeführt werden kan.

  1. @echo off
  2. @REM
  3. @REM - ausfuehren als Benutzer!
  4. @REM
  5. powershell -ExecutionPolicy RemoteSigned -File c:\Scripts\SMART_check\SMART_just_read_and_send_message.ps1


Script SMART_check_disks.ps1

Das Powershell-Script SMART_check_disks.ps1 macht die Auswertung des Diskstatus mittels Powershell und schreibt die Log-Datei.
Das Script kann für einen Benutzer aus der Gruppe der Administratoren auch gleich die Ergebnisse der Auswertung an das Benachrichtigungssystem von Windows schicken. Normale Benutzer benötigen das nachfolgende Script.

  1. #
  2. # PowerShell Script - Check S.M.A.R.T
  3. # (PS-Script als User Administrator ausfuehren!)
  4. #
  5. # Variablen
  6. # Wert
  7. $wert = ""
  8. # Diskname
  9. $diskall = ""
  10. $diskname = ""
  11. # Ausgabe
  12. $ausgabe = ""
  13. # WShell
  14. $wshell = ""
  15. # Flag erster Eintrag
  16. $flerst = 0
  17. # Konstante
  18. # Status S.M.A.R.T (TRUE / FALSE) - TRUE = Fehler
  19. $c_status = "True"
  20. # Verzeichnis Ausgabe
  21. $c_verz = "c:\Scripts\SMART_check\log"
  22. # Log-Ausgabe
  23. $c_logdat = $c_verz + "\smart_check.log"
  24. # Flag-File Fehler
  25. $c_errdat = $c_verz + "\smart_check.err"
  26. # Log-Ausgabe - alle Disks
  27. $c_logfulldat = $c_verz + "\smart_check_full_output.log"
  28. # Init
  29. # Directory anlegen
  30. new-item -itemtype directory -path $c_verz -Force | Out-Null
  31. # Init - Loeschen ERR-Flag-File
  32. if ( Test-Path -Path $c_errdat -PathType Leaf ) {
  33. Remove-item $c_errdat | Out-Null
  34. }
  35. # Init - Loeschen Log-File
  36. if ( Test-Path -Path $c_logdat -PathType Leaf ) {
  37. Remove-item $c_logdat | Out-Null
  38. }
  39. #
  40. # Verarbeitung 1
  41. #
  42. # Zaehlen Disks mit Fehler Status
  43. $wert=Get-CimInstance -namespace root\wmi -class MSStorageDriver_FailurePredictStatus | Select-Object PredictFailure | Select-String $c_status | Measure-Object
  44. # Anzeige Bildschirm
  45. if ( $wert.count -gt 0 ) {
  46. # Alle Disks
  47. $diskall=Get-CimInstance -namespace root\wmi -class MSStorageDriver_FailurePredictStatus |Select-Object InstanceName,PredictFailure | Where-Object { $_.PredictFailure -match $c_status } | Select-Object InstanceName
  48. # Anzeige
  49. foreach ($diskname in $diskall) {
  50. Add-Type -AssemblyName System.Windows.Forms
  51. $global:balloon = New-Object System.Windows.Forms.NotifyIcon
  52. $path = (Get-Process -id $pid).Path
  53. $balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
  54. $balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Warning
  55. $balloon.BalloonTipText = "S.M.A.R.T - Disk Failure near for disk '$diskname'"
  56. $balloon.BalloonTipTitle = "Attention $Env:USERNAME"
  57. $balloon.Visible = $true
  58. $balloon.ShowBalloonTip(5000)
  59. # Ausgabe als File
  60. if ( Test-Path -Path $c_verz ) {
  61. if ( $flerst -eq 0 ) {
  62. $flerst = 1
  63. Start-Transcript -Path $c_logdat -Append
  64. write-host "SMART - Problematic disks:"
  65. write-host "=========================="
  66. }
  67. # Ausgabe fehlerhafte Disks in Log-Datei
  68. write-host "S.M.A.R.T - Disk Failure near for disk '$diskname'"
  69. }
  70. }
  71. }
  72. #
  73. # Verarbeitung 2
  74. #
  75. # Zaehlen Disks mit Fehler Status
  76. $wert=Get-Disk | Select-Object Number | get-disk -number { $_.Number } | Select-Object "Healthstatus" | Select-String "Healthy" -NotMatch | Measure-Object
  77. # Anzeige Bildschirm
  78. if ( $wert.count -gt 0 ) {
  79. # Start
  80. if ( Test-Path -Path $c_verz ) {
  81. if ( $flerst -eq 0 ) {
  82. $flerst = 1
  83. Start-Transcript -Path $c_logdat -Append
  84. write-host "SMART - Problematic disks:"
  85. write-host "=========================="
  86. }
  87. }
  88. # Output Error-Message Indicator
  89. write-host "S.M.A.R.T - Disk Failure near for disk - see output of get-disk from log file"
  90. }
  91. # Ende und Errorflag
  92. if ( $flerst -eq 1) {
  93. # Ende Ausgabe
  94. Stop-Transcript | Out-Null
  95. # Error-Flag File
  96. write-output "S.M.A.R.T - Disk Failure detected on $(Get-Date -Format d.M.yyyy) $((Get-Date).ToShortTimeString())" | Out-File -FilePath $c_errdat
  97. }
  98. #
  99. # Alle Disks ausgeben - nur zur Dokumentation
  100. #
  101. Get-CimInstance -namespace root\wmi -class MSStorageDriver_FailurePredictStatus | Out-File -FilePath $c_logfulldat
  102. wmic diskdrive get caption,status,serialnumber,pnpdeviceid | Out-File -Append -FilePath $c_logfulldat
  103. Get-Disk | Get-StorageReliabilityCounter | Out-File -Append -FilePath $c_logfulldat
  104. Get-Disk | Select-Object Number | get-disk -number { $_.Number } | Format-Custom | Out-File -Append -FilePath $c_logfulldat

Update 10.04.2023:
Ich werte die Ausgabe von Get-Disk | Get-StorageReliabilityCounter in meinem Script nicht aus, da ich für meine SSD hier keine Werte erhalte und nur meine alte Festplatte (HDD) hier Werte anzeigt.

Script SMART_just_read_and_send_message.ps1

Das Powershell-Script SMART_just_read_and_send_message.ps1 schickt für den Benutzer, der nicht Teil der Gruppe der Administratoren ist, die Ergebnisse, die das Script mit Administratoren-Rechten ermittelt hat, an das Benachrichtigungssystem von Windows.

  1. #
  2. # PowerShell Script - Check S.M.A.R.T
  3. #
  4. # Scheduled Task
  5. # https://serverfault.com/questions/631995/program-does-not-run-properly-as-scheduled-task
  6. # Konstanten
  7. # Verzeichnis Ausgabe
  8. $c_verz = "C:\Scripts\SMART_Check\log"
  9. # Log-Ausgabe
  10. $c_logdat = $c_verz + "\smart_check.log"
  11. # Suchstring
  12. $c_suchstr = "S.M.A.R.T"
  13. # Verarbeitung
  14. if ( Test-Path -Path $c_logdat -PathType Leaf ) {
  15. write-host "Log-Datei '$c_logdat' gefunden."
  16. write-host "Schicke Meldungen an Windows Notification System"
  17. foreach($line in Get-Content $c_logdat) {
  18. if($line -match $c_suchstr){
  19. write-host "$line"
  20. Add-Type -AssemblyName System.Windows.Forms
  21. $global:balloon = New-Object System.Windows.Forms.NotifyIcon
  22. $path = (Get-Process -id $pid).Path
  23. $balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path)
  24. $balloon.BalloonTipIcon = [System.Windows.Forms.ToolTipIcon]::Warning
  25. $balloon.BalloonTipText = "$line'"
  26. $balloon.BalloonTipTitle = "Attention $Env:USERNAME"
  27. $balloon.Visible = $true
  28. $balloon.ShowBalloonTip(5000)
  29. }
  30. }
  31. } else {
  32. write-host "Keine Log-Datei '$c_logdat' gefunden."
  33. write-host "Keine problematischen Disks gefunden."
  34. }


Aufgabenplanung / Task Scheduler

Ich benötige hier 3 Jobs.

2 Jobs laufen nach der Anmeldung des normalen Benutzers, den ich immer für die Anmeldung benutze, damit diesem bei Problemen die Information geschickt werden kann. Der erste Job läuft dann unter den Rechten eines Administrators. Der zweite Job als der normale Benutzer. Die gehören beide dem normalen Benutzer.

Dann gibt es noch den dritten Job, der dem User aus der Gruppe der Administratoren gehört und auch unter diesem läuft.

Job 1 - Beispiel-Name: Check Health Status S.M.A.R.T

Besitzer: normaler Benutzer
Ausführung als User Admin


Der Job macht die Auswertung für den normalen Benutzer. Da die Auswertebefehl Administrator-Rechte benötigen, muss der Job als Administrator laufen. Der Job darf unabhängig von der Benutzeranmeldung des Administrators laufen.

Die Start-Bedingung: Nach Anmeldung <Anmeldenamen normaler Benutzer>
Auszuführender Befehl:
powershell -ExecutionPolicy RemoteSigned -File C:\Scripts\SMART_Check\SMART_check_disks.ps1

Job 2 - Beispiel-Name: Check Health Status S.M.A.R.T - Senden Meldung

Besitzer: normaler Benutzer
Ausführung als User Benutzer


Der Job macht die Auswertung für den normalen Benutzer.
Der Job läuft als normaler Benutzer.
Der Job soll nur ausgeführt werden, wenn der normale Benutzer sich anmeldet.

Die Start-Bedingung: Nach Anmeldung <Anmeldenamen normaler Benutzer>
Ergänzende Regel: 5 Minuten Ausführung verzögern (dammit Job1 fertig ist bevor dieser Job läuft)
Auszuführender Befehl:
powershell -WindowStyle hidden -ExecutionPolicy RemoteSigned -File C:\Scripts\SMART_Check\SMART_just_read_and_send_message.ps1

Job 3 - Beispiel-Name: Check Health Status S.M.A.R.T - Admin

Besitzer: Administrator
Ausführung als User Admin


Der Job macht die Auswertung für den Administrator. Der Job darf bei Anmeldung des Administrators laufen.

Die Start-Bedingung: Nach Anmeldung <Administrator>
Auszuführender Befehl:
powershell -WindowStyle hidden -ExecutionPolicy RemoteSigned -File C:\Scripts\SMART_Check\SMART_check_disks.ps1

top Linux

Voraussetzungen

Im Linux-Umfeld bin ich öfters als Administrator auf den Systemen unterwegs, weshalb ich hier nur dem Administrator anzeige, wie der Status der Festplatten ist.

Hierfür habe ich unterhalb von /root ein Script abgelegt.

Script

Beschreibung

Das Script ermitelt dynamisch, welche Festplatten es im System gibt und ermittelt dann deren Status.
Beim Finden von Fehlern werden für jede Festplatte die Ausgaben am Bildschirm ohne Umleitung in eine Log-Datei gemacht.

Eintragung in .profile oder .bashrc

In der Konfigurationsdatei .profile oder .bashrc kann das u.a. Script /root/smart_check.sh eingetragen werden werden, damit gleich nach der Anmeldung des root-Users der Status der Festplatten ausgegeben wird.

Script smart_check.sh

Code für das Script smart_check.sh.

  1. #!/bin/bash
  2. #
  3. # SMARTCTL Check Disk Status
  4. #
  5. # Variablen
  6. # Zaehlen Ausgabe smartctl
  7. v_cnt=0
  8. # Disks
  9. v_disk=""
  10. # flag Fehler gefunden
  11. fl_fehler=0
  12. # Konstanten
  13. # Pre-String Disk
  14. c_predisk="/dev/"
  15. # Einschraenkungsstring
  16. c_strgrep="overall-health"
  17. # String Suche Erfolg
  18. c_strok="PASSED"
  19. #
  20. # Verarbeitung
  21. #
  22. # Start
  23. echo "##############################################"
  24. echo "S.M.A.R.T. - Auswertung"
  25. echo "##############################################"
  26. # Analyse
  27. for v_disk in $( lsblk |grep disk | cut -d " " -f1)
  28. do
  29. v_cnt=$(smartctl -H ${c_predisk}${v_disk} | grep "${c_strgrep}" | grep "${c_strok}" | wc -l)
  30. if [ "${v_cnt}" -le 0 ];
  31. then
  32. # Fehler
  33. fl_fehler=1
  34. # Ausgabe
  35. echo "*************"
  36. echo "S.M.A.R.T. - Check fuer ${c_predisk}${v_disk}"
  37. echo "fehlgeschlagen."
  38. smartctl -H ${c_predisk}${v_disk}
  39. echo "*************"
  40. else
  41. echo "Disk ${c_predisk}${v_disk} ohne Befund."
  42. fi
  43. done
  44. # Ausgabe wenn kein Fehler und Ende
  45. if [ "${fl_fehler}" -eq 1 ];
  46. then
  47. echo "##############################################"
  48. exit 5
  49. else
  50. echo "Alles OK"
  51. echo "##############################################"
  52. exit 0
  53. fi

top Links zum Thema

Hinweis:
Für die Richtigkeit der Daten übernehme ich keine Gewähr!
Für den Inhalt von Internet-Seiten, auf die von dieser Seite verwiesen wird, übernehme ich keine Verantwortung!