This discussion has been locked. The information referenced herein may be inaccurate due to age, software updates, or external references.
You can no longer post new replies to this discussion. If you have a similar question you can start a new discussion in this forum.

Embedding output into an alert email action

Hello everyone,

I'm stuck and I'm not sure what to do next.  First the disclaimer,  I am NOT a programmer, so the majority of my code was inherited by a lot of you in the community or in the Google universe.  

Objective:

Embed output from a batch file into an email alert action.  The output is ping and tracert results from the poller to the device.

Trigger Actions - Configuration Settings:

1st trigger is Execute An External Program:

Network path to external program = c:\Scripts\Ping-TraceRT.bat ${IP_Address} ${NodeName} -alert=${N=Alerting;M=AlertDefID} -alertId=${N=Alerting;M=AlertID} -${N=Alerting;M=Notes}

I'm receiving the expected output (ping and tracert) results in the text file.

2nd trigger is Send An Email/Page:

Message body:

Device Name: ${NodeName}
IP Address: ${N=SwisEntity;M=IP_Address}
Status: ${N=SwisEntity;M=Status}
Group: ${N=SwisEntity;M=CustomProperties.Assignment_Group}
Priority: ${N=SwisEntity;M=CustomProperties.Priority}
Date: ${DateTime}
Polling Engine: ${N=SwisEntity;M=Engine.DisplayName}

Ping & Tracert Information:
${N=Alerting;M=Notes}

The email doesn't contain any of the expected output from the batch file.  My first thought is that I'm missing something in script, but I'm not sure what that is and I'm not sure how I would code it.

Attached is the batch file I'm using.

@echo off

  cd C:\Scripts

  rem: This sends the Orion variables to a text file for later analysis.  This overwrites existing files of the same name.

  echo %* > %2.txt

  rem: This appends a ping to the text file.  This appends to the current file.

  ping %1 >> %2.txt

  rem: This appends a tracert to the text file.  This appends to the current file.

  tracert %1 >> %2.txt


