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.

Upgrade from NMP 11.0.1 to 11.5 breaks SDK 1.10 set CustomProperties

Hello all,

I want to thank those that released the SDK.  It's a great tool and we've used it extensively.
We have a powershell script, using v1.10.16.0 of the SDK, which we use to add nodes, setup pollers, and set the nodes Custom Properties.  After upgrading Orion Network Performance Monitor from 11.0.1 to 11.5 values for Custom Properties no longer get set.  It's as if the initial node creation seems to no longer create the ground work or index for custom properties to be added/edited.  When we run the script there's no errors generated.
After a node is added via the PS script, if you go in through the WebGUI, and edit the custom properties of the node, save it and go back, the values for those custom properties have reverted back to the origional values.  We are not seeing any issues if a node is manually added via the GUI.  I have a feeling some of the tables have been split and it's almost like the '
Has anyone else run into this issue?
# Basic add node, add n-pollers, set some custom props (p.s. what circle of hell did I enter trying to copy and paste into this form's editor?)
#PSSnapin presence check/add
if (!(Get-PSSnapin -Name "SwisSnapin" -ErrorAction SilentlyContinue))
    { Add-PSSnapin SwisSnapin -ErrorAction SilentlyContinue }
# Default values
[string]$AlertingTier = "SysOps Linux - P1 Very Urgent"
[string]$Access_KCNDataCenter = "No"
[String]$KCNHardwareType = "None"
[string]$ResponsibleGroup = "Server Operations (Linux)"
[string]$Community="public"
[string]$SiteAddressState="MO"
ip2guid($ipString) {
  $ip = [System.Net.IPAddress]::Parse($ipString)
  $src = $ip.GetAddressBytes();
  $data = new-object byte[] 16
  $src.CopyTo($data, $data.Length - $src.Length)
  $dest = new-object byte[] 16
  [Array]::Copy($data, 12, $dest, 0, 4)
  [Array]::Copy($data, 10, $dest, 4, 2)
  [Array]::Copy($data, 8, $dest, 6, 2)
  [Array]::Copy($data, 6, $dest, 8, 2)
  [Array]::Copy($data, 0, $dest, 10, 6)

  return (New-Object Guid (,$dest)).ToString()
}
AddPoller($PollerType) {
  $poller["PollerType"]=$PollerType;
  $pollerUri = New-SwisObject $swis -EntityType "Orion.Pollers" -Properties $poller
}

# Connect to SolarWinds
$SWhost = "cgslpwiswnpm01.centric.com"
$username = "user"
$password = Read-Host -Prompt "Enter password" -AsSecureString
$cred = New-Object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$swis = Connect-Swis -host $SWhost -cred $cred
# For simplicity just putting in a host and IP
# In the script we have steps to verify fqdn and ip
$hostname = 'somehost'
$ip = '10.0.0.1'
$ipGuid = ip2guid($ip)
# add a node
$newNodeProps = @{
  EntityType="Orion.Nodes";
  IPAddress=$ip;
  IPAddressGUID=$ipGuid;
  Caption=$hostname;
  DynamicIP=$False;
  Engine=1;
  Status=1;
  UnManaged=$False;
  Allow64BitCounters=$False;
  SysObjectID="";
  MachineType="";
  VendorIcon="";
  ObjectSubType="SNMP";
  SNMPVersion=2;
  Community=$Community;
}
$newNodeUri = New-SwisObject $swis -EntityType "Orion.Nodes" -Properties $newNodeProps
$nodeProps = Get-SwisObject $swis -Uri $newNodeUri

# register specific pollers for the node
$poller = @{
  NetObject="N:"+$nodeProps["NodeID"];
  NetObjectType="N";
  NetObjectID=$nodeProps["NodeID"];
}
### Create N-type Pollers
AddPoller("N.Status.SNMP.Native");
AddPoller("N.ResponseTime.ICMP.Native");
AddPoller("N.Details.SNMP.Generic");
AddPoller("N.Uptime.SNMP.Generic");
AddPoller("N.Cpu.SNMP.NetSnmpSystemStats");
AddPoller("N.Cpu.SNMP.NetSnmpCpuIdle");
AddPoller("N.Memory.SNMP.NetSnmpReal");
AddPoller("N.IPAddress.ICMP.Generic");

