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.

Full Orion alert rule export using Powershell and OrionSDK

Orion does not yet have a way to perform a complete bulk export (full backup) of all alert rules from the web console UI.

So as of today, the only option is to use the OrionSDK.

There are several use cases on why an Orion admin might need to perform a complete alert rule export.

1. When migrating from one Orion instance to another.

2. Alert rule synchronization between multiple Orion instances.

3. Backup.

Provided below is a Windows Powershell script that will export every ENABLED alert rule from an Orion instance.

Each alert rule will be exported to individual XML files using the <ALERT NAME>-ID-<ALERT ID>.xml naming convention.

# --- ORION-ALERT-BACKUP.ps1
# --- Author: Joseph Dissmeyer, www.dissmeyer.com
# --- Last updated: 2020-01-15
# --- Reference: thwack.solarwinds.com/.../433199
# ---
# --- Save as .ps1 file in your scripts directory.
# ---
# --- How it works:
# --- Downloads all enabled alert rules from an Orion instance.
# --- Each rule is saved individually as .XML file to the same directory
# --- where the script is executed from.
# --- NOTE: This only exports alert rules that are currently ENABLED.

# Requirements:
# 1. OrionSDK. Download binaries from github.com/.../OrionSDK
# 2. An Orion basic user that has "Alert management rights" enabled.
# 3. Edit the hostname, username and password.
 
# Verify OrionSDK SwisSnapin presence 
if (!(Get-PSSnapin -Name "SwisSnapin" -ErrorAction SilentlyContinue))
{       
    Add-PSSnapin SwisSnapin -ErrorAction SilentlyContinue   
}     
 
# Define Variables 
$swis = Connect-Swis -Hostname my-orion-host.domain.com -Username alertbackup -Password My_Bogu$_P@55w01d
 
# Get all AlertIds, add to array
$AlertList = Get-SwisData $swis "SELECT AlertId FROM Orion.AlertConfigurations WHERE Enabled = True" 
$AlertIds = $AlertList -split ' ' 

# Iterate through the Alertids array, back up each rule found
foreach($alertid in $AlertIds){ 
  $alerttitle = Get-SwisData $swis "SELECT Name FROM Orion.AlertConfigurations WHERE AlertId = $alertid" 
 
  # remove all possible 'special characters' from the alert title
  $alerttitle = $alerttitle -replace '(#|\||"|,|/|:|\<|\>|\[|\]|%|$|@|â|€|Tm|\?)', '' 
  # remove all spaces from the alert title, replace with underscore
  $alerttitle = $alerttitle -replace '\s','_' 
 
  $filename = "$alerttitle-ID-$alertid.xml" 
   
  Set-Content $filename $ExportedAlert.InnerText 
  $ExportedAlert = Invoke-SwisVerb $swis Orion.AlertConfigurations Export @($alertid)
}

# End script

I currently have this running as a scheduled task to backup all active alert rules daily, then commit changes to a git repository.

You may need to modify this PS script for your own environment.

This script has been tested on:

Windows 10 workstation

Windows Server 2012 R2