Parents
  • How is your batch file updating the Notes field?  It doesn't look like there's any mechanism to put the contents of your text file back into the Alert Notes.

  • Thanks !  Last time I saw you was SWUG AZ right before the pandemic.  I hope you and your family are doing well.

    Do you by chance have any examples of what that code should look like in the script or is there some documentation that I can work off of?  In the meantime I'll look online and give it a try.

    Thanks again.

  • I hope you enjoyed yourself at the SWUG and we're anxious to get back on the road.  You know I'm going to go all #PowerShell on this, right?  Give me a little time to look in my archives to see if I already have something for this. If not, I think I can probably help you out in a day or so (unless someone beats me to the punch).

    This is the entity (Orion.AlertActive) and the verb (AppendNote) you would use.

  • This is my first pass - it's more complex than I thought to do this "properly" but it should be workable.

  • Thanks and sorry for the delay in responding back to you.  I thought this string was triggered to email me when there's a response.

    As far as the ping and tracert portion of the script, that's working.  I'm trying to figure out why it's not populating the AlertNote in SWQL.  My first guess is that the authentication method to SWQL is the issue.  I did replace COMPUTER name on row 55 to my main poller name, but that didn't resolve the missing data.  

  • Any chance you can show me the structure of your alert?  (Or better yet, export it and attach it to this thread)

  • <AlertDefinition xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Alerting.Models"><AlertID>1289</AlertID><AlertMessage>${N=Alerting;M=Severity}: ${NodeName} is ${N=SwisEntity;M=Status}</AlertMessage><AlertRefID>276432a5-6fba-4525-8fe1-f7ba30c5931a</AlertRefID><Canned>false</Canned><Category /><CreatedBy>sbolyard</CreatedBy><CustomProperties xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" /><Description>SolarWinds monitors the ping response of each device via the ICMP protocol. Alert is configured to send appropriate actions when the device has not made a ping response continuously for 4 minutes.</Description><Enabled>true</Enabled><ExecutionTimePeriods xmlns:d2p1="http://schemas.solarwinds.com/2008/Core" /><Frequency>PT1M</Frequency><LastEdit>2021-07-21T16:37:33.31Z</LastEdit><Name>TEST: Server: Device Down</Name><NotificationEnabled>true</NotificationEnabled><NotificationSettings xmlns:d2p1="http://schemas.solarwinds.com/2008/Core"><d2p1:Enabled>true</d2p1:Enabled><d2p1:NetObjectType>Node</d2p1:NetObjectType><d2p1:Severity>Warning</d2p1:Severity><d2p1:Subject>PS_Server Down_NOC_P1</d2p1:Subject><d2p1:_properties xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>IP Address</d3p1:Key><d3p1:Value><d2p1:Name>IP Address</d2p1:Name><d2p1:Value>${IP_Address}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Object Sub Type</d3p1:Key><d3p1:Value><d2p1:Name>Object Sub Type</d2p1:Name><d2p1:Value>${ObjectSubType}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Status Description</d3p1:Key><d3p1:Value><d2p1:Name>Status Description</d2p1:Name><d2p1:Value>${StatusDescription}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Node Name</d3p1:Key><d3p1:Value><d2p1:Name>Node Name</d2p1:Name><d2p1:Value>${SysName}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Vendor</d3p1:Key><d3p1:Value><d2p1:Name>Vendor</d2p1:Name><d2p1:Value>${Vendor}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt></d2p1:_properties></NotificationSettings><ObjectType>Node</ObjectType><Reset><Conditions><ConditionChainItem><AndThenTimeInterval i:nil="true" /><ChainType>ResetInverseToTrigger</ChainType><Condition xmlns:d5p1="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Alerting" i:nil="true" /><ConjunctionOperator>None</ConjunctionOperator><IsInvertedMinCountThreshold>false</IsInvertedMinCountThreshold><NetObjectsMinCountThreshold i:nil="true" /><ObjectType i:nil="true" /><SustainTime i:nil="true" /><Type i:nil="true" /></ConditionChainItem></Conditions></Reset><ResetActions xmlns:d2p1="http://schemas.solarwinds.com/2008/Orion" /><Severity>Critical</Severity><Trigger><Conditions><ConditionChainItem><AndThenTimeInterval i:nil="true" /><ChainType>Trigger</ChainType><Condition xmlns:d5p1="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Alerting" xmlns:d5p2="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Alerting.Plugins.Conditions.Dynamic" i:type="d5p2:AlertConditionDynamic"><d5p2:ExprTree><d5p1:Child><d5p1:Expr><d5p1:Child><d5p1:Expr><d5p1:Child /><d5p1:NodeType>Field</d5p1:NodeType><d5p1:Value>Orion.Nodes|Status</d5p1:Value></d5p1:Expr><d5p1:Expr><d5p1:Child /><d5p1:NodeType>Constant</d5p1:NodeType><d5p1:Value>2</d5p1:Value></d5p1:Expr></d5p1:Child><d5p1:NodeType>Operator</d5p1:NodeType><d5p1:Value>=</d5p1:Value></d5p1:Expr><d5p1:Expr><d5p1:Child><d5p1:Expr><d5p1:Child i:nil="true" /><d5p1:NodeType>Field</d5p1:NodeType><d5p1:Value>Orion.Nodes|Caption</d5p1:Value></d5p1:Expr><d5p1:Expr><d5p1:Child i:nil="true" /><d5p1:NodeType>Constant</d5p1:NodeType><d5p1:Value>C1VTWTESTSAP01</d5p1:Value></d5p1:Expr></d5p1:Child><d5p1:NodeType>Operator</d5p1:NodeType><d5p1:Value>=</d5p1:Value></d5p1:Expr></d5p1:Child><d5p1:NodeType>Operator</d5p1:NodeType><d5p1:Value>AND</d5p1:Value></d5p2:ExprTree><d5p2:Scope i:nil="true" /><d5p2:TimeWindow i:nil="true" /></Condition><ConjunctionOperator>None</ConjunctionOperator><IsInvertedMinCountThreshold>false</IsInvertedMinCountThreshold><NetObjectsMinCountThreshold i:nil="true" /><ObjectType>Node</ObjectType><SustainTime>PT4M</SustainTime><Type xmlns:d5p1="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Alerting.Plugins.Conditions.Dynamic" i:type="d5p1:ConditionTypeDynamic" /></ConditionChainItem></Conditions></Trigger><TriggerActions xmlns:d2p1="http://schemas.solarwinds.com/2008/Orion"><d2p1:ActionDefinition xmlns:d3p1="http://schemas.solarwinds.com/2008/Core" i:type="d3p1:ActionDefinitionEx"><d2p1:ActionProperties><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailBCC</d2p1:PropertyName><d2p1:PropertyValue /></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailCC</d2p1:PropertyName><d2p1:PropertyValue /></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailFrom</d2p1:PropertyName><d2p1:PropertyValue>Monitoring@honorhealth.com</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailMessage</d2p1:PropertyName><d2p1:PropertyValue>Auto-Ticket created for:
    
    Device Name:  ${NodeName}
    IP Address:  ${N=SwisEntity;M=IP_Address}
    Status:  ${N=SwisEntity;M=Status}
    Group:  ${N=SwisEntity;M=CustomProperties.Assignment_Group}
    Priority:  ${N=SwisEntity;M=CustomProperties.Priority}
    Date:      ${DateTime}
    Polling Engine:  ${N=SwisEntity;M=Engine.DisplayName}
    
    Ping &amp; Tracert Information:
    ${N=Alerting;M=Notes}
    
    Alert URL: ${N=Alerting;M=AlertDetailsUrl}  
    Alert Name: ${N=Alerting;M=AlertName}</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailTo</d2p1:PropertyName><d2p1:PropertyValue>sbolyard@honorhealth.com</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EscalationLevel</d2p1:PropertyName><d2p1:PropertyValue>5</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionIfAknowledge</d2p1:PropertyName><d2p1:PropertyValue>False</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionRepeatTimeSpan</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>MessageContentType</d2p1:PropertyName><d2p1:PropertyValue>1</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Priority</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Sender</d2p1:PropertyName><d2p1:PropertyValue>SolarWinds Monitoring</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>SmtpServerID</d2p1:PropertyName><d2p1:PropertyValue>4</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Subject</d2p1:PropertyName><d2p1:PropertyValue>${N=Alerting;M=Severity}: ${NodeName} is ${N=SwisEntity;M=Status}</d2p1:PropertyValue></d2p1:ActionProperty></d2p1:ActionProperties><d2p1:ActionTypeID>Email</d2p1:ActionTypeID><d2p1:Description>To: sbolyard@honorhealth.com &lt;br/&gt;From: Monitoring@honorhealth.com&lt;br/&gt;Subject: ${N=Alerting;M=Severity}: ${NodeName} is ${N=SwisEntity;M=Status}</d2p1:Description><d2p1:Enabled>true</d2p1:Enabled><d2p1:ID i:nil="true" /><d2p1:IconPath i:nil="true" /><d2p1:IsShared>false</d2p1:IsShared><d2p1:Order>1</d2p1:Order><d2p1:TimePeriods /><d2p1:Title>TEST Notification: Service desk, NOC and OSC supervisors</d2p1:Title><d2p1:TransitiveID i:nil="true" /><d3p1:BackUpSmtpServer i:nil="true" /><d3p1:SmtpServer><d3p1:Address>mail.honorhealth.com</d3p1:Address><d3p1:BackupServerID>0</d3p1:BackupServerID><d3p1:Credentials i:nil="true" /><d3p1:EnableSSL>false</d3p1:EnableSSL><d3p1:IsDefault>false</d3p1:IsDefault><d3p1:Port>25</d3p1:Port><d3p1:ProtectionHash i:nil="true" /><d3p1:ProtectionIV i:nil="true" /><d3p1:ServerID>4</d3p1:ServerID></d3p1:SmtpServer></d2p1:ActionDefinition><d2p1:ActionDefinition><d2p1:ActionProperties><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Credentials</d2p1:PropertyName><d2p1:PropertyValue>65</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EscalationLevel</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionIfAknowledge</d2p1:PropertyName><d2p1:PropertyValue>True</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionRepeatTimeSpan</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>ProgramPath</d2p1:PropertyName><d2p1:PropertyValue>C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe -file "c:\scripts\PingTraceRT.ps1" ${IP_Address} ${AlertObjectID} ${AddNote} ${AlertNote}</d2p1:PropertyValue></d2p1:ActionProperty></d2p1:ActionProperties><d2p1:ActionTypeID>ExecuteExternalProgram</d2p1:ActionTypeID><d2p1:Description>Execute a program when the Alert is Triggered or Reset</d2p1:Description><d2p1:Enabled>true</d2p1:Enabled><d2p1:ID>4674</d2p1:ID><d2p1:IconPath i:nil="true" /><d2p1:IsShared>false</d2p1:IsShared><d2p1:Order>1</d2p1:Order><d2p1:TimePeriods xmlns:d4p1="http://schemas.solarwinds.com/2008/Core" /><d2p1:Title>Ping and tracert</d2p1:Title><d2p1:TransitiveID i:nil="true" /></d2p1:ActionDefinition></TriggerActions><Uri>swis://<NPM polling engine>/Orion/Orion.AlertConfigurations/AlertID=1289</Uri></AlertDefinition>

  • OK - I had to step back and think about this some more.  This is done slightly differently now.  There's the function Test-PingTrace (stored in func_PingTrace.ps1) and the script that's being called by Orion (stored as Ping-TraceRT.ps1)  Put these files in the same folder (looks like you used 'C:\Scripts') in your example.

    <# File: func_PingTrace.ps1 #>
    <#
    .Synopsis
       Function that runs a 'PowerShell' ping and trace route - optionally adds it to an alert note
    .NOTES
       To help with https://thwack.solarwinds.com/product-forums/the-orion-platform/f/alert-lab/91386/embedding-output-into-an-alert-email-action
    
    #>
    function Test-PingTrace {
        [CmdletBinding(
            HelpUri = 'https://thwack.solarwinds.com/product-forums/the-orion-platform/f/alert-lab/91386/embedding-output-into-an-alert-email-action/',
            SupportsShouldProcess = $true,
            ConfirmImpact = 'Low')]
        [Alias()]
        [OutputType([String])]
        Param
        (
            # The IP Address of the thing on which to operate
            [Parameter(Mandatory = $true)]
            [Alias("IP")] 
            [string]$IPAddress,
    
            # The Alert Object ID - required by the appendNote verb
            [Parameter(Mandatory = $false)]
            [int]$AlertObjectID,
    
            # Do you want us to update the note or just do the thing?
            [switch]$AddNote,
    
            # Number of times to try and ping (default to 4)
            [int]$NumPings = 4,
    
            # Number of times to hop for a trace (default to 15)
            [int]$NumHops = 15
        )
    
        Begin {
            #### Build Connection to SolarWinds Orion Server ####
            # If we want to update the note, we need to connect to SWIS
            if ( $AddNote ) {
                # Connect to "self" (Local Computername and connect with the certificate)
                $SwisConnection = Connect-Swis -Hostname "$env:COMPUTERNAME" -Certificate
            }
        }
        Process {
            if ( $pscmdlet.ShouldProcess("$IPAddress", "Ping the thing") ) {
    
                Write-Host "Pinging '$IPAddress' $NumPings times" -ForegroundColor Yellow
                # Using Test-Connection adds a whole bunch of other stuff we don't need, so get the basics
                $PingResults = Test-Connection -ComputerName $IPAddress -Count $NumPings -ErrorAction SilentlyContinue | Select-Object -Property @{ Name = "Source"; Expression = { $_.PSComputerName } }, Address, ReplySize, ResponseTime
    
                Write-Host "Running Traceroute for '$IPAddress'" -ForegroundColor Yellow
                # Tracing using Test-NetConnection adds a whole bunch of other stuff we don't need, so get the basics
                $TraceRtResults = Test-NetConnection -ComputerName $IPAddress -TraceRoute -Hops $NumHops -ErrorAction SilentlyContinue | Select-Object SourceAddress, RemoteAddress, @{ Name = "RTT"; Expression = { $_.PingReplyDetails.RoundtripTime } }, TraceRoute
    
                $Note = ""
                Write-Host "Ping Results:" -ForegroundColor Green
                if ( $PingResults ) {
                    $PingResults
                    $Note +=  @"
    Ping Results:
    -----------------------------------------------------
    Source Address:         $( $env:COMPUTERNAME )
    Remote Address:         $( $PingResults[0].Address )
    Number of Pings:        $NumPings
    Avg Response Time (ms): $( $PingResults | Measure-Object -Property ResponseTime -Average | Select-Object -ExpandProperty Average )
    
    "@                
                }
                else {
                    Write-Host "Ping to '$IPAddress' did not return any packets" -ForegroundColor Red
                    $Note += @"
    Ping Results:
    -----------------------------------------------------
    Source Address:         $( $env:COMPUTERNAME )
    Remote Address:         $IPAddress
    Number of Pings:        $NumPings
    Avg Response Time (ms): N/A
    ***** PING FAILED *****
    
    "@
                }
    
    
                Write-Host "Trace Results:" -ForegroundColor Green
                if ( $TraceRtResults ) {
                    $TraceRtResults
                    $Note += @"
    Trace Route Results:
    -----------------------------------------------------
    Source Address:       $( $env:COMPUTERNAME )
    Remote Address:       $IPAddress
    Round Trip Time (ms): $( $TraceRtResults.RTT )
    Hops:
    $( $TraceRtResults.TraceRoute | ForEach-Object { "`t$( $_ )`n" } )
    "@
                } else {
                    Write-Host "Trace to '$IPAddress' did not complete correctly"
                    $Note += @"
    Trace Route Results:
    -----------------------------------------------------
    Source Address:       $( $env:COMPUTERNAME )
    Remote Address:       $IPAddress
    Round Trip Time (ms): N/A
    Hops:
        N/A
    ***** TRACE FAILED *****
    "@
                }
    
                if ( $AddNote ) {
                    # Update the Note in Orion
                    # Since 'AppendNote' is expecting an array of AlertObjectIds, we can just wrap with @( $thing ) to turn it into an array
                    Invoke-SwisVerb -SwisConnection $SwisConnection -EntityName "Orion.AlertActive" -Verb "AppendNote" -Arguments ( @( $AlertObjectID ), $Note ) | Out-Null
                }
            }
        }
    
        End {
            # Nothing to do here
        }
    }

    <# File Name: Ping-TraceRT.ps1 #>
    
    # Move to the Proper Folder where these scripts 'live'
    Write-Host "Execution Path: $( ( Split-Path -Path $MyInvocation.MyCommand.Path -Parent ) )"
    Set-Location -Path ( Split-Path -Path $MyInvocation.MyCommand.Path -Parent )
    
    # Check & Import the Test-PingTrace function
    
    
    if ( -not ( Get-Command -Name Test-PingTrace -ErrorAction SilentlyContinue) ) {
        . .\func_PingTrace.ps1
    }
    
    <# Expected Arguments
        First argument: IP Address
        Second argument: AlertObjectID
    #>
    
    if ( $args[0] ) {
        $IPAddress = $args[0]
    
    }
    if ( $args[1]) {
        $AlertObectID = $args[1]
        $UpdateNote   = $true
    } else {
        $UpdateNote   = $false
    }
    
    
    # Do the thing using the function
    Test-PingTrace -IPAddress $IPAddress -AlertObjectID $AlertObectID -AddNote:$UpdateNote

    In your alert action to execute an external program the call is:

    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File C:\Scripts\Ping-TraceRT.ps1 ${N=SwisEntity;M=IP_Address} ${N=Alerting;M=AlertObjectID}

    The way the authentication is built in the function, it has to run on the Orion server, but I did test it and it seems to have worked.

    I've tried to comment the scripts as much as possible to be more of a help.