## Prepare a custom property value
$customProps = @{
  AlertingTier=$AlertingTier;
  ResponsibleGroup=$ResponsibleGroup;
  KCNHardwareType=$KCNHardwareType;
  SiteAddressState=$SiteAddressState;
  Comments="Host added by script";

## Build the Custom Properties node URI
$SWNodeURICP = "$newNodeUri/CustomProperties"
## Set Custom Properties
Set-SwisObject $swis -Uri $SWNodeURICP -Properties $customProps



  • Hello, unfortunately you really hit the bug, related to the splitting of the Nodes table and we really apologize for that.

    Problem is, that the CRUD action doesn't create the record in the NodesCustomProperties fragment. However here is the workaround how to fix it (until we fix that in the product). Put following lines before the line, where you set the Custom properties values:

    [System.String]$sqlCommand=("Insert into NodesCustomProperties (NodeID) VALUES (" + $nodeProps.nodeid + ")")

    Invoke-SwisVerb $swis "Orion.Reporting" "ExecuteSQL" $sqlCommand |Out-Null

    This should create the correct record, which allows you then to set the Custom Property values.

    Btw. here are few things I found during execution of your script. This may potentialy cause troubles in future (and some really made troubles to me, maybe because of different PowerShell version), so it may worth to correct that to avoid those troubles:

    1. Function declarations don't start with keyword "function", (for ip2guid and AddPoller functions)

    2. Missing } bracket after " Comments="Host added by script";"

    3. Node propertybag $newNodeProps contains "Engine" instead of the EngineID

    I hope it helps.

    Regards,

    Honza

  • I did not realize we could execute raw SQL from SWQL.  THANKS A MILLION for revealing this functionality.  Nowhere in the documentation does it tell us about this.

    This helps me tremendously and I don't have to install a Database drivers now everywhere I want to access custom tables we have created.

  • Well it's a bit hidden functionality (as not much advanced users may damage their database), internally used by the Web based reporting, however requires the admin rights for the user to execute. I'm glad it helps you in future. The verb is able to execute non-query as well as query commands. In case of query the verb returns the results in XML structure.

    H.

  • I'm glad you find it helpful. But I do need to caution you that this does not mean we can support whatever-you-use-this-for in general. It's undocumented for a reason - our database schema may change from version to version. I recommend you plan on removing this workaround once we publish a proper fix for this custom property bug. I'll post in this forum when that happens.

  • Jan,

    Thank you for this workaround.  I work with Centric-jim and the work around you provided worked for the WMI windows boxes I am monitoring (centric-jim is still testing in the Linux world), but now I have an issue with adding volumes that previously was not there.  Should this code still work or did something else change in the database to prevent this code from executing properly?  After execution, I am not seeing any new rows in the Orion.Volumes table through the swql editor. Thank you for any help you can offer.

    #we should be passing $poller to make the function prettier, but it still works

    function AddPoller($PollerType)

    {

        $poller["PollerType"]=$PollerType;

        $pollerUri = New-SwisObject $swis -EntityType "Orion.Pollers" -Properties $poller

    }

    $volumes = "C:\"

    #this is ran inside a larger loop where $SWnodeID has already been found.

                        foreach ($vol in $volumes)

                        {

                        #This checks for the existence of the C: and M: Drives assigned to the solarwinds node

                        $SWNodeVolCheck = Get-SwisData -SwisConnection $swis -Query "SELECT NodeID, Caption FROM Orion.Volumes WHERE Caption = '$($vol)' AND NodeID = '$($SWNodeID)'"

                    

                        If ($SWNodeVolCheck -eq $null)

                            {

                            #Volume was not found, create new volume for current node

                            #$VolAction = "Add $Vol"

                           

                            $newVolumeProps = @{

                                NodeID=$SWNodeID;

                                VolumeType="Fixed Disk";

                                VolumeSize="0";

                                Icon="FixedDisk.gif";

                                Index="3";

                                Caption=$vol;

                                VolumeDescription=$vol;

                                PollInterval="120";

                                StatCollection="10";

                                RediscoveryInterval="20";

                                StatusIcon="Up.gif";

                                FullName=$vol;

                                Responding="";

                                VolumePercentUsed="";

                                VolumeAllocationFailuresThisHour="";

                                VolumeSpaceUsed="";

                                VolumeAllocationFailuresToday="";

                                VolumeSpaceAvailable="";

                                DiskQueueLength="";

                                DiskTransfer="";

                                DiskReads="";

                                DiskWrites="";

                                TotalDiskIOPS="";

                                }

                            $newVolumeURI = New-SwisObject $swis –EntityType "Orion.Volumes" –Properties $newVolumeProps

                            $VolProps = Get-SwisObject $swis -Uri $newVolumeURI

                            foreach ($pollerType in @('V.Status.WMI.Windows','V.Details.WMI.Windows','V.Statistics.WMI.Windows'))

                                {

                                $poller = @{

                                    PollerType=$pollerType;

                                    NetObject="V:"+$VolProps["VolumeID"];

                                    NetObjectType="V";

                                    NetObjectID=$VolProps["VolumeID"];

                                    }

       

                                AddPoller $pollerType;

                                }

                           

                            }

                        }

  • That should still work. Are you getting any errors from these commands? It would be very strange for "New-SwisObject Orion.Volumes" to "succeed" but not have actually created the record.

  • @tdanner I realize this, and I actually take the upgrade scenarios into my design.  That is why I create custom Views and create my SQL based off of the views rather than the tables.  Then if the schema changes all I have to do is update my View.

    How do I do the call using REST I have the Invoke portions?  I just need to know if I need to know which values I can make fixed and which to be possibly variable.

    What should the payload look like:

    my $payload = {

                              sqlQueryText => $sql,

                              sqlQueryParameters =>  ???????,

                              outputRowsMaxCount => ??????,

                              schemaOnly => ??????,

                        };

       my $entityName = "Orion.Reporting";

       my $verbName = "ExecuteSQL";

       $self->invoke($entityName, $verbName, $payload) = @_;

  • ERROR: New-SwisObject : Unable to create Volume. Details : Information : Assigned default value '3/12/2015 1:49:41 PM' for NextPoll.

    ERROR: Information : Assigned default value '3/12/2015 2:07:41 PM' for NextRediscovery.

    ERROR: Error : In property VolumeSpaceAvailable. Reason : Unable to convert '' to System.Double.

    ERROR: Information : Assigned default value '0' for Status or StatusDescription.

    ERROR: Information : Assigned default value '' for DeviceId.

    ERROR:

    ERROR: ----------------------------------

    updatetest.ps1 (418): ERROR: At Line: 418 char: 41

    ERROR: +                        $newVolumeURI = New-SwisObject $swis –EntityType "Orion. ...

    ERROR: +                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ERROR:    + CategoryInfo          : InvalidOperation: (:) [New-SwisObject], FaultException`1

    ERROR:    + FullyQualifiedErrorId : SwisError,SwisPowerShell.NewSwisObject

    It helps if you read the full error code emoticons_blush.png.  It looks like you can no longer use empty string for VolumeSpaceAvailable.  so I commented it out and the information was passed into the database.  If this is not an appropriate method, please let me know what I should pass.  I currently see the drive in the vital stats page.  thank you for your help.

  • That's a good fix. This property validation is new in the 2015.1 version of the platform. (Thanks, madhavan!)

    You can now leave out all of those default values in your script (where you used to have to provide empty string for a lot of properties) and the property validation will fill them in.

  • The only required parameter is the sql query, as a string. You can omit the rest.