Windows Server 2016

  • To make things more secure one trick you can do is to change line 26 like so

    $swis = Connect-Swis -Hostname my-orion-host.domain.com -Username alertbackup -Password My_Bogu$_P@55w01d 

    becomes

    $swis = Connect-Swis -Hostname my-orion-host.domain.com -Trusted

    Then you just set up your scheduled task to run under any Windows account that has permission to access Orion, that way you don't need to hard code or store credentials and can just rely on built in Windows security.  It's been a project of mine over the past year or two to always try to find ways to keep my scripts more secure.  Its deadly how many repos have hard coded creds and system names and such sitting in them that people forgot to clean up.

  • This is an excellent point! Thank you for sharing this tip and good advice. I'll update in a bit...

  • This worked gorgeously! Thanks for writing it. I don't suppose you have an import version of this? I've got 375 custom alerts to bring into a new deployment and would prefer not to do so one by one.

  • No I don't have an import script at this time. However I do understand the need to have one. I have around the same amount of alert rules (we have a very large NPM/SAM deployment).

    There is an "import" function as documented in the OrionSDK wiki here: Alerts · solarwinds/OrionSDK Wiki · GitHub

    I wouldn't expect it taking long to figure out how to do this. I'm thinking you just need to replace the logic in the foreach loop to look at each backup file on disk (i.e. each saved alert XML file) then use the import function.

    The key is line 33 in the script. Instead of

    `$ExportedAlert = Invoke-SwisVerb $swis Orion.AlertConfigurations Export @($alertid)`

    you would use something like this...

    `$ExportedAlert = Invoke-SwisVerb $swis Orion.AlertConfigurations Import @($alertid)`

    I don't have time to test out an import script right now but this should be more than enough to get you started.

  • I've used this bit, for example, to sync up alerts between instances.  Pretty painless.

    # get Alert IDs for enabled alerts

    $AlertIDs = Get-SwisData -SwisConnection $swissource -Query "SELECT AlertID FROM Orion.AlertConfigurations WHERE Enabled = 'true' and name not like '%syslog%'"

    # migrate the alerts

    foreach ($AlertID in $AlertIDs) {

    $AlertName = Get-SwisData -SwisConnection $swissource -Query "SELECT Name FROM Orion.AlertConfigurations WHERE AlertID = $AlertID"

    $Existing = Get-SwisData -SwisConnection $swisdest "select name from orion.alertconfigurations where name = '$AlertName'"

        if ($existing.count -eq 0) {

                    write-output "Migrating alert named: $AlertName"

                    $ExportedAlert = Invoke-SwisVerb $swissource Orion.AlertConfigurations Export $AlertID

                    Invoke-SwisVerb $swisdest Orion.AlertConfigurations Import $ExportedAlert

        }

        else { "Alert named: $AlertName already exists, skipping" }

        }




  • This is so cool - thank you.

    Whilst I am far from being able to create something like this, I am at last, beginning to understand the guts of PowerShell scripts and see what they are trying to do.

    One question:

    1. Is it possible (I'm going to presume yes) to have the xml files exported to a specific or specified location? I ask, as I created this script in our setup and it ran and stored all the XML's in the '\windows\system32' folder. So how can I adjust it to select a location please?

    EDIT: I see why (doh) the script placed the files in \windows\system32 because that's where I ran it from. Still, I would like to be able to specifiy the storage location. Thank you.

  •  

    #Question, how is the initial connection set up for your script? Do I have the source and destination backwards? 

    # Verify OrionSDK SwisSnapin presence
    if (!(Get-PSSnapin -Name "SwisSnapin" -ErrorAction SilentlyContinue))
    {
    Add-PSSnapin SwisSnapin -ErrorAction SilentlyContinue
    }

    # Define Variables
    $swissource = Connect-Swis -Hostname HostThatHasTheExistingAlerts -Username bobmarley -Password IrieMun
    $swisdest = Connect-Swis -Hostname HostIwantToCopyAlertsTo -Username bobmarley -Password IrieMun

    #####The rest of the script

    # get Alert IDs for enabled alerts
    $AlertIDs = Get-SwisData -SwisConnection $swissource -Query "SELECT AlertID FROM Orion.AlertConfigurations WHERE Enabled = 'true' and name not like '%syslog%'"

    # migrate the alerts
    foreach ($AlertID in $AlertIDs) {
    $AlertName = Get-SwisData -SwisConnection $swissource -Query "SELECT Name FROM Orion.AlertConfigurations WHERE AlertID = $AlertID"

    $Existing = Get-SwisData -SwisConnection $swisdest "select name from orion.alertconfigurations where name = '$AlertName'"
    if ($existing.count -eq 0) {
    write-output "Migrating alert named: $AlertName"
    $ExportedAlert = Invoke-SwisVerb $swissource Orion.AlertConfigurations Export $AlertID
    Invoke-SwisVerb $swisdest Orion.AlertConfigurations Import $ExportedAlert
    }
    else { "Alert named: $AlertName already exists, skipping" }
    }

  • Yeah that looks to be about right to me, did you have any trouble with it?

  • Thanks for posting, this script worked fantastic. I changed one line so it would save the files in a specific directory using this 

    $filename = "C:\PowershellScripts\BackupAlerts\$alerttitle-ID-$alertid.xml"

  •   Set-Content $filename $ExportedAlert.InnerText 
      $ExportedAlert = Invoke-SwisVerb $swis Orion.AlertConfigurations Export @($alertid)

    These two lines are inverted