Powershell - search for old files and email alert - powershell

Having some trouble with a powershell script which Im completely new too
What Im trying to do is basically monitor a specific folder for XML files only. If the files are older than say a 30mins then to email myself to alert me there is a problem
This is what I have so far:
$Path = "‪D:\Temp"
$SMTPServer = "10.1.1.12"
$From = "Email <email#aol.com>"
$To = "emailme#whatever.com"
$Subject = "Alert: Potential issue with service"
$SMTPMessage = #{
To = $To
From = $From
Subject = "$Subject"
Smtpserver = $SMTPServer
}
$File = Get-ChildItem -path $path -Filter ".XML" | Where-Object {$_.LastWriteTime -lt (Get-
Date).AddMinutes(-30)}
If ($File)
{ $SMTPBody = "Batches older than 30 minutes located in D:\Temp while service is actively running.
Service may require a restart."
$File | ForEach { $SMTPBody += "$($_.FullName)`n" }
Send-MailMessage #SMTPMessage -Body $SMTPBody
It doesnt work at all at the moment its failing at the first stage in trying to find the path
Any help would be great
Thanks

Related

My boss for work asked me to create a powershell script to send email notifications when a new file is added or a file has been changed

I've been searching online about this script and I've only found this so far
I don't know anything about scripting but I've tried to implement this on my pc and I haven't received any emails whenever I added a file to my test folder. help with this would be much appreciated.
P.S if you're going to explain something to me about scripting, act like you're explaining to a 5 year old because I'm clueless when it comes to scripting lol
Param (
[string]$Path = "C:\Users\ahmad.mahmoud\Desktop\test",
[string]$SMTPServer = "smtp.domain.com",
[string]$From = "email#domain.com",
[string]$To = "email#domain.com",
[string]$Subject = "new file added"
)
$SMTPMessage = #{
To = $To
From = $From
Subject = "$Subject at $Path"
Smtpserver = $SMTPServer
}
$File = Get-ChildItem $Path | Where { $_.LastWriteTime -ge [datetime]::Now.AddMinutes(-1) }
If ($File)
{ $SMTPBody = "`nThe following files have recently been added/changed:`n`n"
$File | ForEach { $SMTPBody += "$($_.FullName)`n" }
Send-MailMessage #SMTPMessage -Body $SMTPBody
}
I tried to implement the code above in PowerShell but I didn't get any email notifications whenever I added a new file to my test file (of course I changed the email and stmp server address due to privacy reasons.)

Powershell script to check folder for files and send email

I'm trying to get a script to work but I'm running into some issues. We have a folder that gets ZIP files sent to it via FTP and a service on the server moves them to another directory for processing. The issue is sometimes the service will be running but not doing anything so the monitoring doesn't sent a alert. I am working on a PowerShell script to check the folder for .zip files older than 30 minutes and if found send a email to that team to check out why the files haven't been moved. Below is what I have written so far, any help would be greatly appreciated. Thanks.
$Path = "c:\test"
$SMTPServer = "mail.server.com"
$From = "Monitor Prod <mon.server.com>"
$To = "people#server.com"
$Subject = "Alert: Potential issue with service in PROD"
$SMTPMessage = #{
To = $To
From = $From
Subject = "$Subject"
Smtpserver = $SMTPServer
}
$File = Get-ChildItem -path $path -Filter ".txt" | Where-Object {$_.LastWriteTime -lt (Get-Date).AddMinutes(-30)}
If ($File)
{ $SMTPBody = "Batches older than 30 minutes located in c:\test while service is actively running. Service may require a restart."
$File | ForEach { $SMTPBody += "$($_.FullName)`n" }
Send-MailMessage #SMTPMessage -Body $SMTPBody
}

Powershell email attachement

I am trying to create a script to automatically send an email with various attachments. I am having an issue of the of it saying the file is not found. I can confirm that the file is present in the folder. I am unsure why I am getting this error and have tried running the script on various platforms thinking that it may be an issue of where the code is running but nothing has worked as of yet. Any help would be greatly appreciated.
Param (
$Path = "\\cottonwood\users\Shared\Pool Acquisitions",
$SMTPServer = "mail.genericmail.com",
$From = "address#genericmail.com",
#The below commented out line is used to test with just one individual. Be sure to comment out the one with all individuals before troubleshooting.
#$To = #("lt#genericmail.com"),
$SMTPport = "587",
$To = #("address#genericmail.com"),
$Subject = "Folders Added in",
$logname = "\\cottonwood\users\Shared\Loan Documents - Active\logs\New Folders$date.txt",
$date = (Get-Date -Format MMddyyyy),
$SMTPBody = "body",
$files = (Get-ChildItem "\\cottonwood\users\IT\Missing Folder Location")
)
$SMTPMessage = #{
To = $To
From = $From
Subject = "$Subject $Path"
Smtpserver = $SMTPServer
Port = $SMTPport
}
$attachment = $files
$SMTPBody = "`nThe following folders have been found to be non-existant in the last 24 hours:`n`n"
Send-MailMessage #SMTPMessage -Body $SMTPBody -Attachments $attachment
Send-MailMessage is unable to locate the files as the variable $files does not include the full file path
Change:
$files = (Get-ChildItem "\\cottonwood\users\IT\Missing Folder Location")
To:
$files = (Get-ChildItem "\\cottonwood\users\IT\Missing Folder Location").fullname

