cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamic IP Polling, Interface Discovery, and Alert Suppression Management Examples - PowerShell

Dynamic IP Polling, Interface Discovery, and Alert Suppression Management Examples - PowerShell

so, before our cloud team migrates things to GCP we have to flip our nodes to Dynamic IP polling, update DNS, and mute alerts; then after the migration we have to remove the existing (legacy) interfaces, discover and add new ones, and make sure alert suppression is removed.

in the website, this can take something like 5 minutes per node; we have > 8,000 servers.

enter PowerShell, stage left. the cloud team provides us with a csv of server names and verified DNS entries, and the magic of the API does everything else.

The Pre-Migration Script:

#region Top of Script

#requires -version 2
<#
.SYNOPSIS
    Transitions nodes from standard to Dynamic IP Polling and Schedule Alert Suppression

.DESCRIPTION
    https://github.com/solarwinds/OrionSDK/wiki/PowerShell

.NOTES
    Version:        1.0
    Author:         Zack Mutchler
    Creation Date:  August 3, 2018
    Purpose/Change: Initial Script development. 
#>

#endregion

#####-----------------------------------------------------------------------------------------#####

#region Pre-Work

# Start the transcript
$transcript = Read-Host "Where do you want to save the logfile?"
Start-Transcript -Path $transcript -Force -Append

# Start the timer
$stopWatch = [ System.Diagnostics.Stopwatch ]:Smiley FrustratedtartNew()

#endregion Pre-Work

#####-----------------------------------------------------------------------------------------#####

#region Functions

# Create a function to connect to the SolarWinds Information Service (SWIS)
Function Set-SwisConnection {
   
    Param(
        [Parameter( Mandatory = $true, HelpMessage = "What SolarWinds server are you connecting to (Hostname or IP)?" ) ] [string ] $SolarWindsServer,
        [Parameter( Mandatory = $true, HelpMessage = "Do you want to use the credentials from PowerShell (Trusted), or a new login (Explicit)?" ) ] [ ValidateSet( 'Trusted', 'Explicit' ) ] [string ] $ConnectionType
    )

    # Import the SolarWinds PowerShell Module
    Import-Module SwisPowerShell

    # Connect to SWIS
    IF ( $ConnectionType -eq 'Trusted'  ) {

        $swis = Connect-Swis -Trusted -Hostname $SolarWindsServer
   
    }

    ELSE {
   
        $creds = Get-Credential -Message "Please provide a Domain or Local Login for SolarWinds"

        $swis = Connect-Swis -Credential $creds -Hostname $SolarWindsServer

    }

RETURN $swis

}

#endregion Functions

#####-----------------------------------------------------------------------------------------#####

#region Variables

# Set the target for SWIS
$hostname = Read-Host "What is the hostname of the SolarWinds server you want to connect to?"

# Create a SwisConnection
$swis = Set-SwisConnection -SolarWindsServer $hostname -ConnectionType Trusted

# Grab the source data
$sourceCSV = Read-Host 'Where is the source CSV file?'
$nodes = Import-Csv -Path $sourceCSV

# Set the Alert Suppression start time
$suppressTime = Read-Host "What is the DateTime to start alert suppression? MM/DD/YY HH:MM"
$suppressTime = $suppressTime -as [ DateTime ]

If( !( $suppressTime ) ) {

    Throw "You entered an invalid date. Please start over and use the MM/DD/YY HH:MM format."

}

#endregion Variables

#####-----------------------------------------------------------------------------------------#####

#region Execution

