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.

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?

  • 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 <>

      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 (

    $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

    # }