PowerShell script to find log files more than 10 MB and send mail whenever a new file generated in that folder

I need to find new files in a folder which are over 10 MB in size, and then send a mail with the name of the files.
The tricky part: Mail should be send when there is a new file arrives in the folder, so I have to always keep track and differentiate between the old file and new file.
Problem: I have written the following code and am not able to build the logic for mail. How can I identify the new file comes and trigger the mail?
$namearray = #()
$n = gci 'C:\Users\RF\local\ReuseLibrary\FamilySaveDirectory' | % {get-item $.FullName| ? { $.length -gt 10mb }}
foreach($a in $n) {
$namearray += $a.name
}
$namearray
Send-MailMessage -To *#gmail.com -From '****#*.com' -Subject "Add User for $namearray NX License" -Body "Script execute $namearray successfully.." -SmtpServer 'mail.****.de'
As already pointed out in the comments, you can use the FileSystemWatcher object to monitor your filesystem. It got a little more tricky than just using the object, because you also need to be able to get the files which are already in the folder, not only the newly created ones.
Should the script really trigger the mail every time it has a new item in the $namearray? Maybe you'll get a flood of e-mails then.
It's better to use a function instead of a script to do your task because you have more flexibility, so you can check for only newly created files, and also for all files inside your folder.
Please try the function. I couldn't test it very well, because I don't have a folder where 10 MB large files get created all the time.
Usage:
To get all files (the wildcard * in the filter is important!):
Get-Files -filter '*.txt' -folder 'C:\yourfolder' -AllFiles
To monitor only new created files:
Get-Files -filter '*.txt' -folder 'C:\yourfolder' -NewFiles
Function:
Please edit the Send-MailMessage part so that you will receive the mail on your account.
function Get-Files() {
param(
[string]$filter,
[string]$folder,
[Parameter(ParameterSetName='AllFiles')]
[switch]$AllFiles,
[Parameter(ParameterSetName='NewFiles')]
[switch]$NewFiles
)
# Preparing the Name array
[string[]]$namearray = #()
if(!$NewFiles.IsPresent) {
# Getting all files which are already inside the
# folder and more than 10 MB
$files = gci $folder | % { get-item $_.FullName |
? { $_.length -gt 10mb -and $_.Extension -like $filter} } |
% { $namearray += $_.FullName }
# Send E-Mail
$secondnamearray = $namearray | out-string
Send-MailMessage -To '*#gmail.com' -From '****#*.com' -Subject "Add User for NameArray NX License" -Body $secondnamearray -SmtpServer 'mail.****.de'
$namearray = ""
}
# Monitoring of the Files
$monitoring = New-Object System.IO.FileSystemWatcher
$monitoring.Filter = $filter
$monitoring.path = $folder
$monitoring.EnableRaisingEvents = $true
$event = Register-ObjectEvent -InputObject $monitoring -EventName Created -Action {
# Checking for filesize
$x = (get-item $eventArgs.FullPath).length / 10mb
if ($x -ge 1) {
Write-Host "New Item found: $($eventArgs.FullPath). Sending E-Mail!"
$namearray += $eventArgs.FullPath
$newnamearray = $namearray | out-string
Send-MailMessage -To '*#gmail.com' -From '****#*.com' -Subject "Add User for NameArray NX License" -Body $newnamearray -SmtpServer 'mail.****.de'
$namearray = ""
}
}
}

Powershell applied to Outlook Com Object - Multiple Filters

