Build precise queries to find exactly what you need
Press ESC to close
Nagios World Conference 2026: Sept. 14-17 in St. Paul, MN | Learn More
Windows vVersion 1.7.1 bellow, to respect paths on newer versions of HPE SSA:
#### # # NAME: check_smartarray.ps1 # # AUTHOR: Christophe Robert – christophe °dot° robert °at° cocoche °dot° fr # Daniel Beardsmore [DGB] – daniel °at° trustnetworks °dot° co °dot° uk # # DESC: Check HPSSACLI/HPACUCLI results for RAID status on Windows – hpssacli/hpacucli command line tool # # Script compatibility : Python 2+ # Return Values : # No problems – OK (exit code 0) # Drive status != OK but not “Failed” – WARNING (exit code 1) # Drive status is “Failed” – CRITICAL (exit code 2) # # TODO : Script errors – UNKNOWN (exit code 3) # # VERSION: # 1.0 – Initial dev. – 09-02-2012 (02 Sept. 2012) # 1.1 – Correcting some errors and add comments – 09-15-2013 (15 Sept. 2013) # * Add SAS array to be considerated (only SATA was before) # * Add comments # * Add UNKNOWN mark – script errors # 1.2 – Correcting some errors – 09-24-2013 (24 Sept. 2013) # * Add SCSI array to be considerated # * Add comments # 1.3 – Add multi controllers compatibility – 01-07-2015 (07 Jan. 2015) # 1.4 – Add controller, battery and cache status checks – 01-18-2015 (18 Jan. 2015) # 1.5 – Modify result analisys – 01-21-2015 (21 Jan. 2015) # 1.6 – Corrected exception collection in existing code # * Permits parameter “Blacklist” to blacklist controller status results # * Auto-detects the location of HPACUCLI/HPSSACLI # @ DGB 2016-04-22 # 1.7 – Cleaned up the output formatting, and removed duplication of results # * Drive predictive failure now raised to warning level (untested) # * Better compatibility with HPSSACLI (controller warnings were not being reported) # @ DGB 2016-09-19 # ####
param ( [string]$Blacklist = (‘Nothing’) )
Function Get-Storage-Executable-Path () { $programPaths = ( ‘C:Program FilesHPHPSSACLIbinhpssacli.exe’, ‘C:Program FilesHPHPACUCLIBinhpacucli.exe’, ‘C:Program FilesCompaqHPACUCLIBinhpacucli.exe’, ‘C:Program Files (x86)HPHPACUCLIBinhpacucli.exe’, ‘C:Program Files (x86)CompaqHPACUCLIBinhpacucli.exe’, ‘C:Program FilesSmart Storage Administratorssaclibinssacli.exe’, ‘C:Program Files (x86)Smart Storage Administratorssaclibinssacli.exe’ );
foreach ($path in $programPaths) { if (Test-Path $path) { return $path } }
return $false }
Function Should-Line-Be-Skipped ($line) { $line = $line.trim() $colonPos = $line.indexOf(“:”) if ($colonPos -eq -1) { return $false } $LHS = $line.trim().substring(0, $colonPos)
return $global:blacklistItems -contains $LHS }
Function Read-HPSmartArrayStatus ($buffer){ #creation de table de hash qui permet d’associer une clé et une valeur $system = @{“ctrl” = @() ; “array” = @() ; “logical” = @() ; “physical” = @()}
foreach ($line in $buffer) { $line = $line.trim() # Insert all controllers in dedicated list of dict if ($line -like “Smart Array*”) { #Write-Host “–Debug– Enter smart” #Write-Host “–Debug– Value = $line” $system.Item(“ctrl”) += $line #$system.Item(“ctrl”).add($line) #Write-Host “–Debug– Dict : $system” }
# Insert all arrays in dedicated list of dict elseif ($line -like “*array*SATA*” -Or $line -like “*array*SAS*” -Or $line -like “*array*SCSI*”) { #Write-Host “–Debug– Enter array” #Write-Host “–Debug– Value = $line” $system.Item(“array”) += $line #$system.Item(“array”).add($line) #Write-Host “–Debug– Dict : $system” }
# Insert all logicaldrives in dedicated list of dict elseif ($line -like “*logicaldrive*”) { #Write-Host “–Debug– Enter logical” #Write-Host “–Debug– Value = $line” $system.Item(“logical”) += $line #$system.Item(“logical”).add($line) #Write-Host “–Debug– Dict : $system” }
# Insert all physicaldives in dedicated list of dict elseif ($line -like “*physicaldrive*”) { #Write-Host “–Debug– Enter physical” #Write-Host “–Debug– Value = $line” $system.Item(“physical”) += $line #$system.Item(“physical”).add($line) #Write-Host “–Debug– Dict : $system” } }
#Write-Host “–Debug– Show ‘system’ dict content” #Write-Host “–Debug– Value = $system”
return $system }
Function Get-Errors ($buffer) { $errors = @{“CRITICAL” = @() ; “WARNING” = @() ; “UNKNOWN” = @()} $nb_ctrl = 0 $nb_array = 0 $nb_logical = 0 $nb_physical = 0
# For each controller found, check errors and find S/N foreach ($element in $buffer.Item(“ctrl”)) { #Write-Host “–Debug– Controller : $element” $nb_ctrl += 1
$slot = $element.split(” “)[5] #Write-Host “–Debug– Slot : $slot”
$ctrl_status = & $prg ctrl slot=$slot show status
$ctrl_status = $ctrl_status | Where-Object { $_ }
foreach ($line in $ctrl_status) { #Write-Host “–Debug– Controller internal status : $line”
if (Should-Line-Be-Skipped $line) { continue; }
if ($line -like “Smart*”) { $hw = $line.trim() } if ($line -like “*Status*”) { if ($line -notlike “*OK*”) { $status = $line.trim() $errors.Item(“WARNING”) += “$status in $hw” } } } }
# For each array found, check errors foreach ($element in $buffer.Item(“array”)) { #Write-Host “–Debug– Array : $element” $nb_array += 1 }
# For each logicaldrive found, check errors foreach ($element in $buffer.Item(“logical”)) { #Write-Host “–Debug– Logicaldrive : $element” $nb_logical += 1
if ($element -like “*OK*”) { #Write-Host $element continue } elseif ($element -like “*Failed*”) { #Write-Host $element $errors.Item(“CRITICAL”) += $element } elseif ($element -like “*Recover*”) { #Write-Host $element $errors.Item(“WARNING”) += $element } else { #Write-Host $element $errors.Item(“UNKNOWN”) += $element } }
# For each physical drive found, check errors foreach ($element in $buffer.Item(“physical”)) { #Write-Host “–Debug– Physicaldrive : $element” $nb_physical += 1
if ($element -like “*OK*”) { #Write-Host $element continue } elseif ($element -like “*Failed*”) { #Write-Host $element $errors.Item(“CRITICAL”) += $element } elseif ($element -like “*Rebuilding*” -or $element -like “*Predictive Failure*”) { #Write-Host $element $errors.Item(“WARNING”) += $element } else { #Write-Host $element $errors.Item(“UNKNOWN”) += $element } }
#Write-Host “–Debug– Errors dict : $errors” return $errors, $nb_ctrl, $nb_array, $nb_logical, $nb_physical }
### Core ###
$prg = Get-Storage-Executable-Path if ($prg -eq $false) { Write-Host “DOH! Cannot find ProLiant Array Configuration Utility or Smart Storage Administrator on this computer.” exit 3 }
$exec = & $prg ‘ctrl all show config’ #Write-Host $exec
$global:Warning = 0 $global:Critical = 0 $global:Unknown = 0 $global:ToSendList = @() $global:ToSendStr = “”
$global:blacklistItems = $Blacklist.split(“,”) 0..($global:blacklistItems.Length – 1) | % { $global:blacklistItems[$_] = $global:blacklistItems[$_].trim() }
try { # Execute Hp program with needed parameters and remove empty lines $res = $exec | Where-Object { $_ } #Write-Host $res
# Parse and analyse returned lines $nagios = Read-HPSmartArrayStatus $res #Write-Host $nagios
# Check errors $health, $nb_ctrl, $nb_array, $nb_logical, $nb_physical = Get-Errors $nagios
#Write-Host “–Debug– Health dict : $health”
if ($health.Item(“CRITICAL”).count -ne 0) { #Write-Host “–Debug– Enter critical” $global:Critical += 1 foreach ($elem in $health.Item(“CRITICAL”)) { $global:ToSendList += ‘CRITICAL – ‘ + $elem } } elseif (($health.Item(“WARNING”).count -ne 0) -and ($global:Critical -eq 0)) { #Write-Host “–Debug– Enter warning” $global:Warning += 1 foreach ($elem in $health.Item(“WARNING”)) { $global:ToSendList += ‘WARNING – ‘ + $elem } } elseif (($health.Item(“UNKNOWN”).count -ne 0) -and ($global:Critical -eq 0) -and ($global:Warning -eq 0)) { #Write-Host “–Debug– Enter unknown” $global:Unknown += 1 foreach ($elem in $health.Item(“UNKNOWN”)) { $global:ToSendList += ‘UNKNOWN – ‘ + $elem } } elseif (($nb_ctrl -eq 0) -and ($nb_array -eq 0) -and ($nb_logical -eq 0) -and ($nb_physical -eq 0)) { #Write-Host “–Debug– Enter unknown” $global:Unknown += 1 $global:ToSendList += ‘UNKNOWN – One of element of these : controller ($nb_ctrl), array ($nb_array), logicaldrive ($nb_logical) or physicaldrive ($nb_physical) is missing !’ } else { $global:ToSendList += “OK – RAID status is good – Nb Ctrl : $nb_ctrl – Nb Array : $nb_array – Nb logicaldrive : $nb_logical – Nb physicaldrive : $nb_physical” }
$global:ToSendStr = $global:ToSendList -join “; ” #Write-Host $global:ToSendStr } catch { $global:ToSendStr = $_.Exception.Message $global:Unknown += 1; } finally { Write-Host $global:ToSendStr
if ($global:Critical -ne 0) { exit 2 } elseif ($global:Warning -ne 0) { exit 1 } elseif ($global:Unknown -ne 0) { exit 3 } else { exit 0 } }