Version 1

    ###########################################################################

    #

    # NAME: Solarwinds-AckFromVictorOps.ps1

    #

    # AUTHOR: Sean Stark

    #

    # Purpose: Gets VictorOps Alerts from REST API. Parses through each alert and acks or clears the associated alert in Solarwinds.

    #

    # Current Limitations: - You may be limited to the number of VictorOps API calls depending on your subscription

    #                      - The VictorOps incidents API endpoint does not return any custom fields you may be sending.

    #                      - Unable to set the AcknowledgedBy field. This will always show the service account running the script.

    #

    ###########################################################################

    #

    # Updated to v2 by VictorOps in April 2019

    #

    ###########################################################################

    #

    #

    #

    ############  Variables ##############

     

     

    #Victor Ops Company ID

    $API_ID = "<Your API ID>"

     

     

    #Victor Ops API Key

    $ApiKey = "<Your API Key>"

     

     

    #Set to your SolarWinds Primary Application Server

    $SolarWindsServer = "<Your Primary SolarWinds Server Name>"

     

     

    #Victor Ops API Url for Incidents

    $API_URL = "https://api.victorops.com/api-public/v1/incidents"

     

     

    #Create a Header Object for the Rest Request

    $headers = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]'

    $headers.Add("X-VO-Api-Key", $ApiKey)

    $headers.Add("X-VO-Api-Id", $API_ID)

     

     

    #Ignore SSL Certificate Trusts

    add-type @"

        using System.Net;

        using System.Security.Cryptography.X509Certificates;

        public class TrustAllCertsPolicy : ICertificatePolicy {

            public bool CheckValidationResult(

                ServicePoint srvPoint, X509Certificate certificate,

                WebRequest request, int certificateProblem) {

                return true;

            }

        }

    "@

     

     

    ######################################

     

     

    #Add the Solarwinds SDK Snapin

    # Add-PSSnapin SwisSnapin

    Import-Module SwisPowerShell

     

     

     

     

    #Create Crendential Object from the SolarWinds Creds

    $Creds = Get-Credential -Credential ${Credential}

     

     

    #Create SWIS connection object

    $Swis = Connect-Swis ñHostname $SolarWindsServer -Credential $Creds

     

     

    #Invoke the Rest Method, get Incidents

    try{

        $Incidents = Invoke-RestMethod -Method Get -Uri $API_URL -ContentType "application/json" -Headers $headers

    }

    Catch{

        Write-Host "Message: $($Error[0])"

        exit 1;

    }

     

     

    #If there are not current Incidents update stat to 0

    If ($Incidents.incidents.Count -le 0){

        Write-Host "Statistic.TotalIncidents:" 0;

        exit 0;

    }

     

     

    #Check for Incidents

    If($Incidents){

     

     

       #Get Just Acked and Resolved incidents

        $ACKED = @($Incidents.incidents | Where-Object {$_.currentPhase -eq "ACKED"})

        $RESOLVED = @($Incidents.incidents  | Where-Object {$_.currentPhase -eq "RESOLVED"})

        $UNACKED = @($Incidents.incidents  | Where-Object {$_.currentPhase -eq "UNACKED"})

     

     

        #Output TotalIncidents

        Write-Host "Statistic.TotalIncidents: $($Incidents.incidents.Count)"

        Write-Host "Statistic.TotalAcked: $($ACKED.Count)"

        Write-Host "Statistic.TotalResolved: $($RESOLVED.Count)"

     

     

        #Select Unique incidents from ACKED, Resolved, and Unacked State. The same incident can show up in Resolved and Unacked if it is a repeating issue. We don't want to clear the incident in this case.

        $RESOLVED = $RESOLVED | Where-Object {($_.entityId -notin $ACKED.entityId) -and ($_.entityId -notin $UNACKED.entityId)}

        $Incidents = $ACKED + $RESOLVED

     

     

        #Loop through each incident

        ForEach ($Incident in $Incidents){

     

     

            #Set the Incident Values to Variables, its possible victorops could change this in the future

            $AlertTitle = $Incident.entityDisplayName

            $AlertAuthor = $Incident.transitions.by

            $AlertID = $Incident.entityId

            $AlertState = $Incident.CurrentPhase

            $AlertMessage = "$($Incident.transitions.message) | Acked By: $($Incident.transitions.by)"

            $AlertPagedUsers = $Incident.pagedUsers

     

     

            #Output for Debug

            Write-Host " "

            Write-Host "Alert ID: $AlertID"  -ForegroundColor Green

            Write-Host "Alert Title: $AlertTitle"

            Write-Host "Alert Author: $AlertAuthor"

            Write-Host "Alert Acked By: $AlertMessage"

            Write-Host "Alert State: $AlertState"

            Write-Host "Alert Paged Users: $AlertPagedUsers"

     

     

            #Check for a null message value and set to blank

            If(!($AlertMessage)){$AlertMessage = " "}

     

     

            #Define the SQL Query to find the Alert in the Orion.AlertStatus Table

            $Query = "SELECT AlertActiveID, AlertObjectID FROM Orion.AlertActive Where AlertObjectID = $AlertID"

     

     

            #Query the Solarwinds Orion.AlertStatus Table for the Alert.

            try{

                $AlertQuery = Get-SwisData $swis $Query

            }

            catch{Write-Host "$($Error[0])"}

     

     

            #Convert AlertID to an Array of Integers. This is to support the Solarwinds ACK Parameter

            $AlertID = @($AlertID -as [int])

     

     

            #Check for Results

            If($AlertQuery){

     

     

                #Ack the Alert from Solarwinds if Acked

                If($Incident.CurrentPhase -eq "ACKED"){

                    Write-Host "Acking Alert" -ForegroundColor Red

                    #Create and XML String for Acking the Alert in Solarwinds

                    $xmlString = "<ArrayOfint xmlns='http://schemas.microsoft.com/2003/10/Serialization/Arrays'>

                                    <int>$($AlertID)</int>

                                  </ArrayOfint>"

                    $xmlElement = ([xml]$xmlString).DocumentElement

              

                    #Ack Alert

                    Invoke-SwisVerb $swis Orion.AlertActive Acknowledge @( $xmlElement,$AlertMessage)

                }

     

     

                #Clear the Alert from Solarwinds if Resolved

                If($Incident.CurrentPhase -eq "RESOLVED"){

                    Write-Host "Clearing Alert" -ForegroundColor Red

                    #Create and XML String for Acking the Alert in Solarwinds

                    $xmlString = "<ArrayOfint xmlns='http://schemas.microsoft.com/2003/10/Serialization/Arrays'>

                                    <int>$($AlertID)</int>

                                  </ArrayOfint>"

                    $xmlElement = ([xml]$xmlString).DocumentElement

     

     

                    #Clear the Alert

                    Invoke-SwisVerb $swis Orion.AlertActive ClearAlert @( $xmlElement )

                }

            }

        }

    }