Reply
  • OK - I had to step back and think about this some more.  This is done slightly differently now.  There's the function Test-PingTrace (stored in func_PingTrace.ps1) and the script that's being called by Orion (stored as Ping-TraceRT.ps1)  Put these files in the same folder (looks like you used 'C:\Scripts') in your example.

    <# File: func_PingTrace.ps1 #>
    <#
    .Synopsis
       Function that runs a 'PowerShell' ping and trace route - optionally adds it to an alert note
    .NOTES
       To help with https://thwack.solarwinds.com/product-forums/the-orion-platform/f/alert-lab/91386/embedding-output-into-an-alert-email-action
    
    #>
    function Test-PingTrace {
        [CmdletBinding(
            HelpUri = 'https://thwack.solarwinds.com/product-forums/the-orion-platform/f/alert-lab/91386/embedding-output-into-an-alert-email-action/',
            SupportsShouldProcess = $true,
            ConfirmImpact = 'Low')]
        [Alias()]
        [OutputType([String])]
        Param
        (
            # The IP Address of the thing on which to operate
            [Parameter(Mandatory = $true)]
            [Alias("IP")] 
            [string]$IPAddress,
    
            # The Alert Object ID - required by the appendNote verb
            [Parameter(Mandatory = $false)]
            [int]$AlertObjectID,
    
            # Do you want us to update the note or just do the thing?
            [switch]$AddNote,
    
            # Number of times to try and ping (default to 4)
            [int]$NumPings = 4,
    
            # Number of times to hop for a trace (default to 15)
            [int]$NumHops = 15
        )
    
        Begin {
            #### Build Connection to SolarWinds Orion Server ####
            # If we want to update the note, we need to connect to SWIS
            if ( $AddNote ) {
                # Connect to "self" (Local Computername and connect with the certificate)
                $SwisConnection = Connect-Swis -Hostname "$env:COMPUTERNAME" -Certificate
            }
        }
        Process {
            if ( $pscmdlet.ShouldProcess("$IPAddress", "Ping the thing") ) {
    
                Write-Host "Pinging '$IPAddress' $NumPings times" -ForegroundColor Yellow
                # Using Test-Connection adds a whole bunch of other stuff we don't need, so get the basics
                $PingResults = Test-Connection -ComputerName $IPAddress -Count $NumPings -ErrorAction SilentlyContinue | Select-Object -Property @{ Name = "Source"; Expression = { $_.PSComputerName } }, Address, ReplySize, ResponseTime
    
                Write-Host "Running Traceroute for '$IPAddress'" -ForegroundColor Yellow
                # Tracing using Test-NetConnection adds a whole bunch of other stuff we don't need, so get the basics
                $TraceRtResults = Test-NetConnection -ComputerName $IPAddress -TraceRoute -Hops $NumHops -ErrorAction SilentlyContinue | Select-Object SourceAddress, RemoteAddress, @{ Name = "RTT"; Expression = { $_.PingReplyDetails.RoundtripTime } }, TraceRoute
    
                $Note = ""
                Write-Host "Ping Results:" -ForegroundColor Green
                if ( $PingResults ) {
                    $PingResults
                    $Note +=  @"
    Ping Results:
    -----------------------------------------------------
    Source Address:         $( $env:COMPUTERNAME )
    Remote Address:         $( $PingResults[0].Address )
    Number of Pings:        $NumPings
    Avg Response Time (ms): $( $PingResults | Measure-Object -Property ResponseTime -Average | Select-Object -ExpandProperty Average )
    
    "@                
                }
                else {
                    Write-Host "Ping to '$IPAddress' did not return any packets" -ForegroundColor Red
                    $Note += @"
    Ping Results:
    -----------------------------------------------------
    Source Address:         $( $env:COMPUTERNAME )
    Remote Address:         $IPAddress
    Number of Pings:        $NumPings
    Avg Response Time (ms): N/A
    ***** PING FAILED *****
    
    "@
                }
    
    
                Write-Host "Trace Results:" -ForegroundColor Green
                if ( $TraceRtResults ) {
                    $TraceRtResults
                    $Note += @"
    Trace Route Results:
    -----------------------------------------------------
    Source Address:       $( $env:COMPUTERNAME )
    Remote Address:       $IPAddress
    Round Trip Time (ms): $( $TraceRtResults.RTT )
    Hops:
    $( $TraceRtResults.TraceRoute | ForEach-Object { "`t$( $_ )`n" } )
    "@
                } else {
                    Write-Host "Trace to '$IPAddress' did not complete correctly"
                    $Note += @"
    Trace Route Results:
    -----------------------------------------------------
    Source Address:       $( $env:COMPUTERNAME )
    Remote Address:       $IPAddress
    Round Trip Time (ms): N/A
    Hops:
        N/A
    ***** TRACE FAILED *****
    "@
                }
    
                if ( $AddNote ) {
                    # Update the Note in Orion
                    # Since 'AppendNote' is expecting an array of AlertObjectIds, we can just wrap with @( $thing ) to turn it into an array
                    Invoke-SwisVerb -SwisConnection $SwisConnection -EntityName "Orion.AlertActive" -Verb "AppendNote" -Arguments ( @( $AlertObjectID ), $Note ) | Out-Null
                }
            }
        }
    
        End {
            # Nothing to do here
        }
    }

    <# File Name: Ping-TraceRT.ps1 #>
    
    # Move to the Proper Folder where these scripts 'live'
    Write-Host "Execution Path: $( ( Split-Path -Path $MyInvocation.MyCommand.Path -Parent ) )"
    Set-Location -Path ( Split-Path -Path $MyInvocation.MyCommand.Path -Parent )
    
    # Check & Import the Test-PingTrace function
    
    
    if ( -not ( Get-Command -Name Test-PingTrace -ErrorAction SilentlyContinue) ) {
        . .\func_PingTrace.ps1
    }
    
    <# Expected Arguments
        First argument: IP Address
        Second argument: AlertObjectID
    #>
    
    if ( $args[0] ) {
        $IPAddress = $args[0]
    
    }
    if ( $args[1]) {
        $AlertObectID = $args[1]
        $UpdateNote   = $true
    } else {
        $UpdateNote   = $false
    }
    
    
    # Do the thing using the function
    Test-PingTrace -IPAddress $IPAddress -AlertObjectID $AlertObectID -AddNote:$UpdateNote

    In your alert action to execute an external program the call is:

    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File C:\Scripts\Ping-TraceRT.ps1 ${N=SwisEntity;M=IP_Address} ${N=Alerting;M=AlertObjectID}

    The way the authentication is built in the function, it has to run on the Orion server, but I did test it and it seems to have worked.

    I've tried to comment the scripts as much as possible to be more of a help.

