Powershell script to check folder for files and send email - powershell

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
}

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 - search for old files and email alert

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

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 = ""
}
}
}

Cryptolocker Honeypot FileSystemWatcher

I am a novice when it comes to scripting so please bear with me. I am trying to create a script that will monitor a bait file that is added to all file shares on a server. When the script sees that the file was modified it will block access to the user that made the modification and send an email. The script seems to work ok other than the FileSystemWatcher. It will only monitor the last share. I have seen a similar post on here but was getting confused with the answer. Can someone please help me with the task of creating a FileSystemWatcher for each bait file? I would also like any input as to how I might improve upon the script in other ways. Your help is greatly appreciated.
$to = "joe#blow.com"
$File = "test.txt"
$FilePath = "C:\temp"
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
## SEND MAIL FUNCTION
function sendMail($s, $to) {
$smtpServer = "mail.nowhere.com"
$smtpFrom = "alert#nowhere.com"
$smtpTo = $to
$messageSubject = $s[0]
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $false
$message.Body = $s[1]
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)
}
## Get a list of shares and Perform tasks on each location.
$cryptopaths = Get-WmiObject -Class win32_share -filter "Type=0 AND name like '%[^$]'" | ForEach ($_.Path) {
$cryptopath = $_.Path
## Copy the bait file to the share location
Copy $FilePath\$File $cryptopath\$File -Force
##Get files hash
Try {
$Origin = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$FilePath\$File")))
$Copy = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$CryptoPath\$File")))
}
##Error on reading hash
Catch {
echo "error reading $CryptoPath\$File"
}
## If files don't match, then Send messaged and quit
if (Compare-Object $Origin $Copy){
## files don't match
$subject = "Error logged on $CryptoPath\$File by $env:username on $env:computername"
$body = "The original file does not match the witness file. Aborting monitor script."
$email =#($subject,$body)
sendMail -s $email -to "ben22#nowhere.com"
Exit
}
## CREATE WATCHER ON DIRECTORY
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $CryptoPath
$watcher.Filter = $File
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $false
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName
}
## Execute Watcher
while($TRUE){
$result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::Changed `
-bor [System.IO.WatcherChangeTypes]::Renamed `
-bor [System.IO.WatcherChangeTypes]::Deleted `
-bor [System.IO.WatcherChangeTypes]::Created, 1000);
if ($result.TimedOut){
continue;
}
if ($result.Name -eq $File) {
### Make sure the files do not match
try {
$FileCheck = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$CryptoPath\$File")))
if (Compare-Object $Origin $FileCheck){
## files don't match
$body = "Witness file $FilePath\$File on $env:computername has been modified."
}
}
catch {
## file deleted
$body = "Witness file $FilePath\$File on $env:computername has been deleted"
}
finally {
## Deny owner of changed file access to shares and disconnect their open sessions. Send email alert
Get-Acl "$CryptoPath\$File" | foreach ($_.Owner) {
Get-SmbShare | Block-SmbShareAccess –AccountName $_.Owner
Close-SmbSession –ClientUserName $_.Owner
}
$subject = "EMERGENCY ON FILE SERVER -- $FilePath\$File by $env:username on $env:computername"
$email =#($subject,$body)
sendMail -s $email -to "ben22#nowhere.com"
sendMail -s $email -to "5555555555#txt.bell.ca"
Exit
}
}
}
The problem is that you create FileSystemWatcher instances in a loop (ForEach ($_.Path) {}), but you assign them to the same variable $watcher, overwriting the previous reference each time. Once outside the loop, you work with the $watcher variable, which references the last FileSystemWatcher instance you created and that's why you are receiving notifications for the last file only.
To get this working, you should use a type that allows storing multiple references -- that is, an array. Example:
$watchers = #();
...
$watcher = New-Object System.IO.FileSystemWatcher;
...
$watchers += $watcher;
Also, I would propose to use event handler/callback/delegate-based approach instead of waiting for a change using WaitForChanged(), because waiting for multiple file system watchers would call for a parallelized solution (well, ideally). Use Register-ObjectEvent to register an event handler and see this example in particular: http://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b.
PowerShellPack also has a Start-FileSystemWatcher cmdlet that wraps this all up nicely, but I'm not sure about the status of PowerShellPack in general. It should be part of the Windows 7/8 Resource Kit, though.