Hi there, sure I'm glad to. My code is probably more complicated than it needs to be to check a simple single database on a single server. My environment has typically five named instances per single server so I actually have to check up to five times per server and report back on all instances within a single sensor. Checking a single instance would not require code like this.
In addition, to make presentation more friendly, I make use of a lookup value which I'll include here also. It just makes reading the sensor visually a lot easier and is totally optional.
Param ([string]$HOSTNAME, [string]$INSTANCENAME)
#Create String Bulder Containers
$sb = New-Object System.Text.StringBuilder
$sw = New-Object System.IO.StringWriter($sb)
$XmlWriter = New-Object System.XMl.XmlTextWriter($sw)
#Set The Formatting
$xmlWriter.Formatting = "Indented"
$xmlWriter.Indentation = "4"
$XmlWriter.WriteStartElement('PRTG') # <-- Opening PRTG Root Node
#Add an XML Node for Each Client
#Query Versus SQL
$Blocking = 0
$X = Invoke-Sqlcmd 'sp_who' -ServerInstance "$HOSTNAME\$INSTANCENAME" | where {$_.blk -ne '0 '}
If ($X -ne $null) {$Blocking = 1}
# Write the XML
$xmlWriter.WriteStartElement('result')
$xmlWriter.WriteElementString("channel","$ClientCode Blocking")
$xmlWriter.WriteElementString("value",$Blocking)
$xmlWriter.WriteElementString("unit","Custom")
$xmlWriter.WriteElementString("showChart","1")
$xmlWriter.WriteElementString("showTable","1")
$xmlWriter.WriteElementString("ValueLookup","prtg.blockinglookup.yesno.statenook") # Here is the lookup I'll reference later
$xmlWriter.WriteEndElement() # <-- Closing result
# Write Close Tag for Root Element
$xmlWriter.WriteEndElement() # <-- Closing PRTG
# Finish The Document
$xmlWriter.Finalize
$xmlWriter.Flush()
$xmlWriter.Close()
#Echo the result back to PRTG
$sb.ToString()
My lookup table is pretty simple...
<?xml version="1.0" encoding="UTF-8"?>
<ValueLookup id="prtg.blockinglookup.yesno.statenook" desiredValue="0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd">
<Lookups>
<Boolean state="Ok" value="0">
No Blocking Detected
</Boolean>
<Boolean state="Error" value="1">
Blocking Detected
</Boolean>
</Lookups>
</ValueLookup>
Hope this helps, I know its more complex than necessary, but I've simplified it here by removing a for-loop I'm using to both enumerate a list of instances on a particular Host, then do the blocking check per-instance. The use of the XML nodes lets me create a sensor output including any number of instances.
I have noticed that this sensor can be a little resource intensive so I wouldn't schedule it too aggressively. Also, at least in my environment, I find that this comes back as "down" in some cases where the "sp_who" query is returning an actual "blocking" return which is completely transient and normal for the DB in question.
Kind Regards,
Adam
Add comment