Last active
February 23, 2020 20:30
-
-
Save dstreefkerk/10224178 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -version 3 | |
<# | |
.SYNOPSIS | |
Get-ProliantDiskDrives - Get HP ProLiant disk drive status for PRTG | |
.DESCRIPTION | |
Reads the status of HP ProLiant Smart Array disk drives via WMI and HP WBEM | |
http://www.hp.com/go/HPwbem | |
.OUTPUTS | |
XML formatted for a PRTG Advanced Script Sensor. | |
Numeric status per channel as per $statusDMTF and $statusHPExtended below | |
.LINK | |
http://daniel.streefkerkonline.com/monitoring-hp-proliant-via-powershell-wmi-drive-health/ | |
.NOTES | |
Written By: Daniel Streefkerk | |
Website: http://daniel.streefkerkonline.com | |
Twitter: http://twitter.com/dstreefkerk | |
Todo: Nothing at the moment | |
Change Log | |
https://gist.github.com/dstreefkerk/10224178 | |
#> | |
Param( | |
[Parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Name of the server to connect to')] | |
[String] | |
$ServerName | |
) | |
# Capitalise the server name, just for display purposes later | |
$ServerName = $($ServerName.ToUpper()) | |
$statusDMTF = @{ | |
'0' = 'Unknown' | |
'1' = 'Other' | |
'2' = 'OK' | |
'3' = 'Degraded' | |
'4' = 'Stressed' | |
'5' = 'Predictive Failure' | |
'6' = 'Error' | |
'7' = 'Non-Recoverable Error' | |
'8' = 'Starting' | |
'9' = 'Stopping' | |
'10' = 'Stopped' | |
'11' = 'In Service' | |
'12' = 'No Contact' | |
'13' = 'Lost Communication' | |
'14' = 'Aborted' | |
'15' = 'Dormant' | |
'16' = 'Supporting Entity in Error' | |
'17' = 'Completed' | |
'18' = 'Power Mode' | |
'19' = 'Relocating' | |
} | |
$statusHPExtended = @{ | |
'32768' = 'Queued for Secure Erase' | |
'32769' = 'Erase in Progress' | |
'32770' = 'Erase Completed' | |
'32771' = 'Physical Path In Error' | |
'32772' = 'Transient Data Drive' | |
'32773' = 'Rebuild' | |
'32774' = 'SSDWearOut' | |
'32775' = 'Not Authenticated' | |
} | |
# First, test that we can use WMI | |
$wmiErrorVariable = @() | |
try { | |
$computerSystem = Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_ComputerSystem -ComputerName $ServerName -ErrorAction Stop -WarningAction SilentlyContinue -ErrorVariable wmiErrorVariable | |
} | |
catch [System.UnauthorizedAccessException] { | |
$wmiError = $true | |
$wmiErrorMessage = "WMI Access to $ServerName is denied. Error: $($_.Exception.Message)" | |
} | |
catch [System.Runtime.InteropServices.COMException] { | |
$wmiError = $true | |
$wmiErrorMessage = "Couldn't query $ServerName via WMI. Error: $($_.Exception.Message)" | |
} | |
catch { | |
$wmiError = $true | |
$wmiErrorMessage = $_.Exception.Message | |
} | |
finally { | |
if ($wmiError -eq $true) { | |
"<prtg>" | |
"<error>1</error>" | |
"<text>$wmiErrorMessage $($_.Exception.Message)</text>" | |
"</prtg>" | |
Exit | |
} | |
} | |
# Get all disks via WMI | |
$disks = Get-WmiObject -Namespace ROOT\HPQ -Class HPSA_DiskDrive -ComputerName $ServerName -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -ErrorVariable wmiError | |
# If the ROOT\HPQ WMI query failed, throw an error. | |
if ($wmiError.Count -gt 0) { | |
"<prtg>" | |
"<error>1</error>" | |
"<text>The Insight WBEM Management Providers don't seem to be installed on $($ServerName.ToUpper()). Error: $($wmiError.Exception.Message)</text>" | |
"</prtg>" | |
Exit | |
} | |
$diskObjectCollection = @() | |
foreach ($disk in $disks) { | |
$thisDisk = New-Object psobject | |
# Display name for the channel | |
$diskName = "$($disk.ElementName) - $($disk.Description) Disk $($disk.Name)" | |
# Base operational status in textual form | |
$baseStatus = $disk.OperationalStatus[0] | |
# Extended operational status in textual form | |
$extendedStatus = $disk.OperationalStatus[1] | |
# Set some properties we'll use later | |
$thisDisk | Add-Member -MemberType "NoteProperty" -Name "Name" -Value $diskName | |
#Uncomment the below line, and comment out the line below it to get a textual representation of the status instead of a number | |
#$thisDisk | Add-Member -MemberType "NoteProperty" -Name "OperationalStatus" -Value $statusDMTF["$baseStatus"] | |
$thisDisk | Add-Member -MemberType "NoteProperty" -Name "OperationalStatus" -Value $baseStatus | |
#Uncomment the below line, and comment out the line below it to get a textual representation of the status instead of a number | |
#$thisDisk | Add-Member -MemberType "NoteProperty" -Name "ExtendedOperationalStatus" -Value $statusHPExtended["$extendedStatus"] | |
$thisDisk | Add-Member -MemberType "NoteProperty" -Name "ExtendedOperationalStatus" -Value "$extendedStatus" | |
# If the Operational Status of the disk isn't equal to 2 (OK), we'll be setting the whole PRTG sensor to error | |
if ($baseStatus -ne 2) { | |
$thisDisk | Add-Member -MemberType NoteProperty -Name "Error" -Value $true | |
$thisDisk | Add-Member -MemberType NoteProperty -Name "StateMessage" -Value "$diskName has the following operational status: $($statusDMTF["$baseStatus"])/$($statusHPExtended["$extendedStatus"])). " | |
} else { | |
$thisDisk | Add-Member -MemberType NoteProperty -Name "Error" -Value $false | |
$thisDisk | Add-Member -MemberType NoteProperty -Name "StateMessage" -Value $null | |
} | |
# Add this custom object to the collection | |
$diskObjectCollection += $thisDisk | |
} | |
# If you don't use PRTG, you could just un-comment the below line | |
#$diskObjectCollection | ft -AutoSize; exit; | |
"<prtg>" | |
foreach ($diskObject in $diskObjectCollection) { | |
"<result>" | |
"<channel>$($diskObject.name)</channel>" | |
# Display the status message in the channel | |
if ($diskObject.ExtendedOperationalStatus -gt 0) { | |
"<value>$($diskObject.OperationalStatus).$($diskObject.ExtendedOperationalStatus)</value>" | |
} else { | |
"<value>$($diskObject.OperationalStatus)</value>" | |
} | |
# Set the channel to warning status if there operational status isn't as it should be | |
if ($diskObject.Error -eq $true) { | |
"<warning>1</warning>" | |
} | |
"</result>" | |
} | |
# If any of the disks are in error, output their status to the sensor's message field. | |
if (($diskObjectCollection | where error -eq $true).count -gt 0) { | |
"<error>1</error>" | |
"<text>$($diskObjectCollection | where error -eq $true | % {$($_.StateMessage)})</text>" | |
} | |
"</prtg>" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment