Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # Originally from https://thwack.solarwinds.com/docs/DOC-188081
- # Posted on pastebin to get assistance with script breaking
- # ----------------------------------------------------------------------------
- # process_alert_reply_email.ps1
- #
- # Retrieve unread messages in a specified Exchange mailbox, then strip out
- # the Solarwinds alert definition ID, the object that triggered the alert,
- # and the object type (Solarwinds requires all three to handle an alert).
- #
- # This script assumes that the first word in the email message is a
- # command verb such as ack or comment. Any text between the command and a
- # return and/or newline character(s) is treated as a comment, and it will
- # be appended to the alert in Solarwinds.
- #
- # Message syntax
- # --------------
- # At minimum, the email message must contain these elements, formatted as
- # described below. These elements can appear anywhere in the message body.
- # Alert definition ID: A GUID in brackets, formatted like this:
- # [AlertDefinition=D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D]
- # Object ID: A string of digits, in brackets, formatted like this:
- # [ObjectID=99999]
- # Object Type: A string representing a valid Solarwinds object type, formatted
- # like this:
- # [ObjectType=APM: Application]
- #
- # Commands
- # --------
- # The command must be the first word in the message body.
- #
- # ack: Acknowledge the alert and append a comment if one is supplied.
- # comment: Append a comment to the alert
- #
- # Comments
- # --------
- # Comments are optional. Any text between the command verb and a newline or return
- # character will be treated as a comment. There are no formatting requirements
- # for comments.
- #
- # Example
- # -------
- # This message would acknowledge an alert and append a comment.
- #
- # Ack Kurt is looking into this
- # ~~~~~~~~~~~~~~~~~~~~~
- # Me, Senior Systems Administrator
- # ~~~~~~~~~~~~~~~~~~~~~~
- # From: Solarwinds
- # Sent: Friday, October 02, 2015 12:33 PM
- # To: Me <me@myemail.com>
- # Subject: Solarwinds Alert: Oracle database disk utilization KURTSDB on Node kurtsserver.mydomain.com is Down
- #
- # When replying, type your text above this line
- # ________________________________________
- #
- # To acknowledge this alert, click here or reply to this message with "ack" as the first word in the body.
- #
- # Alert details:
- # Oracle database disk utilization KURTSDB on Node kurtsserver.mydomain.com is Down at Friday, October 2, 2015 12:32 PM.
- #
- # When replying, do not delete text below
- # ________________________________________
- #
- # [AlertDefinition=535d1493-a543-4df0-acbf-6b43770aceeb] [ObjectID=1271][ObjectType=APM: Application]
- #
- # Example
- # -------
- # This message would also acknowledge an alert and append a comment
- #
- # Ack Third alert comment from ME
- # [AlertDefinition=535d1493-a543-4df0-acbf-6b43770aceeb] [ObjectID=673] [ObjectType=APM: Application]
- # ----------------------------------------------------------------------------
- #
- # Thanks
- # ------
- # Many thanks to everyone who shared code, answers, and insights online, for
- # you made this code possible.
- #
- # Load the Solarwinds snapin
- Add-PSSnapin SwisSnapin
- # Process-Message ($message)
- # $message: An object representing and Exchange email message
- function Process-Message ($message) {
- $subject = $message.Subject
- $fromName = $message.From.Name
- $fromAddress = $message.From.Address
- # MM We want to look for white spaces when finding the comment
- # Replace any whitespace in the message body with a single space
- #$body = $message.Body.Text -replace '\s+', ' '
- $body = $message.Body.Text
- # Search for a regular expression matching a string of word characters, digits, and dashes surrounded by "[AlertDefinition=]"
- # and retrieve the Alert Definition ID
- if ($body -match "\[AlertDefinition=([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})\]") {
- $alertDefID = $Matches[1]
- }
- else {
- throw [System.Exception] "Message must contain an Alert Definition ID like [AlertDefinition=D1A5279D-B27D-4CD4-A05E-EFDD53D08E8D]"
- exit 1
- }
- # Search for a regular expression matching a string of digits surrounded by "[ObjectID=]"
- # and retrieve the Object ID
- if ($body -match "\[ObjectID=([0-9]+)\]") {
- $objectID = $Matches[1]
- }
- else {
- throw [System.FormatException] "Message must contain an Object ID like [ObjectID=99999]"
- exit 1
- }
- # Search for a regular expression matching a string of word characters, spaces, periods, and colons) surrounded by "[ObjectType=]"
- # and retrieve the Object Type
- if ($body -match "\[ObjectType=([\d\w\s\.\:]+)\]") {
- $objectType = $Matches[1].Trim()
- }
- else {
- throw [System.FormatException] "Message must contain an Object Type like [ObjectID=APM Application]"
- exit 1
- }
- # Strip off the first word of the body - this should be the command
- if ($body -match "^(\S+)\s") {
- $command = $Matches[1]
- }
- else {
- throw [System.FormatException] "Message must include a command"
- exit 1
- }
- # By default, add a comment with the sender's address and timestamp
- # Use the '+' operator because Powershell does something odd with the date string
- $comment = (Get-Date).ToString('M-dd-yyyy HH:mm:ss') + " Updated by "+ $fromName + " (" + $fromAddress +")"
- # Strip off everything between the first word and the return or newline
- # and add it to the default comment
- #if ($body -match "^\S+\s+([^\[\r\n]*)\s") {
- if ($body -match "^\S+\s+([^\[\r\n]|^\r\n|[\w\s!""#$%&'()*+,\-\./:;<=>?@\\^`{|}~]*)\s") {
- $comment = $comment + ": " + $Matches[1]
- }
- Write-Host "Alert Definition ID ", $alertDefID
- Write-Host "Object ID ", $objectID
- Write-Host "Object Type ", $objectType
- Write-Host "Command ", $command
- Write-Host "Comment '",$comment,"'"
- #Hand off the command to the appropriate function
- try {
- switch ($command.ToLower()) {
- "ack" {
- Acknowledge-Alert $alertDefID $objectID $objectType $comment
- }
- "comment" {
- Comment-Alert $alertDefID $objectID $objectType $comment
- }
- default {
- throw [System.FormatException] "The ",$command," command is not supported."
- exit 1
- }
- }
- } catch {
- Write-Host $_.Exception.Message
- throw $_.Exception
- }
- return $true
- }
- # Acknowledge-Alert ($alertDefId, $objectId, $objectType)
- # alertDefId: GUID, The ID of the alert definition that was fulfilled to produce this alert
- # Corresponds to Orion.AlertStatus.AlertDefID
- # objectID: Integer, The ID of the object that triggered the alert
- # Corresponds to Orion.AlertStatus.ActiveObject
- # objectType: String, The name of the type of object that triggered the alert
- # Corresponds to Orion.AlertStatus.ObjectType
- # comment: String, A comment to append to the alert
- # Corresponds to Orion.AlertStatus.Notes
- #
- function Acknowledge-Alert () {
- Param(
- [String] $alertDefId,
- [String] $objectId,
- [String] $objectType,
- [String] $comment = ""
- )
- $swis = Connect-Swis $SWServer -UserName $SWUsername -Password $SWPassword
- $xmlString = "<ArrayOfAlertInfo xmlns='http://schemas.solarwinds.com/2008/Orion'>
- <AlertInfo>
- <DefinitionId>$($alertDefId)</DefinitionId>
- <ObjectType>$($objectType)</ObjectType>
- <ObjectId>$($objectId)</ObjectId>
- </AlertInfo>
- </ArrayOfAlertInfo>"
- $xmlElement = ([xml]$xmlString).DocumentElement
- # Acknowledge the alert
- Invoke-SwisVerb $swis Orion.AlertStatus Acknowledge @( $xmlElement )
- # If there is a nonempty comment, add it to the alert
- if ($comment -notmatch "^([\s]*)$" ) {
- try {
- Comment-Alert $alertDefID $objectID $objectType $comment
- } catch {
- Write-Host $_.Exception.Message
- throw $_.Exception
- }
- }
- return $true
- }
- # Comment-Alert ($alertDefId, $objectId, $objectType)
- # alertDefId: GUID, The ID of the alert definition that was fulfilled to produce this alert
- # Corresponds to Orion.AlertStatus.AlertDefID
- # objectID: Integer, The ID of the object that triggered the alert
- # Corresponds to Orion.AlertStatus.ActiveObject
- # objectType: String, The name of the type of object that triggered the alert
- # Corresponds to Orion.AlertStatus.ObjectType
- # comment: String, A comment to append to the alert
- # Corresponds to Orion.AlertStatus.Notes
- #
- function Comment-Alert () {
- Param(
- [String] $alertDefId,
- [String] $objectId,
- [String] $objectType,
- [String] $comment = ""
- )
- # Exit if the comment string is empty spaces
- if ($comment -notmatch "^([\s]*)$" ) {
- $swis = Connect-Swis $SWServer -UserName $SWUsername -Password $SWPassword
- Invoke-SwisVerb $swis Orion.AlertStatus AddNote @($alertDefId, $objectId, $objectType, $comment)
- } else {
- throw [System.FormatException] "Comment may not contain only spaces"
- exit 1
- }
- return $true
- }
- # Begin main script body
- # How many messages to process at once
- $batchSize = 5
- # Email address of the Exchange mailbox to read
- $exchangeEmail = "solarwinds@mydomain.com"
- # Exchange user credentials, if not using your own
- $exchangeUsername = "ORG-MYUNIT-Solarwinds"
- $exchangePassword = "ORG-MYUNIT-Solarwinds_password"
- $exchangeDomain = "DOMAINNAME"
- # Solarwinds credentials
- $SWUsername = "Solarwinds_user"
- $SWPassword = "Solarwinds_users_password"
- $SWServer = "solarwinds.mydomain.com"
- # load the Exchange Web Services assembly
- [void] [Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll")
- # set ref to exchange, first references 2007, 2nd is 2010 (default)
- $s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
- #$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
- # use first option if you want to impersonate, otherwise, grab your own credentials
- $s.Credentials = New-Object Net.NetworkCredential($exchangeUsername, $exchangePassword, $exchangeDomain)
- #$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
- #$s.UseDefaultCredentials = $true
- # Discover the URL from the Exchange email address
- $s.AutodiscoverUrl($exchangeEmail)
- # Get a handle to the Inbox
- $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
- # Get a handle to the Deleted Items folder
- $trash = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::DeletedItems)
- # Create a property set (to let us access the body & other details not available from the FindItems call)
- $psPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
- $psPropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;
- $items = $inbox.FindItems($batchSize)
- # output unread count
- Write-Host "Number of unread messages in",$inbox.DisplayName,":",$inbox.UnreadCount
- foreach ($item in $items.Items)
- {
- # load the property set to allow us to get to the body
- $item.load($psPropertySet)
- # Process the message
- try {
- Process-Message $item
- $status_message="Your request was handled successfully."
- Write-Host "Processed message with subject [ "$item.Subject" ]"
- } catch {
- $status_message="Your request failed. Please contact the monitoring team for support. Error details: " + $_.Exception.Message
- Write-Host "Unable to process message with subject [ "$item.Subject" ]. Error: "$_.Exception.Message
- } finally {
- $item.Reply($status_message, $false)
- $item.Move($trash.Id)
- $item.IsRead = $true
- }
- }
- # End main script body
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement