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

# Advanced File Age Monitor with PowerShell

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

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 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 lchance The script already looks for wildcard extensions so there shouldn't be any issues there. The other issue is that I cannot type apparently. Line 22 should be 'Statistic' not 'Statistics'. I wrote it correctly in the answer to the question, but my sample script was broken. This is what happens when you write quick scripts at home away from your lab. I'll update the sample script above to ensure it's correct and others don't trip over my typing abilities • ###### Re: Advanced File Age Monitor with PowerShell Jonathan where can I get the Template for the Powershell File Age Monitor, I don't see it available on our Solarwinds server under the Thwack templates or the standard ones. Thanks Karlita • ###### Re: Advanced File Age Monitor with PowerShell krcourser if you're referring to my code above, I didn't put it into a template, but they are not hard to create yourself. • Go to SAM Settings • Click "Create New Template" • Give the template a name • Click on "Add Component Monitors" • Select "Manually Add Component Monitors" • Go through the list and look for Windows PowerShell From here it's a case of filing in the details. There will be a a box to click for the "script" where you can paste in the above. Adjust the code to fit your needs. Test it against a node you want to validate, and you should get results. • ###### Re: Advanced File Age Monitor with PowerShell Awesome, thanks so much. I’m fairly new to scripting and Orion so I have been doing a lot of testing, trials, error, frustration…. We used to use a product called Zabbix and it seemed hard but we managed to get what we needed to work with it but trying to get all those monitors to transfer to Orion has proven to be a challenge when trying to monitor log files and database tables. I really appreciate your help and guidance. Karlita • ###### Re: Advanced File Age Monitor with PowerShell Jonathan, I got the results I am looking for just need to clarify the defined age part, if I don’t want them to be more than 20 minutes old do I just have to change$days = 0, $hours = 0, and$mins = 20.  I am assuming the $_.LastWriteTime –lt… means last write time less than the given totals in those variables. Like I said very new to most scripting and especially Powershell, I know just enough to be dangerous. I get time to learn a bit but once I get done what is needed do get to use it again for months to years so have to relearn it all again. I am a very big fan of documentation for this reason. Thanks again for your help. Karlita • ###### Re: Advanced File Age Monitor with PowerShell Jonathan, Sorry to be a pain but it all works when testing while creating the Template but once I try and assign it, to the same node I tested against, I get the following output, any ideas. • ###### Re: Advanced File Age Monitor with PowerShell Hey krcourser, Are you running that script in local or remote mode? In either case, can you double-check that the path exists? • ###### Re: Advanced File Age Monitor with PowerShell Used both and yes the path exists, used unc path and C:\ It works when creating the template but when I apply to the same serve it was testing with get the error. Sent via the Samsung Galaxy S® 5 ACTIVE™, an AT&T 4G LTE smartphone • ###### Re: Advanced File Age Monitor with PowerShell Steven, I believe I got it working, I restarted the WinRM service but I think the fix was when I selected Remote Host I also checked the Use HTTPS protocol and it failed no matter if I selected Remote Host or Local Host. The Monitor is up now so I just need to put a file in the directory to see I the alert works now. Thanks for all your help and Jonathans too. Now I just have to get the Oracle Database query to actually connect to the database on my next hurdle to tackle for getting all my Applications monitored. Karlita • ###### Re: Advanced File Age Monitor with PowerShell I having a issue with this script saying Get output failed. I just cant figure out how to fix it..Here is the script$path = "\XxxxxXXX\D$\SPA_Live\in\"$stats = 0

$msg =''$days = 0

$hours = 0$mins = 15

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

if ($files -ne$null) {

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

$msg = 'Message: ' +$f_names

$stats =$files.Count

} else {

$msg = 'Message: files exceed defined age' } Write-Host$msg

• ###### Re: Advanced File Age Monitor with PowerShell

This might be abit late, but shouldn't either $mins be$minutes or visa versa?

• ###### Re: Advanced File Age Monitor with PowerShell

Never late to correct my code.  Thanks for the observations.  I've corrected it now.

1 of 1 people found this helpful

• ###### Re: Advanced File Age Monitor with PowerShell

Hey Jonathan -

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

${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 Fantastic, I'll give that a try. • ###### Re: Advanced File Age Monitor with PowerShell The alert results are printing the variables as plain text instead of interpreting them. • ###### Re: Advanced File Age Monitor with PowerShell 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. 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 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 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 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 The -include '*.*' can be changed to -include '*.OLD' • ###### Re: Advanced File Age Monitor with PowerShell 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 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.

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

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

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

Silly questions (maybe) - are you running it as a particular user? Do you have the impersonate checkbox checked? If so, does that user have access to that path?

• ###### Re: Advanced File Age Monitor with PowerShell

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

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