ORIGINAL POST:
Goal: an email is sent to a service account every day from a source.
Take the csv file it gives me and put it in a folder for the DBA guy.
Without further adieu, here is my current script:
#define variables
$datestamp = (get-date).AddDays(-1).ToString("MMddyyyy")
$datestamp = $datestamp.ToString()
$path = "C:\MyPath"
$dest = "C:\MyPath\Archive"
$file = "MyFile.csv"
#create outlook session
$objOutlook = New-Object -Com Outlook.Application
$inbox = $objOutlook.Session.GetDefaultFolder(6)
$inbox.Items.Restrict("[UnRead] = True" -and "[SenderEmailAddress] = 'SomePlace#SomeDomain.net'") | select -Expand Attachments | %
{
for ($i = $_.Count; $i; $i--)
{
$_.Item($i).SaveAsFile("C:\MyPath\$($_.Item($i).FileName)")
$_.Parent.Unread = $false
}
}
if (Test-Path "C:\MyPath\*.csv")
{
if(((Get-ChildItem C:\MyPath | Measure-Object ).Count) -gt '1' )
{
Send-MailMessage –SmtpServer "server.domain.com" –From "PoorITGuy#domain.com" -To "PoorITGuy#domain.com" -Subject " FAIL" -Body "FAILED. Too many valid items from mailbox.
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
throw "Too many items to get."
}
else
{
Get-ChildItem $path\*.csv | foreach {Copy-Item $_ "C:\MyPath\$"}
Copy-Item C:\MyPath\*.csv "$path\$file"
Copy-Item C:\MyPath\*.csv "$dest\${datestamp}_$file"
if(Test-Path "$dest\$file")
{
Send-MailMessage –SmtpServer "server.domain.com" –From "PoorITGuy#domain.com" -To "PoorITGuy#domain.com" -Subject "some message”
#cleanup - remove all files from base directory, clean mailbox, close out com object.
Remove-Item "$path\*.csv"
$inbox.Items | select | %
{
for ($i = $_.Count; $i; $i--)
{
$_.Item($i).Delete
}
}
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
}
else
{
Send-MailMessage –SmtpServer "server.domain.com" –From "PoorITGuy#domain.com" -To "PoorITGuy#domain.com" -Subject " failure" -Body "File manipulation failure."
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
throw "File manipulation failure."
}
}
}
else
{
Send-MailMessage –SmtpServer "server.domain.com" –From "PoorITGuy#domain.com" -To PoorITGuy#domain.com -Subject "FAIL" -Body "No item mailbox."
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
throw "No item to get in inbox."
}
What doesn't work:
$inbox.Items.Restrict("[UnRead] = True" -and "[SenderEmailAddress] = 'SomePlace#SomeDomain.net'") | select -Expand Attachments | %
It seems that you cannot restrict the comObject Outlook.Application with more than one filter.
I've done a ton of searching on this and cannot find an answer on how to best perform this task in lieu of this. But I want my script to be spam-proof, so it needs to know that it is sent from the expected sender AND it needs to be unread only (see error catching right below)
In addition, I'm not certain if this would work:
$inbox.Items | select | %
{
for ($i = $_.Count; $i; $i--)
{
$_.Item($i).Delete
}
}
Also would like input on the script itself. Any input to make it more efficient would be appreciated.
The correct code (lots of syntax errors on the above prevented it from doing what I wanted to)
#define variables
$datestamp = (get-date).AddDays(-1).ToString("MMddyyyy")
$datestamp = $datestamp.ToString()
$path = "C:\MyPath"
$dest = "C:\MyPath\Archive"
$importpath = "C:\MyPath\Import"
$file = "MyFile.csv"
$folderExclude = "C:\MyPath\Archive"
#create outlook session
$objOutlook = New-Object -Com Outlook.Application
$inbox = $objOutlook.Session.GetDefaultFolder(6)
$inbox.Items.Restrict("[Unread] = True AND [SenderEmailAddress] = 'SomePlace#SomeDomain.net'") | select -Expand Attachments | % {
for ($i = $_.Count; $i; $i--) {
$_.Item($i).SaveAsFile("\\server\MyPath\$($_.Item($i).FileName)")
$_.Parent.Unread = $false
}
}
if (Test-Path "C:\MyPath\*.csv") {
if(((Get-ChildItem C:\MyPath -Include "*.csv" | Measure-Object ).Count) -gt '1' ) {
Send-MailMessage -SmtpServer smtpserver.mydomain.com -From Powershell#mydomain.com -To someguy#mydomain.com -Subject "FAIL" -Body "FAILED. Too many items from PSAutomationSrv mailbox."
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
throw "Too many items to get."
}
else {
Copy-Item C:\MyPath\*.csv "$importpath\$file"
Copy-Item C:\MyPath\*.csv "$dest\${datestamp}_$file"
if(Test-Path "$dest\${datestamp}_$file") {
Send-MailMessage -SmtpServer smtpserver.mydomain.com -From Powershell#mydomain.com -To someguy#mydomain.com -Subject " successful" -Body "Date is: ${datestamp} File name is: ${dest}\${file}"
#cleanup - remove all files from base directory, clean mailbox, close out com object.
Remove-Item $path\*.csv
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
}
else {
Send-MailMessage -SmtpServer smtpserver.mydomain.com -From Powershell#mydomain.com -To someguy#mydomain.com -Subject " import - failure" -Body "File manipulation failure."
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
throw "File manipulation failure."
}
}
}
else {
Send-MailMessage -To -SmtpServer smtpserver.mydomain.com -From Powershell#mydomain.com -To someguy#mydomain.com -Subject "FAIL" -Body "FAILED. No item in mailbox."
$objOutlook.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objOutlook)
throw "No item to get in inbox."
}
Notes - I had some code in excess.
Get-ChildItem $path\*.csv | foreach {Copy-Item $_ "C:\MyPath\$"}
is incorrect syntax, and unnecessary since the script already knows it is just manipulating one file anyway.
For deleting the inbox I would need to use Export-Mailbox it seems, which I do not want to do; as the service account performing this function is NOT an exchange admin nor do I want it to be. I'm just going to manually delete the inbox periodically or have the exchange guy do it on his end.