42 Replies Latest reply on Nov 6, 2019 3:17 PM by miali

    Advanced File Age Monitor with PowerShell

    Deltona

      Hi,


      I need to monitor the age of file in a folder. I can not use the default File Age monitor because it does not accept a wildcard for filename.

      The files that are in the folder have different names, hence the need to use another File Age monitoring approach.


      I've found a PowerShell script online that does the trick but I am having difficulties getting it to work in SAM. It could be that I don't fully understand what SAM expects as an output.

      Hopefully someone here can help so that we all can benefit from it. I know a lot of people have requested the ability to monitor File Age when file does not have a set name.


      Here's the PowerShell script:


      $fullPath = "C:\hp\hpsmh\certs"
      $numdays = 3
      $numhours = 10
      $nummins = 5
      function ShowOldFiles($path, $days, $hours, $mins)
      {
      $files = @(get-childitem $path -include *.* -recurse | where {($_.LastWriteTime -lt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins)) -and
      ($_.psIsContainer -eq $false)})
      if ($files -ne $NULL)
      {
      for ($idx = 0; $idx -lt $files.Length; $idx++)
      {
      $file = $files[$idx]
      write-host ("Old: " + $file.Name) -Fore Red
      }
      }
      }
      ShowOldFiles $fullPath $numdays $numhours $nummins

       

      Attached screenshots show a test script and the expected output (file name in red). The other screenshot shows the error displayed in SAM when performing a test.

      Are there any SAM/PowerShell gurus around that ould modify the script so that it works with SAM?

        • Re: Advanced File Age Monitor with PowerShell
          Jonathan Angliss

          SAM is expecting 2 lines to come back, one a message (optional), and another a statistic.  Your output doesn't match the format that SAM is after.  I'd do the following:

           

          $path = 'c:\temp'
          $stats = 0
          $msg = ''
          $days = 3
          $hours = 10
          $mins = 5
          
          
          $files = @(Get-ChildItem -Recurse -Path $path -Include '*.*' | ?{ $_.LastWriteTime -lt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins) -and $_.psIsContainer -eq $false})
          
          
          if ($files -ne $null) {
            $f_names = [System.String]::Join('|',$files)
            $msg = 'Message: ' + $f_names
            $stats = $files.Count
          } else {
            $msg = 'Message: 0 files exceed defined age'
          }
          
          
          Write-Host $msg
          Write-Host "Statistic: $stats"
           

           

          WIth this, it'll output the file names in the Message, and the file count that exceeds the age will be a statistic, and you can monitor/alert based on that value. One thing to be careful of is the length that the message will get, depending on the number of files in the path.

           

          Edit: Corrected a 'typo' on line 22 which originally said 'Statistics' rather than the correct verbiage 'Statistic', and corrected variables $minutes to $mins

          1 of 1 people found this helpful
            • Re: Advanced File Age Monitor with PowerShell
              lchance

              Jonathan,

               

              I have a current need to monitor for a wildcard file extension and this seems to work great, however, what do you think is causing this error in the Template Monitor itself?

               

              If I execute the script from the PowerShell CMD line then it works great, but this same SCRIPT inside a SAM PowerShell Monitor fails with this message:

              PowerShell script error. Script output values are not defined or improperly defined.






              • Re: Advanced File Age Monitor with PowerShell
                rschroeder

                Your skills are so cool and helpful!  Thanks for sharing your expertise with Thwack!

                • Re: Advanced File Age Monitor with PowerShell
                  jcordle

                  Hey Jonathan -

                   

                  Thanks for your work here.

                   

                  I seem to have it nailed down pretty well, save for one issue.

                  Similar to another user here, I have it working perfectly from PS *on* the Solarwinds Server (using UNC path for the target system), but in Solarwinds, I get the "UP" successful result on the test from "component test", and in the details I get:

                   

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

                  Message: 0 files exceed defined age

                  Statistic: 0

                   

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

                  Get-ChildItem : Cannot find path 'C:\PATH' because it does not exist.

                  At line:9 char:12

                  + $files = @(Get-ChildItem -Recurse -Path $path -Include '*.*' | ?{ $_.LastWriteTi ...

                  + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                    + CategoryInfo : ObjectNotFound: (C:\PATH) [Get-ChildItem], ItemNotFoundException

                    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

                   

                  (Where C:\PATH is the path on the system I am testing against)

                   

                  I've tried entering and re-entering the credentials; no luck. I'm using the same credentials in both places. No issues from PS on the server, but not working from Solarwinds targeting the same thing.

                   

                  Ideas?

                  • Re: Advanced File Age Monitor with PowerShell
                    miali

                    Thanks Jonathan. I used your script and modified little for my requirement. Worked like a charm!

                  • Re: Advanced File Age Monitor with PowerShell
                    orioncrack

                    Hi guys,

                     

                    This template works great but when I add an additional Windows Powershell component to the template for an additional path to monitor, I lose all of the options.

                     

                     

                    powershlly.jpg

                     

                    When I add another component, none of these options are available, what am I missing here?

                     

                    Really appreciate the help.

                    .

                    • Re: Advanced File Age Monitor with PowerShell
                      jokautzman

                      When I run this script from my computer, the server I want to monitor, or the PS on the SAM server, I get the expected result (one file that I placed there to test). However, when I run "Get Script Output" in the "Edit Script" workflow, I see a result of 0. When I test the component monitor, I also see a result of 0 and the following error:

                       

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

                      Get-ChildItem : Cannot find path '\\FQDNservername.domain.local\subfolder' because it does not exist.

                      At line:8 char:25

                      + $files = @(Get-ChildItem <<<< -Recurse -Path $path -Include '*.*' -Exclude '*.db' | ?{ $_.LastWriteTime -lt (Get-Date).AddMinutes(-$mins) -and $_.psIsContainer -eq $false})

                        + CategoryInfo : ObjectNotFound: (\\FQDNservername...\subfolder:String) [Get-ChildItem], ItemNotFoundException

                        + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

                       

                      Why would this work in a PS1 but not when running from SAM?

                       

                      Edit: Nevermind, I was using improper credentials to run the script against the UNC path, causing Get-ChildItem to fail, making $files null. The $stats parameter carried on past the "else" and gave me the false reading.

                      • Re: Advanced File Age Monitor with PowerShell
                        jokautzman

                        Any suggestion for getting the $f_names to only include the file names and not the full UNC path? My $msg output for a sample file is:

                        \\servername.domain.local\subfolder\subfolder2\subfolder3\test.txt

                          • Re: Advanced File Age Monitor with PowerShell
                            Jonathan Angliss

                            You can change line 13 to read:

                             

                              $f_names = [System.String]::Join('|',$files.Name) 

                             

                            This should return just the file names.

                              • Re: Advanced File Age Monitor with PowerShell
                                jokautzman

                                What I meant to say was: thank you, that works perfectly!

                                 

                                Do you have any advice for passing the results of that script into the Alert i set up to monitor the application?

                                  • Re: Advanced File Age Monitor with PowerShell
                                    Jonathan Angliss

                                    You can use the following variables to output the useful data:

                                     

                                    ${N=SwisEntity;M=ComponentAlert.StatisticData}
                                    ${N=SwisEntity;M=ComponentAlert.ComponentMessage}
                                    

                                     

                                    The "StatisticData" will output numerical value, which will be the number of files, and "ComponentMessage" will be the list of the files, separated by "|" character.

                                      • Re: Advanced File Age Monitor with PowerShell
                                        jokautzman

                                        The alert results are printing the variables as plain text instead of interpreting them.

                                          • Re: Advanced File Age Monitor with PowerShell
                                            Jonathan Angliss

                                            Which version of SAM are you using? They changed the variable format relatively recently.  The above format is the new style, but the old alerting style uses much shorter styles.  Do you manage your alerts via the SolarWinds web console?  If so, go to the alert you're trying to edit, go to the trigger actions, select your email and in the "Message" section click on the "Insert Variable" button.  The top button will put the variables in the subject line, the bottom will put it in the body.

                                             

                                            2016-10-13 10_28_40-Edit Alert - _ADConnect - Sync Time_.png

                                             

                                            Change the drop down on the left for "Show variables for" to "Component" and take a look at some of the values there and test.  I may have provided the wrong one, or for some reason copy/paste didn't work.  For the two above, I used "Statistic Data (Component Alerting Properties)" and "Component Message (Component Alerting Properties)".  Click the "Insert Variable" button, and move it to where you want it.  You can insert multiple variables at once, then cut/move them in the actual message.

                                          • Re: Advanced File Age Monitor with PowerShell
                                            laurence.guerrero

                                            Hi Jonathan,

                                            I'll start off by stating that I really don't know anything about scripting, so any help you maybe able to provide would be greatly appreciated! I believe the script provided above is along the lines of what I'm looking for. What I need to know is, what exactly do I need to modify in order to order to have poll for NEW ".OLD" files in a specific folder.

                                             

                                            Any help would be greatly appreciated!

                                              • Re: Advanced File Age Monitor with PowerShell
                                                Deltona

                                                Hi there,

                                                 

                                                What evidence do you have and can use, in order to determine whether the file is new or not?

                                                If it is the timestamp, what would the time difference be and is it constant?

                                                  • Re: Advanced File Age Monitor with PowerShell
                                                    laurence.guerrero

                                                    Wow! You guys are awesome for the quick replies! Kudos!

                                                     

                                                    I would think the time stamp would be the best bet. It is pretty constant except in the middle of the night... The files will have a gap of an hour max! Usually they're updated every few minutes. So, if there wasn't a new .old file in an hour, I would like for it to alert.

                                                     

                                                     

                                                    ***EDIT***

                                                     

                                                    Deltona,

                                                     

                                                    We could also poll for any ".queue" files. If there are more then 2 present we could alert on that as well if that makes it any easier. Being that those are the files being converted into .old files and should not accumulate.

                                                  • Re: Advanced File Age Monitor with PowerShell
                                                    Jonathan Angliss

                                                    The -include '*.*' can be changed to -include '*.OLD'

                                                      • Re: Advanced File Age Monitor with PowerShell
                                                        laurence.guerrero

                                                        Kudos for getting back to me so quickly Jonathan!

                                                         

                                                        I will give the change a shot and see how it goes!

                                                        • Re: Advanced File Age Monitor with PowerShell
                                                          laurence.guerrero

                                                          So this is the output that I get after running the script with the ".old" change.

                                                           

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

                                                          Message: 0 files exceed defined age

                                                          Statistic: 0

                                                           

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

                                                          Get-ChildItem : Cannot find path '\\FQDNservername\d$\SubFolder' because it does not exist.

                                                          At line:9 char:12

                                                          + $files = @(Get-ChildItem -Recurse -Path $path -Include '*.old' | ?{ $_.LastWri ...

                                                          + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                                                          + CategoryInfo : ObjectNotFound: (\\FQDNservername\d$\SubFolder:String) [Get-ChildItem], ItemNotFoundException

                                                          + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

                                                           

                                                          Also tried using the IP instead of server name. Any thoughts? The folder does exist, and I did verify that I am testing on the correct server. Unlike jokautzman's situation (sept 30th posting), I'm using the correct credentials.

                                                           

                                                          Any suggestions would be great.

                                                            • Re: Advanced File Age Monitor with PowerShell
                                                              Jonathan Angliss

                                                              Drive letters with $ after are usually admin type shares that have restricted access just to administrators.  Is the account you're using an admin on the remote server? Can you create a new share pointed straight to "SubFolder" and see if that works? I'm always hesitant to use the drive shares, especially as it introduces powershell variable delimiters into the code, which could cause other issues.

                                                               

                                                              Another option is that sometimes PowerShell doesn't load the providers, so it doesn't know how to handle the path names.  Try adding Set-Location C: above the Get-ChildItem line.  There are some details about it here with a different solution as well.

                                                                • Re: Advanced File Age Monitor with PowerShell
                                                                  laurence.guerrero

                                                                  Alright, I tried a good combination of these yesterday with no success. The $ symbol was actually a mistake. The folder is located on the D drive. So I've now changed that to "D:". When running the script via the "GET SCRIPT OUTPUT" button on Solarwinds when creating a template, the output returned is 

                                                                   

                                                                  Just to verify.... This should be looking for anything that is a minute old right? I wouldn't be surprised if I was totally wrong. haha That would be why I'm searching for assistance

                                                                  Am I doing anything else wrong that would cause the script out put to return with "Not Defined"?

                                                                   

                                                                  Thank you so much for the input and the link!

                                                                    • Re: Advanced File Age Monitor with PowerShell
                                                                      Jonathan Angliss

                                                                      Is the share actually created as "D:" or just "D"? I'm not sure you can create a windows share with : in them.  What I'd suggest is trying to make a new share on the server such as directly to the subfolder with the files, and use that share name.  Make sure to grant the account that you're using to access with the necessary rights.

                                                                       

                                                                      I would also set $days and $hours to 0, instead of a blank value, otherwise you might cause an issue with the powershell processor.

                                                    • Re: Advanced File Age Monitor with PowerShell
                                                      salvi_moxie

                                                      Like many who have posted here, I'm also facing similar issue. This isn't working for me if I change the path from C:temp as in the script to something that I want to monitor. It keeps saying "0 files exceed defined age" even though there are more than 1000 files in it.

                                                       

                                                      Basically I'm trying to monitor mail queue in C:\inetpub\mailroot\Queue path, to alert if us if a mail is stuck there for more than 30 minutes.

                                                       

                                                      $path = C:\inetpub\mailroot\Queue

                                                      $stats = 0

                                                      $msg = ''

                                                      $days = 0

                                                      $hours = 0

                                                      $mins = 30

                                                       

                                                      $files = @(Get-ChildItem -Recurse -Path $path -Include '*.*' | ?{ $_.LastWriteTime -lt (Get-Date).AddDays(-$days).AddHours(-$hours).AddMinutes(-$mins) -and $_.psIsContainer -eq $false})

                                                       

                                                      if ($files -ne $null) {

                                                        #$f_names = [System.String]::Join('|',$files)

                                                        #$msg = 'Message: ' + $f_names

                                                        $stats = $files.Count

                                                      } else {

                                                        $msg = 'Message: 0 files exceed defined age'

                                                      }

                                                       

                                                      Write-Host $msg

                                                      Write-Host "Statistic: $stats"

                                                       

                                                      Note: I have commented file names portion as I don't need to know the file names.

                                                      • Re: Advanced File Age Monitor with PowerShell
                                                        salvi_moxie

                                                        No, I choose to inherit from node, which has admin rights on the server and can access the path if I RDP to the server using those credentials.

                                                        • Re: Advanced File Age Monitor with PowerShell
                                                          netspacer1

                                                          How should the code look like, if i dont want subfolders to be included in the code?