# Iterate through the source data and match to existing SW Nodes and update/suppress
Foreach( $n in $nodes ) {

    $server = $n.server
    $dns = $n.dns
    $query = "SELECT uri FROM Orion.Nodes WHERE Caption = @s"

    $uri = Get-SwisData -SwisConnection $swis -Query $query -Parameters @{ s = $server }

    If( !( $uri ) ) {

        Write-Host "Server Not Found: $( $server )" -ForegroundColor Yellow

    }

    Else {
   
        Write-Host "$( $server )`n`tDNS: $( $dns )`n`tURI: $( $uri )"

        Try {
           
            Set-SwisObject -SwisConnection $swis -Uri $uri -Properties @{ DNS = $dns; DynamicIP = $true } | Out-Null

            Invoke-SwisVerb -SwisConnection $swis -EntityName Orion.AlertSuppression -Verb SuppressAlerts -Arguments @( $uri, $suppressTime ) | Out-Null

            Write-Host "$( $server ) has been updated to DynamicIP polling and alerts will be muted at $( $suppressTime )" -ForegroundColor Green

        }

        Catch {

            $errorMessage = $_.Exception.Message

            Write-Host "$( $errorMessage )" -ForegroundColor Red

        }
               
    }

}

# Stop the clock and show us how long this took
$stopWatch.Stop()

Write-Host "SCRIPT DURATION:`n  HOURS: $( $stopWatch.Elapsed.Hours )`n  MINUTES: $( $stopWatch.Elapsed.Minutes )`n  SECONDS: $( $stopWatch.Elapsed.Seconds )"

#Stop the transcript recording
Stop-Transcript

#endregion Execution

The Post-Migration Script:

#region Top of Script

#requires -version 2
<#
.SYNOPSIS
    Removes old interfaces, adds new, and removes alert suppression

.DESCRIPTION
    https://github.com/solarwinds/OrionSDK/wiki/PowerShell

.NOTES
    Version:        1.0
    Author:         Zack Mutchler
    Creation Date:  August 3, 2018
    Purpose/Change: Initial Script development. 
#>

#endregion

#####-----------------------------------------------------------------------------------------#####

#region Pre-Work

# Start the transcript
$transcript = Read-Host "Where do you want to save the logfile?"
Start-Transcript -Path $transcript -Force -Append

# Start the timer
$stopWatch = [ System.Diagnostics.Stopwatch ]:Smiley FrustratedtartNew()

#endregion Pre-Work

#####-----------------------------------------------------------------------------------------#####

#region Functions

# Create a function to connect to the SolarWinds Information Service (SWIS)
Function Set-SwisConnection {
   
    Param(
        [Parameter( Mandatory = $true, HelpMessage = "What SolarWinds server are you connecting to (Hostname or IP)?" ) ] [string ] $SolarWindsServer,
        [Parameter( Mandatory = $true, HelpMessage = "Do you want to use the credentials from PowerShell (Trusted), or a new login (Explicit)?" ) ] [ ValidateSet( 'Trusted', 'Explicit' ) ] [string ] $ConnectionType
    )

    # Import the SolarWinds PowerShell Module
    Import-Module SwisPowerShell

    # Connect to SWIS
    IF ( $ConnectionType -eq 'Trusted'  ) {

        $swis = Connect-Swis -Trusted -Hostname $SolarWindsServer
   
    }

    ELSE {
   
        $creds = Get-Credential -Message "Please provide a Domain or Local Login for SolarWinds"

        $swis = Connect-Swis -Credential $creds -Hostname $SolarWindsServer

    }

RETURN $swis

}

#endregion Functions

#####-----------------------------------------------------------------------------------------#####

#region Variables

# Set the target for SWIS
$hostname = Read-Host "What is the hostname of the SolarWinds server you want to connect to?"

# Create a SwisConnection
$swis = Set-SwisConnection -SolarWindsServer $hostname -ConnectionType Trusted

# Grab the source data
$sourceCSV = Read-Host 'Where is the source CSV file?'
$nodes = Import-Csv -Path $sourceCSV

# Create a string to use in our nodes query
$captions = "'$( $nodes.server -join "','" )'"

#endregion Variables

#####-----------------------------------------------------------------------------------------#####

#region Execution

# Create the query to evaluate nodes on
$nodesQuery = "SELECT NodeID, Caption, ObjectSubType, Uri FROM Orion.Nodes WHERE Caption IN ( $( $captions ) )"

$nodesResults = Get-SwisData -SwisConnection $swis -Query $nodesQuery

# List the servers that were not found in SolarWinds
$missing = Compare-Object -ReferenceObject $nodes.server -DifferenceObject $nodesResults.Caption

