4 Replies Latest reply on Jul 18, 2019 11:45 PM by the_ben_keen

    Is there a way to automatically unmanage nodes after they have been down for a time period?


      We have departments that are notorious for ignoring their down nodes.  I have tried sending reports to them weekly to get them to unmange, remove or remediate them, but had little success.  I'd like to get more aggressive with this.  I'd like to have nodes automatically go into an unmanaged state after they have been down for a defined period, and then possible even deleted completely if they remain unmanaged for so long. 


      Any insight on how to do this?

        • Re: Is there a way to automatically unmanage nodes after they have been down for a time period?
          Steven Klassen

          Hey there,


          You could use the API. Just make sure you install the SDK on your system (any system is fine as long as it can reach SolarWinds) and run the script as an AD user that can authenticate in your web console.


          *** Read the script carefully - there are no warranties, etc etc. ***


          #requires -version 3
            UnManage/Delete Stale Nodes
            After a node has been down for X time period, unmanage it; when it's been
            down for Y time period, delete it.
            Requires the SolarWinds SDK found at:
            Author: Steven Klassen <sklassen@loop1.com>
            Creation Date: 01/25/2017
          #-----------------------------[ Configuration ]-------------------------------#
          $version = '0.1'
          $debug = $true  # set to false to quiet debugging
          $testConnection = $false  # set to true to test SolarWinds connection on each run
          # solarwinds particulars
          $hostname = 'your_solarwinds_host'
          # required settings for aging out devices
          $hoursUntilUnmanaged = 24 * 30 # 30 days
          $hoursUntilDeleted = 24 * 60 # 60 days
          $hoursToUnManage = 24 * 30 # 30 days
          # optional custom property settings
          $decommissionedOn = "" # create a Date/Time custom property for unmanage time
          #--------------------------[ Modules/Functions ]------------------------------#
          Function Test-Connection($hostname) {
              try {
                  Get-SwisData $swis "SELECT TOP 1 Caption FROM Orion.Nodes" | Out-Null
              } catch {
                  return $false
              return $true
          Function Set-CustomProperty($uri, $cpName, $cpValue) {
              try {
                  Set-SwisObject $swis -Uri $("{0}/CustomProperties" -f $uri) @{ $cpName = $cpValue } | Out-Null
              catch {
                  Write-Warning "Failed to update custom property [$cpName] for uri [$uri]."
          #--------------------------------[ Execution ]--------------------------------#
          # preference flags
          $ErrorActionPreference = 'Stop'
          if ($debug) {
              $DebugPreference = 'Continue'
          } else {
              $DebugPreference = 'SilentlyContinue'
          Write-Debug "Hostname in use is $hostname..."
          # load the snapin if it's not already loaded
          if (-not (Get-PSSnapin | Where-Object { $_.Name -ceq 'SwisSnapin' })) {
              Add-PSSnapin 'SwisSnapin'
          # create a swis object to target the SolarWinds host
          $swis = Connect-Swis -Hostname $hostname -Trusted
          # test the connection with a small query
          if ($testConnection) {
              $result = Test-Connection $swis
              if ($result -eq $true) {
                  Write-Debug "Connection to SolarWinds server successful..."
              } else {
                  Write-Warning "Could not connect to SolarWinds server - $($_.Exception.Message)"
          # build query to look for devices over X days unresponsive
          # credit to @tdanner for the query (https://thwack.solarwinds.com/message/355081#355081)
          $query = @"
                  ,MAX(rt.Availability) AS MaxAvailability
              FROM Orion.Nodes n
              JOIN Orion.ResponseTime rt ON n.NodeID = rt.NodeID
              WHERE rt.DateTime > ADDHOUR(-@hours, GETUTCDATE())
              GROUP BY n.NodeID, n.Caption, n.Uri, n.UnManaged
              HAVING MAX(rt.Availability) = 0
          # query for devices that need to be unmanaged
          $nodesToUnmanage = Get-SwisData $swis $query @{ hours = $hoursUntilUnmanaged }
          $unManageFrom = (Get-Date).ToUniversalTime()
          $unManageTo = ($unManageFrom).AddHours($hoursToUnManage)
          $nodesToUnmanage | ForEach-Object {
              if ($_.UnManaged -eq "true") {
                  Write-Warning "$($_.Caption) already unmanaged - skipping..."
              Write-Host "Setting $($_.Caption) to unmanaged..."
              Invoke-SwisVerb $swis Orion.Nodes UnManage @("N:$($_.NodeID)", $unManageFrom, $unManageTo, "false") | Out-Null
              # optionally set a decommissioned stamp
              if ($decommissionedOn -ne "") {
                  Write-Host "Setting decommisioned date to $(Get-Date)..."
                  Set-CustomProperty $_.Uri $decommissionedOn (Get-Date)
          # query for the devices that need to be deleted
          $nodesToDelete = Get-SwisData $swis $query @{ hours = $hoursUntilDeleted }
          # CAUTION: Uncomment the following lines only if you're certain that
          #          $nodesToDelete is producing the nodes you intend.
          # $nodesToDelete | ForEach-Object {
          #    Write-Host "Deleting node $($_.Caption)..."
          #    Remove-SwisObject $swis -Uri $_.Uri | Out-Null
          # }
          3 of 3 people found this helpful