Children
  • Update:

    Looking at the script a little further I noticed the authentication method is using the SolarWinds certificate.  I did some research on that and found out that swispowershell is not installed on the main poller.  I went ahead and did that and was able to make the connection to SWQL.

    Unfortunately I'm still having problems where the data is not showing up in the DB and email.  I need to verify if I followed your instructions correctly.  Below you will find the alert export information and a screen capture of the directory that I put the two ps1 files.

    <AlertDefinition xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Alerting.Models"><AlertID>1289</AlertID><AlertMessage>${N=Alerting;M=Severity}: ${NodeName} is ${N=SwisEntity;M=Status}</AlertMessage><AlertRefID>276432a5-6fba-4525-8fe1-f7ba30c5931a</AlertRefID><Canned>false</Canned><Category /><CreatedBy>sbolyard</CreatedBy><CustomProperties xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" /><Description>SolarWinds monitors the ping response of each device via the ICMP protocol. Alert is configured to send appropriate actions when the device has not made a ping response continuously for 4 minutes.</Description><Enabled>true</Enabled><ExecutionTimePeriods xmlns:d2p1="http://schemas.solarwinds.com/2008/Core" /><Frequency>PT1M</Frequency><LastEdit>2021-07-22T17:04:19.9133333Z</LastEdit><Name>TEST: Server: Device Down</Name><NotificationEnabled>true</NotificationEnabled><NotificationSettings xmlns:d2p1="http://schemas.solarwinds.com/2008/Core"><d2p1:Enabled>true</d2p1:Enabled><d2p1:NetObjectType>Node</d2p1:NetObjectType><d2p1:Severity>Warning</d2p1:Severity><d2p1:Subject>PS_Server Down_NOC_P1</d2p1:Subject><d2p1:_properties xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>IP Address</d3p1:Key><d3p1:Value><d2p1:Name>IP Address</d2p1:Name><d2p1:Value>${IP_Address}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Object Sub Type</d3p1:Key><d3p1:Value><d2p1:Name>Object Sub Type</d2p1:Name><d2p1:Value>${ObjectSubType}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Status Description</d3p1:Key><d3p1:Value><d2p1:Name>Status Description</d2p1:Name><d2p1:Value>${StatusDescription}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Node Name</d3p1:Key><d3p1:Value><d2p1:Name>Node Name</d2p1:Name><d2p1:Value>${SysName}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt><d3p1:Key>Vendor</d3p1:Key><d3p1:Value><d2p1:Name>Vendor</d2p1:Name><d2p1:Value>${Vendor}</d2p1:Value></d3p1:Value></d3p1:KeyValueOfstringAlertNotificationProperty9sQWCBBt></d2p1:_properties></NotificationSettings><ObjectType>Node</ObjectType><Reset><Conditions><ConditionChainItem><AndThenTimeInterval i:nil="true" /><ChainType>ResetInverseToTrigger</ChainType><Condition xmlns:d5p1="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Alerting" i:nil="true" /><ConjunctionOperator>None</ConjunctionOperator><IsInvertedMinCountThreshold>false</IsInvertedMinCountThreshold><NetObjectsMinCountThreshold i:nil="true" /><ObjectType i:nil="true" /><SustainTime i:nil="true" /><Type i:nil="true" /></ConditionChainItem></Conditions></Reset><ResetActions xmlns:d2p1="http://schemas.solarwinds.com/2008/Orion" /><Severity>Critical</Severity><Trigger><Conditions><ConditionChainItem><AndThenTimeInterval i:nil="true" /><ChainType>Trigger</ChainType><Condition xmlns:d5p1="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Models.Alerting" xmlns:d5p2="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Alerting.Plugins.Conditions.Dynamic" i:type="d5p2:AlertConditionDynamic"><d5p2:ExprTree><d5p1:Child><d5p1:Expr><d5p1:Child><d5p1:Expr><d5p1:Child /><d5p1:NodeType>Field</d5p1:NodeType><d5p1:Value>Orion.Nodes|Status</d5p1:Value></d5p1:Expr><d5p1:Expr><d5p1:Child /><d5p1:NodeType>Constant</d5p1:NodeType><d5p1:Value>2</d5p1:Value></d5p1:Expr></d5p1:Child><d5p1:NodeType>Operator</d5p1:NodeType><d5p1:Value>=</d5p1:Value></d5p1:Expr><d5p1:Expr><d5p1:Child><d5p1:Expr><d5p1:Child i:nil="true" /><d5p1:NodeType>Field</d5p1:NodeType><d5p1:Value>Orion.Nodes|Caption</d5p1:Value></d5p1:Expr><d5p1:Expr><d5p1:Child i:nil="true" /><d5p1:NodeType>Constant</d5p1:NodeType><d5p1:Value>C1VTWTESTSAP01</d5p1:Value></d5p1:Expr></d5p1:Child><d5p1:NodeType>Operator</d5p1:NodeType><d5p1:Value>=</d5p1:Value></d5p1:Expr></d5p1:Child><d5p1:NodeType>Operator</d5p1:NodeType><d5p1:Value>AND</d5p1:Value></d5p2:ExprTree><d5p2:Scope i:nil="true" /><d5p2:TimeWindow i:nil="true" /></Condition><ConjunctionOperator>None</ConjunctionOperator><IsInvertedMinCountThreshold>false</IsInvertedMinCountThreshold><NetObjectsMinCountThreshold i:nil="true" /><ObjectType>Node</ObjectType><SustainTime>PT4M</SustainTime><Type xmlns:d5p1="http://schemas.datacontract.org/2004/07/SolarWinds.Orion.Core.Alerting.Plugins.Conditions.Dynamic" i:type="d5p1:ConditionTypeDynamic" /></ConditionChainItem></Conditions></Trigger><TriggerActions xmlns:d2p1="http://schemas.solarwinds.com/2008/Orion"><d2p1:ActionDefinition xmlns:d3p1="http://schemas.solarwinds.com/2008/Core" i:type="d3p1:ActionDefinitionEx"><d2p1:ActionProperties><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailBCC</d2p1:PropertyName><d2p1:PropertyValue /></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailCC</d2p1:PropertyName><d2p1:PropertyValue /></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailFrom</d2p1:PropertyName><d2p1:PropertyValue>Monitoring@test.com</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailMessage</d2p1:PropertyName><d2p1:PropertyValue>Auto-Ticket created for:
    
    Device Name:  ${NodeName}
    IP Address:  ${N=SwisEntity;M=IP_Address}
    Status:  ${N=SwisEntity;M=Status}
    Group:  ${N=SwisEntity;M=CustomProperties.Assignment_Group}
    Priority:  ${N=SwisEntity;M=CustomProperties.Priority}
    Date:      ${DateTime}
    Polling Engine:  ${N=SwisEntity;M=Engine.DisplayName}
    
    Ping &amp; Tracert Information:
    ${N=Alerting;M=Notes}
    
    Alert URL: ${N=Alerting;M=AlertDetailsUrl}  
    Alert Name: ${N=Alerting;M=AlertName}</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EmailTo</d2p1:PropertyName><d2p1:PropertyValue>demo@test.com</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EscalationLevel</d2p1:PropertyName><d2p1:PropertyValue>5</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionIfAknowledge</d2p1:PropertyName><d2p1:PropertyValue>False</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionRepeatTimeSpan</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>MessageContentType</d2p1:PropertyName><d2p1:PropertyValue>1</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Priority</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Sender</d2p1:PropertyName><d2p1:PropertyValue>SolarWinds Monitoring</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>SmtpServerID</d2p1:PropertyName><d2p1:PropertyValue>4</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Subject</d2p1:PropertyName><d2p1:PropertyValue>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File C:\Scripts\Ping-TraceRT.ps1 ${N=SwisEntity;M=IP_Address} ${N=Alerting;M=AlertObjectID}</d2p1:PropertyValue></d2p1:ActionProperty></d2p1:ActionProperties><d2p1:ActionTypeID>Email</d2p1:ActionTypeID><d2p1:Description>To: demo@test.com &lt;br/&gt;From: Monitoring@test.com&lt;br/&gt;Subject: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File C:\Scripts\Ping-TraceRT.ps1 ${N=SwisEntity;M=IP_Address} ${N=Alerting;M=AlertObjectID}</d2p1:Description><d2p1:Enabled>true</d2p1:Enabled><d2p1:ID i:nil="true" /><d2p1:IconPath i:nil="true" /><d2p1:IsShared>false</d2p1:IsShared><d2p1:Order>1</d2p1:Order><d2p1:TimePeriods /><d2p1:Title>TEST Notification: Service desk, NOC and OSC supervisors</d2p1:Title><d2p1:TransitiveID i:nil="true" /><d3p1:BackUpSmtpServer i:nil="true" /><d3p1:SmtpServer><d3p1:Address>demo.demo.com</d3p1:Address><d3p1:BackupServerID>0</d3p1:BackupServerID><d3p1:Credentials i:nil="true" /><d3p1:EnableSSL>false</d3p1:EnableSSL><d3p1:IsDefault>false</d3p1:IsDefault><d3p1:Port>25</d3p1:Port><d3p1:ProtectionHash i:nil="true" /><d3p1:ProtectionIV i:nil="true" /><d3p1:ServerID>4</d3p1:ServerID></d3p1:SmtpServer></d2p1:ActionDefinition><d2p1:ActionDefinition><d2p1:ActionProperties><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>Credentials</d2p1:PropertyName><d2p1:PropertyValue>65</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>EscalationLevel</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionIfAknowledge</d2p1:PropertyName><d2p1:PropertyValue>True</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>executionRepeatTimeSpan</d2p1:PropertyName><d2p1:PropertyValue>0</d2p1:PropertyValue></d2p1:ActionProperty><d2p1:ActionProperty><d2p1:IsShared>false</d2p1:IsShared><d2p1:PropertyName>ProgramPath</d2p1:PropertyName><d2p1:PropertyValue>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File C:\Scripts\Ping-TraceRT.ps1 ${N=SwisEntity;M=IP_Address} ${N=Alerting;M=AlertObjectID}</d2p1:PropertyValue></d2p1:ActionProperty></d2p1:ActionProperties><d2p1:ActionTypeID>ExecuteExternalProgram</d2p1:ActionTypeID><d2p1:Description>Execute a program when the Alert is Triggered or Reset</d2p1:Description><d2p1:Enabled>true</d2p1:Enabled><d2p1:ID>4674</d2p1:ID><d2p1:IconPath i:nil="true" /><d2p1:IsShared>false</d2p1:IsShared><d2p1:Order>1</d2p1:Order><d2p1:TimePeriods xmlns:d4p1="http://schemas.solarwinds.com/2008/Core" /><d2p1:Title>Ping and tracert</d2p1:Title><d2p1:TransitiveID i:nil="true" /></d2p1:ActionDefinition></TriggerActions><Uri>swis://pollingengine.demo.com/Orion/Orion.AlertConfigurations/AlertID=2468</Uri></AlertDefinition>
    

  • Are the alert notes showing up in the Web Console when the alert is triggered?

    Additionally, I don't think the 'subject' of your email is correct. Slight smile

    Finally, I don't think it's necessary to put quotes around things, but maybe we should change out the execution command to be:

    "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Unrestricted -File "C:\Scripts\Ping-TraceRT.ps1" "${N=SwisEntity;M=IP_Address}" "${N=Alerting;M=AlertObjectID}"

    A few follow-ups if those don't help...

    What version of the Orion platform are you running?

    When you installed the SwisPowerShell module, did you do it for "all users" or just the one account?  (When installing modules there's a -Scope option that controls this action.  If it's just for a single user, then you'll also need to provide that user in the execution dialog box.

  • Corrected the Subject line. Got a little paste happy. We're on the 2020.5 HF1 version.  I updated the network path to include the quotes. I installed the OrionSDK.msi which included the SwisPowerShell module.  The install didn't ask the question about all users or just one.  I've been using the Define user option it tests successfully.  One thing I will mention, when I  tested the connection using $swis = Connect-Swis, I entered my local SolarWinds administrator account to access the API. Since it's not a Windows account, do I need a Windows account with Admin permissions to run this successfully?  I checked the Alert Notes on Web and the field is blank. Could it be a timing thing?  Maybe the script is taking longer than 5 minutes.

  • It might be taking longer than 5 minutes.  If so, that's an easy fix.

    If you are running it on the Orion server itself, you should be able to connect to SWIS via:

    $SwisConnection = Connect-Swis -Hostname "OrionServerNameGoeshere" -Certificate

    That'll connect with the Orion 'service' account and won't need credentials.

    What if you run the script set manually?

    Open a command prompt (not PowerShell) window and put the execution string (swapping in a valid IP and a valid AlertObjectID)?

    Then when I refreshed the web page at /Orion/NetPerfMon/ActiveAlertDetails.aspx?NetObject=AAT:1080

    I got this:

  • OMG - I think I've been leading you down the complete wrong path here.  Let me investigate something...

  • No worries.  Wink Just as an fyi, I did follow the steps above and I did receive output (similar to yours) for the Alert Notes. I ran it in CMD with the service account.

  • After re-reading the names of the verbs and having a come to $diety meeting with myself, I think we need to use the AddNote verb on the Orion.AlertStatus entity.For parameters it takes:

    • [string]alertDefinitionId
    • [string]activeObject
    • [string]objectType
    • [string]note

    Like I said before, I need to dig in a little bit more here and do some testing, but the framework we already have should work.  I'm so, so sorry for the delay.

  • No need to apologize.  I REALLY appreciate your help with this. I'm learning a lot and it's forcing me out of my comfort zone by getting me to learn the code so that I can do this myself going forward. 

  • OK - I think I've got it (but I've said that before haven't I?)

    The files are:

    I've rewritten them to be a little more in line with some best practices, but it's not my best work.

    I also added notes/details in the first one on how to call it.

    After I executed it, this is what appeared on my web console:

    Let's (hopefully) call that part done.  You can validate after you make the edits by running:

    SELECT AlertDefID
         , ActiveObject
         , ObjectType
         , ObjectName
         , AlertMessage
         , Notes
    FROM Orion.AlertStatus
    ORDER BY ObjectName

    In SWQL Studio and looking at the "Notes" field.

    In my environment, the total execution time for the script was 1.39 minutes - so under the 5 minute thing.

  • Verified that this works on two nodes running the script through the command line.  Just like you I received the correct information in the History of this alert on this object and in the Alert Notes field.  Both ran under 2 minutes.