14 Replies Latest reply on Aug 1, 2016 2:34 PM by xtraspecialj

    AppInsight for IIS assing to node API

    guilhermehoescher

      Associating a AppInsight for IIS to a node using API. I tried to use Orion.APM.Application.CreateApplication and Orion.APM.IIS.Application.CreateApplication and did not work

        • Re: AppInsight for IIS assing to node API
          bluefunelemental

          Does this fall under the discoverapplications like windows scheduled tasks or AppInsight for SQL?

          • Re: AppInsight for IIS assing to node API
            sstark85

            I was able to reverse engineer this from watching the web requests when adding the AppInsight IIS application template via the web console. I am essentially making the same web requests as you would when adding this via the web console, minus a few.

             

            This is by no means a supported method by SolarWinds. Please proceed with caution. If you don't understand powershell or can't easily figure out what the script is performing I would suggest not proceeding.

             

            I can say that I have used the below script to successfully add the AppInsight for IIS application template to 150 + nodes. You will need to tweak the script a bit to loop through multiple servers. I intentionally left this ability out.

             

            Make sure you set the initial variables under the Global Variables section.

             

            # Assigns the AppInsight IIS Application Monitor with powershell
            # 
            #    Reveresed enginenered from web requests being made when assigning
            #    a template throught the webconsole
            #
            #    There are 6 main steps to assigning the AppInsight for IIS application template
            # 
            
            
            #**************** Global Variables ################
            
            
            #Credentials for Accessing the Web Console
            $Creds = Get-Credential
            
            
            #SolarWinds Server Name
            $SWServerName = "solarwinds server"
            
            
            #SQL Server Name
            $SQLServer = "sql server"
            
            
            #SQL Database Name
            $SQLDatabase = "solarwinds database name"
            
            
            #Template Name
            $TemplateName = "AppInsight for IIS"
            
            
            #Node Name to add the AppInsight to
            $ServerName = "name of server"
            
            
            Write-Host " #**************** Step 1 - Connect to SWIS get Node Information ######" -ForegroundColor Yellow
            
            
            #Add the Solarwinds SDK Snapin
            Add-PSSnapin SwisSnapin
            
            
            #Create SWIS connection object
            $Swis = Connect-Swis –Hostname $SWServerName -UserName " " -Password " " -IgnoreSslErrors
            
            
            #Get Node Information from swis
            $NodeInfo = Get-SwisData $swis "SELECT NodeID, IPAddress FROM Orion.Nodes WHERE Caption = '$ServerName'" 
            If ($NodeInfo) {
                #Set some variables for later use
                $NodeIP = $NodeInfo.IPAddress
                $NodeID = $NodeInfo.NodeID
                
                #Get the Application Template ID
                $applicationTemplateId = Get-SwisData $swis "SELECT ApplicationTemplateID FROM Orion.APM.ApplicationTemplate WHERE Name = '$TemplateName' "
                
                #Set the Crendtial ID (-3 for Inherit from node... I think)
                $credentialSetId = "-3"
                
                Write-Host "#**************** Step 2 - Check IIS Version for compatability ######" -ForegroundColor Yellow
                
                #Get the server version from web request, assuming port 80 or 443 for the request
                $IISVersion = Invoke-WebRequest "http://$NodeIP"
                
                If ($IISVersion.Headers.Server){
                    $IISVersion = $IISVersion.Headers.Server.split("/")[1]
                }
                Else{
                    $IISVersion = Invoke-WebRequest "https://$NodeIP"
                    If ($IISVersion.Headers.Server){
                       $IISVersion = $IISVersion.Headers.Server.split("/")[1]
                    }
                }
                
                #If the IISVersion has Results Supported Continue
                If ($IISVersion){
                
                    #Set the Body
                    $Body = "{'iisVersion':$IISVersion}" 
                    
                    #Invoke the web request
                    $Results = Invoke-WebRequest -Credential $creds "https://$SWServerName/Orion/APM/IisBlackBox/Services/IisServerConfiguratorServices.asmx/CheckIisVersion" -ContentType "application/json" -Method POST -Body $Body -Verbose
                    
                    #Check the results
                    If ($Results.Content.Contains('"IsVersionSuppoted":true')){
                    
                        Write-Host "#**************** Step 3 - Setup Application -- Configure WinRM, Setup IIS ######" -ForegroundColor Yellow
                        
                        #An Example of what the actual body request looks like
                        #  '{"nodeName":"192.168.76.7","nodeIp":"192.168.76.7","nodeId":2278,"cred":{"Id":"-3","Name":"","UserName":"","Password":""},"useAgent":true}'
                        
                        #Set the Body
                        $Body = '{"nodeName":"' + $NodeIP + '","nodeIp":"' + $NodeIP + '","nodeId":' + $NodeID + ',"cred":{"Id":"-3","Name":"","UserName":"","Password":""},"useAgent":true}'
                        $Body
                        #Invoke the web request
                        $Results = Invoke-WebRequest -Credential $creds "https://$SWServerName/Orion/APM/IisBlackBox/Services/IisServerConfiguratorServices.asmx/SetupApplication" -ContentType "application/json" -Method POST -Body $Body -Verbose
                        Write-Host "Results: " $Results.Content -ForegroundColor Green
                        
                        #Check the results
                        If ($Results){
            
            
                            Write-Host "#**************** Step 4 - Assign the application template to the node ######" -ForegroundColor Yellow
                            
                            $applicationId = (Invoke-SwisVerb $swis "Orion.APM.Application" "CreateApplication" @(
                                # Node ID
                                $nodeId,
                                
                            # Application Template ID
                                $applicationTemplateId,
                                
                            # Credential Set ID
                                $credentialSetId,
                           
                            # Skip if duplicate (in lowercase)
                                "true"
                            )).InnerText
                            
                            Write-Host "#**************** Step 5 - Get Setup Application Status ######" -ForegroundColor Yellow
                            
                            #An Example of what the actual body request looks like
                            #  '{"executeKey":"solarwinds.apm.remoteiisconfiguratorfull.exe-192.168.76.7","appId":2886}'
                            
                            #Set the Body
                            $Body = '{"executeKey":"solarwinds.apm.remoteiisconfiguratorfull.exe-' + $NodeIP + '","appId":' + $applicationId + '}'
                            
                            #Set Count
                            $N = 0
                            
                            Do {
                                #Invoke the web request
                                $Results = Invoke-WebRequest -Credential $creds "https://$SWServerName/Orion/APM/IisBlackBox/Services/IisServerConfiguratorServices.asmx/GetSetupApplicationStatus" -ContentType "application/json" -Method POST -Body $Body -Verbose
                                
                                Start-Sleep -Seconds 5
                                
                                $N += 1
                            
                                Write-Host "Results $N : " $Results.Content -ForegroundColor Green
                            
                            } Until ($Results.Content.Contains('"ExitCode":0') -or $N -ge 20)
                            
                            Write-Host "#**************** Step 6 - Test IIS BlackBox Connection ######" -ForegroundColor Yellow
                            
                            #An Example of what the actual body request looks like
                            #'{"settings":{"NodeId":2278,"AppType":"ABIA","CredentialSet":{"Id":"-3","Login":"","Password":""},"CustomSettings":{"PsUrlWindows":"https://${IP}:5986/wsman/"},"Use64Bit":true,"ExecutePollingMethod":"Agent"}}'
                            
                            #Set the Body
                            $Body = '{"settings":{"NodeId":' + $NodeID + ',"AppType":"ABIA","CredentialSet":{"Id":"-3","Login":"","Password":""},"CustomSettings":{"PsUrlWindows":"https://' + $NodeIP + ':5986/wsman/"},"Use64Bit":true,"ExecutePollingMethod":"Agent"}}'
                            
                            #Invoke the web request
                            $Results = Invoke-WebRequest -Credential $creds "https://$SWServerName/Orion/APM/IisBlackBox/Services/TestConnectionServices.asmx/TestIisBlackBoxConnection" -ContentType "application/json" -Method POST -Body $Body -Verbose
                            Write-Host "Results: " $Results.Content -ForegroundColor Green
                            
                            If ($Results){
                            
                                Write-Host "#**************** Step 7 - Add Database Entry and Poll the application" -ForegroundColor Yellow
                                
                                $DateTime = (Get-Date).AddMinutes(2).ToString('M/dd/yyyy H:mm tt')
                                
                                #Create a Database Entry for the new Application
                                $conn = New-Object System.Data.SqlClient.SqlConnection
                                $conn.ConnectionString = "Data Source=$SQLServer;Initial Catalog=$SQLDatabase;Integrated Security=SSPI;"
                                $conn.Open()
                                $cmd = New-Object System.Data.SqlClient.SqlCommand
                                $cmd.connection = $conn
                                
                                #Insert the new ApplicationID Into the Database
                                $cmd.CommandText = "Insert into [dbo].[APM_IisBb_Application](ApplicationID, AdditionalJobStatus, AdditionalJobTimeStamp)
                                                    Values ('$applicationId','1','$DateTime')"
                                $cmd.executenonquery()
                                
                                #Update the Application Name to Microsoft IIS
                                $cmd.CommandText = "UPDATE [dbo].[APM_Application] SET Name = 'Microsoft IIS' WHERE ID = $applicationId"
                                $cmd.executenonquery()
                                
                                #Clost the SQL Connection
                                $conn.close()
                                
                                #Poll the Application
                                Invoke-SwisVerb $swis "Orion.APM.IIS.Application" "PollNow" $applicationId
                            }
                            Else{
                                Write-Host "Issue Invoking Web Request" -ForegroundColor Red
                            
                                #Delete the Application if fails
                                Invoke-SwisVerb $swis "Orion.APM.Application" "DeleteApplication" $applicationId
                            }
                        }
                    }
                }
            }
            
              • Re: AppInsight for IIS assing to node API
                xtraspecialj

                Very awesome sstark85!!  This is exactly what I was looking for.  I've got almost 200 Nodes that need AppInsight for IIS assigned to them and configuring them seemed like a daunting task.  As I'm imbedding your code into a foreach loop and making it work for our environment, I've come across a few things I have questions about:

                 

                1): Is line 86 purposely misspelled, or is this just a typo: "IsVersionSuppoted":true'"  Did you mean IsVersionSupported, or was it misspelled already and you are just matching that?:

                #Check the results 
                  If ($Results.Content.Contains('"IsVersionSuppoted":true'))
                

                 

                2): Line 94 of your code has 'useagent: "true"'.  Are you really using an agent, or is this just the default and it's safe for me to change it to 'False'.

                $Body = '{"nodeName":"' + $NodeIP + '","nodeIp":"' + $NodeIP + '","nodeId":' + $NodeID + ',"cred":{"Id":"-3","Name":"","UserName":"","Password":""},"useAgent":true}'
                

                 

                3): At the end of line 146 in your code, you have 'ExecutePollingMethod: Agent'.  Is this the same thing as the advanced options when editing Application Templates where you can change 'Preferred Polling Method' from the default of 'Agent' to 'Agentless', or is this something else?   If something else, would I change it to 'WMI' instead of 'Agent'?  If it is the 'Preferred Polling Method' setting then I assume I would change it to 'Agentless', correct?

                #Set the Body  
                  $Body = '{"settings":{"NodeId":' + $NodeID + ',"AppType":"ABIA","CredentialSet":{"Id":"' + $credentialSetID + '","Login":"","Password":""},"CustomSettings":{"PsUrlWindows":"https://' + $NodeIP + ':5986/wsman/"},"Use64Bit":true,"ExecutePollingMethod":"Agent"}}'
                

                 

                4): Also, in the same line 146 mentioned in number 3 above, should I put an actual username and password in the "Login":"", "Password":"" quotes, or are they supposed to be blank like that?

                 

                5): How is the authentication to the SQL Servers made?  I noticed in your connection string you didn't pass any username/passwords.  Will it just use the Windows Account I'm running the script under?  That's fine if so, just need to know.

                 

                6): Any other tips you have for running this?  Anything you ran into for your 150 + nodes run  that you can advise me on prior to running this?  Also, if you have that foreach loop version of this you can share (even privately) that would be amazingly awesome and save me tons of time.  Maybe I can even repay you one day with one of my many queries and scripts I have sitting in my personal library.

                 

                 

                Thank you so much for this!  I can't express how awesome this is and I look forward to getting this going.  It's super cool how you thought to intercept the web requests to reverse engineer this.  I would have never thought to do so.  Mostly because I would have had no idea how to do it in the first place, much less how to make sense of the data I was seeing to turn it into a workable PowerShell code.  I'm good with PowerShell but my knowledge of web services is nearly zero.

                  • Re: AppInsight for IIS assing to node API
                    sstark85

                    Thanks for feedback.

                     

                    1. Line 86, yes that is misspelled.

                    2. and 3. For Line 94 and 146, you can play with that if you like and change it to false and Agentless. I was just filling in what I saw during the web request.

                    4. Login and Password should remain null. The Credential set is using the ID -3, (CredentialSet":{"Id":"-3"), which refers to inherit from node.

                    5. For the SQL authentication, yes this is using creds the script is running under.

                    6. I have not really run into many issues overall, you may find some nodes that you may need to click the Configure Server button again on.

                     

                    For the ForEach Loop you can just add the below right before the If ($NodeInfo) statement on line 50. Make sure to add the closing bracket at the end of the script. I left that out as I didn't want someone to just copy and run the script and ruin their environment.

                     

                    $Servers = "server1", "server2", "server3"
                    
                    ForEach ($Server in $Servers){
                    
                    #Get Node Information from swis
                    $NodeInfo = Get-SwisData $swis "SELECT NodeID, IPAddress FROM Orion.Nodes WHERE Caption = '$Server'"