5 Replies Latest reply on Jul 12, 2019 11:51 AM by Jonathan Angliss

    Powershell Script Output Not Defined

    xfaulknor

      Hello Fellow Thwackers,

       

      I'm trying to get this Powershell script shown as the status of the monitoring component. I've add this script in the edit:

       

      $username = "username"

      $password = ConvertTo-SecureString "password" -AsPlainText -Force

      $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password

      $web = Invoke-WebRequest http://dwtest-web01:8080/manager/html -Credential $cred

      $data = $web.AllElements | Where{$_.TagName -eq "TD"} | Select-Object -Expand InnerText

       

      for($i=0; $i -le $data.Length;$i+=1){

      If ($data[$i] -eq 'false'){

         Write-Host $data[$i-3] "instance status is" $data[$i] | out-String;

         $i+=1

         }

      }

       

      I'm not familiar with having the credentials coming from SW itself but I do have it set up.

       

      I've pasted the same code but the result was "Not Defined"

       

       

      Could anyone help me figure this out?

       

      Thanks

        • Re: Powershell Script Output Not Defined
          mesverrum

          All script based monitors require a statistic as part of the outputs, this article covers it pretty well

          The Basics of PowerShell (part 3)

          1 of 1 people found this helpful
            • Re: Powershell Script Output Not Defined
              xfaulknor

              Hey I've read through to understand how to get this working. I see that SW needs the proper format (Message/Statistic) but my issue is similar with this issue: Invoke-WebRequest Powershell HTML Parsing .

              I've tried parsing the output made but my Invoke-WebRequest code doesn't work without IE so I've added -UseBasicParsing but now I would get "Cannot index into a null array. "


              UseBasicParsing doesn't keep the same data as it did when I didn't used that code. Is there a separate way to get the data when using these lines??

               

              $web = Invoke-WebRequest -uri http://dwtest:8080/manager/html  -Credential $cred -UseBasicParsing

              $data = $web.AllElements | Where{$_.TagName -eq "TD"} | Select-Object -Expand InnerText

              Write-Host "Message: $($data[0])";

               

              Output: ==============================================

              Message:

               

              Errors: ==============================================

              Cannot index into a null array.

              At line:11 char:24

              + Write-Host "Message: $($data[0])";

              + ~~~~~~~~

                + CategoryInfo : InvalidOperation: (:) [], RuntimeException

                + FullyQualifiedErrorId : NullArray

                • Re: Powershell Script Output Not Defined
                  Jonathan Angliss

                  Hello xfaulknor,

                  Did you look at the answer to that discussion? One of the suggestions was to disable Internet Explorer's "First Run" wizard using Group Policy. If you cannot do it that way, you could use psexec to launch Internet Explorer as the local system account (psexec -s iexplorer.exe for example)

                   

                  Another tip for your script, you can use the ${credential} object and SolarWinds will use the credentials from the Credential Library.  So your code would be changed to look something like this:

                   

                  $web = Invoke-WebRequest http://dwtest-web01:8080/manager/html -Credential ${CREDENTIAL}

                   

                  You then select the credential from the drop down list when configuring the component.

                    • Re: Powershell Script Output Not Defined
                      xfaulknor

                      Hey Jonathan,

                       

                      Yep, I've looked into the answer and disabled the IE first run wizard from Group Policy and I'm happy to say it worked! I was able to get this output to show in the template but now I have an issue with it only showing one line of false flags when there are multiple.

                         }

                       

                      $username = "admin"

                      $password = ConvertTo-SecureString "adminadmin" -AsPlainText -Force

                      $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password

                      $web = Invoke-WebRequest http://172.29.128.141:8080/manager/html -Credential $cred

                      $data = $web.AllElements | Where{$_.TagName -eq "TD"} | Select-Object -Expand InnerText

                       

                      for($i=0; $i -le $data.Length;$i+=1){

                      If ($data[$i] -eq 'false'){

                         Write-Host "Message: $($data[$i-3]) "instance status is" $($data[$i])" | out-String;

                         Write-Host "Statistic: 1";

                         $i+=1;

                       

                      I'll use the proper credentials code provided earlier but I would like for this to show all 'false' instances because it seems to pull the first one it sees only.

                       

                      Thanks

                       

                        • Re: Powershell Script Output Not Defined
                          Jonathan Angliss

                          SAM is looking for a particular output format, and you have it partially there.  SAM uses Statistic/Message pairs, one for the value and one for the user readable text.  You've created a "default" output, but as you're outputting it multiple times, it's basically taking the last, or first, result that is returned.  For SAM to capture all the various outputs, you can "name" the pairs (see here for doc reference).  For example:

                           

                          for($i=0; $i -le $data.Length;$i+=1){
                              If ($data[$i] -eq 'false'){
                                  Write-Host "Message.$($data[$i-3]): $($data[$i-3]) instance status is $($data[$i])" | out-String;
                                  Write-Host "Statistic.$($data[$i-3]): 1";
                              }
                          }
                          

                           

                          While those named pairs can be defined dynamically in the code, SAM is expecting the output to remain consistent (ie the named pairs always appear).  From a cursory glance at the code, it appears that you're wanting to show the value 1 if the table has false in the field.  Because SAM is wanting consistent pairs, you'll want to change the code slightly to look something like this:

                           

                          $exit = 0
                          $count = 0
                          for($i=0; $i -le $data.Length;$i+=1){
                              $stat = 0
                              Write-Host "Message.$($data[$i-3]): $($data[$i-3]) instance status is $($data[$i])" | out-String;
                              If ($data[$i] -eq 'false'){
                                  $stat = 1
                                  $count++
                                  if ($count -gt 3) {
                                      $exit = 3
                                  } else {
                                      $exit = 2
                                  }
                              }
                              Write-Host "Statistic.$($data[$i-3]): $stat";
                          }
                          exit $exit
                          

                           

                          What this is doing is assigning an exit code, and a counter. It loops through the data array. It outputs "Message.StudentPlanner_kb: instance status is false" then checks if the table field is false, if it is it then sets the stat to 1, and increments the counter. If the number is greater than 3, then it sets the exit code for later to be critical, otherwise it's warning. Then it outputs "Statistic.StudentPlanner_kb: 1".  The exit code (you can read more here) allows you to just have the component monitor return an exit status, so if you are building alerts off of it you only need to look for one of the statuses (up, down, warning, critical, unknown) rather than going through each of the statistics and seeing if any are 1.

                           

                          As a side note, I did notice you had an "$i+=1" in your code, as well as in the for loop. This would mean in the $data[$i] being 'false', $i would be incremented twice, I'm not sure if that's intentional or not.