Foreach($m in $missing.InputObject ) {

    Write-Host "$m was not found in SolarWinds" -ForegroundColor Red

}

# Evaluate the ones found, delete current interfaces, and remove alert suppression
Foreach( $n in $nodesResults ) {

        $nodeID = $n.NodeID
        $nodeName = $n.Caption
        $pollingMethod = $n.ObjectSubType
        $nodeURI = $n.Uri

        # Remove alert suppression on all nodes
        Invoke-SwisVerb -SwisConnection $swis -EntityName Orion.AlertSuppression -Verb ResumeAlerts -Arguments @( , [ string [] ] $nodeURI ) -ErrorAction SilentlyContinue | Out-Null

        Write-Host "Alert Suppression on $( $nodeName ) has been removed" -ForegroundColor Green

        If( $pollingMethod -ne 'SNMP' ) {

            Write-Host "$( $nodeName ) uses $( $pollingMethod ) - Manually List Resources in Web Console" -ForegroundColor Magenta

        }

        Else {

            # Query for Interface Details
            $intQuery = "SELECT Caption, Uri FROM Orion.NPM.Interfaces WHERE NodeID = $( $nodeID )"
            $intResults = Get-SwisData -SwisConnection $swis -Query $intQuery

            # Remove the Interfaces
            Foreach( $i in $intResults ) {

            $interfaceName = $i.Caption
            $interfaceURI = $i.Uri

            Remove-SwisObject -SwisConnection $swis -Uri $interfaceURI -ErrorAction SilentlyContinue | Out-Null

            Write-Host "Removed $( $interfaceName ) from $( $nodeName )" -ForegroundColor Yellow
           
            }
           
        # Discover interfaces on the nodes
        $discInt = Invoke-SwisVerb $swis -EntityName Orion.NPM.Interfaces -Verb DiscoverInterfacesOnNode -Arguments $nodeID -ErrorAction SilentlyContinue

        # Check if discovery worked
        If( $discInt.Result -ne "Succeed" ) {
   
            Write-Host "Interface Discovery Failed on $( $nodeName ) - $( $discInt.Result )" -ForegroundColor Magenta

        }

        Else {
   
            $discInt.DiscoveredInterfaces.DiscoveredLiteInterface | ?{ ( $_.Caption.InnerText -like '*Filter*' -or $_.Caption.InnerText -like '*Scheduler*' -or $_.Caption.InnerText -like '*Loopback*' -or $_.Caption.InnerText -like '*Debug*' -or $_.ifOperStatus -ne 4 ) } | %{ $discInt.DiscoveredInterfaces.RemoveChild($_)  } | Out-Null

            # Add the remaining interfaces
            Invoke-SwisVerb $swis -EntityName Orion.NPM.Interfaces -Verb AddInterfacesOnNode -Arguments @( $nodeID, $discInt.DiscoveredInterfaces, "AddDefaultPollers" ) | Out-Null

            Write-Host "Interface(s) added on $( $nodeName ): $( $discInt.DiscoveredInterfaces.InnerText )" -ForegroundColor Green

        }                      

    }

}

#endregion Execution

#####-----------------------------------------------------------------------------------------#####

#region Cleanup

# Stop the clock and show us how long this took
$stopWatch.Stop()

Write-Host "SCRIPT DURATION:`n  HOURS: $( $stopWatch.Elapsed.Hours )`n  MINUTES: $( $stopWatch.Elapsed.Minutes )`n  SECONDS: $( $stopWatch.Elapsed.Seconds )"

#Stop the transcript recording
Stop-Transcript

#endregion Cleanup

Note that the Interface Discovery only works for SNMP nodes right now. Luckily that's the majority of ours. For WMI and Agent nodes, we will run Sonar Discovery jobs in the website and add the new interfaces.

These scripts work for us in our environment for the tasks we have, but are being shared to ignite new ideas for what you could do in your own worlds. Enjoy.

Version history
Revision #:
1 of 1
Last update:
‎08-03-2018 04:35 PM
Updated by:
 
Contributors