Skip to content

Instantly share code, notes, and snippets.

@dstreefkerk
Last active February 23, 2020 20:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dstreefkerk/10224178 to your computer and use it in GitHub Desktop.
Save dstreefkerk/10224178 to your computer and use it in GitHub Desktop.
#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