by Lahru at 2012-11-19 11:26:40
Is there a way to do this?by DonJ at 2012-11-19 11:32:26
For each/all files in a directory.
Subtract the file’s modified time from the current time
then
If the time frame for ANY file is outside of a specified timeframe
Complete an action?
My purpose in this is to check up on a proprietary service that sometimes hangs but doesn’t stop.
If I could script the logic outlined above, then finding a file that is so many minutes old would indicate that the service isn’t working and I’d like to then trigger an alert.
Yeah, pretty easily.by Lahru at 2012-11-19 12:25:52Get-ChildItem -path \whatever | ForEach {
}
Inside that ForEach block, you’d put your calculation and use an If construct to check your timeframe. Something like $.LastWriteTime - $.CreationTime would be the calculation.
In v3, add the -File parameter to Get-ChildItem so that it doesn’t return directories, if there are subfolders in there. Add -recurse to recurse files in subfolders.
OK, awesome, so that gets me here:by DonJ at 2012-11-19 12:39:03$files = get-childitem -path \any\where* -include *.pdf, *.tif, *.jpg
What I’d like to do is send an email rather than write-host and I can do this with the send-MailMessage Cmdlet, but I don’t need a message per file.
Foreach ($file in $files)
{
$time = ((get-date) - $file.LastWriteTime).Totalminutes
IF($time -gt 2)
{
Write-Host "$file is $time minutes old."
}
}
So is there a way to get only 1 ACTION if 2 files return $True?
I could write a new-item to a specific directory and then check that directory sending a message if a Trigger File exists, but I think that is getting too complicated.
Write-Host is evil ;).by Lahru at 2012-11-20 08:18:35
Just accumulate your message in a variable:
$message = ‘’
And:
$message += "$file is $time minutes old"
You can pass that to Send-MailMessage at the end of your script. Is $message -eq ‘’ at the end, then don’t send anything. I could probably turn this into a one-liner, even.
$mailbody = Dir \any\where* -include .txt,.pdf | where { ((get-date) - $.lastwritetime).totalminutes -gt 2 } | Select @{n=‘File’;e={$.name}},@{n=‘Minutes Old’;e={((get-date) - $.lastwritetime).totalminutes}}
Then just use Send-MailMessage and $mailbody. Shame Send-Mail doesn’t accept pipeline input. Coulda made it a true one-liner.
Ok I am not completely certain what is happening in your one liner. But I need to refine my trigger for the action regardless of the action.by DonJ at 2012-11-20 08:26:34
I want to send an alert or complete an action such as restarting a service,
but I don’t want to send out 50 messages (1 for each file) & I don’t want to restart a service 50 times either.
How would I get 1 single action out of this?
So in other words; regardless of whether I get 1 old file or 100 I want only 1 alert. How can I do that?
my attempts to run the one-liner against a directory I know has files that match the "too old" parmeters I get this]Send-MailMessage : Cannot validate argument on parameter 'Body'. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.[/powershell]
$mailbody = Dir \any\where* -include .txt,.pdf | where { ((get-date) - $.lastwritetime).totalminutes -gt 2 } | Select @{n=‘File’;e={$.name}},@{n=‘Minutes Old’;e={((get-date) - $.lastwritetime).totalminutes}}
if ($mailbody) { Send-MailMessage -To x -From x -Body $mailbody }
The one-liner is just doing what your script was doing. If you prefer that:
$files = get-childitem -path \any\where* -include *.pdf, *.tif, *.jpg
$message = ‘’
Foreach ($file in $files)
{
$time = ((get-date) - $file.LastWriteTime).Totalminutes
IF($time -gt 2)
{
$message += "$file is $time minutes old.`n"
}
}
if ($message -ne ‘’) { Send-MailMessage -To x -From x -Body $message }
You got the error because, I suspect, you tacked Send-MailMessage onto the end of what I gave you. Can’t do that, because nothing in it accepts pipeline input.