I wrote a script for checking below-listed strings[$string] in my log and send a mail with the relevant logs attachment if one of that pattern matches on that logs.
This script is working as expected, but my challenge is now to check how to exclude already alerted strings. For example:
My log file overwrites every 4 mins or sometime faster than 4 mins which is based on the call traffic. Since my script is running every 3 mins, sometimes I get numerous alert mails for the same error.
So, how to check if that error is new or already alerted before sending a mail to me? I am new to Powershell scripting. Thanks in advance!
Script:
$string='(Unable to connect to the remote server|A serious|Socket error - cannot connect|Fetch returned HTTP error|"Open error|URL=http")'
$path1="D:\Program Files\AVP\*.txt"
$Target = "D:\Program Files\AVP\Avp_Logs.zip"
if (Select-String -Path $path1 -pattern $string)
{
set-alias sz "C:\Program Files\7-Zip\7z.exe"
$count=(Select-String -Path $path1 -pattern $string).length
$string1=Select-String -Path $path1 -pattern $string
sz a $Target $Source -ssw ;
$body1=("The Error:-"+$string+": "+"Error Count"+" "+$count+"::")
$string1 | ConvertTo-Html | Out-File 'E:\PowershellScripts\test.html'
$body=""
$body=$body1+$body2
Send-MailMessage -From "alert#domain.com" -To user#domain.com-Attachments $Target -Subject "A Seriuos Error on server1,please check" $body -BodyAsHtml -SmtpServer domain.com
}
else
{
write-host "nothing to process"
}
Related
I'm having an issue when trying to complete my script.
I'm trying to create a rule for couple of users:
(if message arrives from (x), move to Inbox).
This is the script I wrote:
$names = #{"name1#name.com","name2#name.com"}
Loop
foreach($name in $names){
Write-Host "Moving the message for $name"
new-inboxrule -Name "MoveFromMailchimp" -Mailbox $name -MoveToFolder
"$name:\Inbox" -From "senderEmailAddress" -StopProcessingRules: $false
}
However it throws an error upon $name:\Inbox, saying it does not want to take ":".
Does anyone have any ideas?
You need to escape your variable in the string.
Try:
"$($name):\Inbox"
I'm not Powershell guru but do anyone of you have some script which counting files in an folder and automaticlly send mail to user? Our users have an roaming profile
(\\profile-srv\%username%)
Folder name is the same as username. Is it possible to have an script which will count files in every home folder and send email to user?
domain is: FirmaBis.org total users: 150
So count in ex. aaba and send mail to aaba#firmabis.org
Count next aaca and send mail to aaca#firmabis.org
So script will count files and send mail to user based on folder name and + firmabis.org.
Thanks!
# Get just the directories in the user directory share, ignore any files, loop over them
Get-ChildItem -Path '\\server\share' -Directory | ForEach-Object {
# List all the files in the current folder (loop variable $_ is the folder)
$FilesInFolder = #($_ | Get-ChildItem -Recurse -Force -File)
# Count the files
$NumFiles = $FilesInFolder.Count
# Calculate how many MB they take up, and show it to 2 decimal places
$FileSize = $FilesInFolder.Length | Measure-Object -Sum | Select-ExpandProperty Sum
$FileSize = "{0:.0}MB" -f ($FileSize/1MB)
# Build the email message
$Message = #"
Hi,
The folder for account ($($_.Name)) has $($FilesInFolder.Count) files in it.
They add up to $FileSize
"#
# Send the message through an SMTP server which is configured to allow
# unauthenticated relay emails from the computer running the script.
Send-MailMessage -SmtpServer yourmailserver -To "$($_.Name)#FirmaBis.org" -From 'script#FirmaBis.org' -Body $Message
}
Untested, but ...
I have not seen anything that you have tried so far. Just to give you a set off:
You can get the list of Files count using the combination of Get-childitem and .Count method.
( Get-ChildItem D:\FolderName | measure-object).Count
You can store the output in the variable.
Then, You can pass the variable as a BODY in Send-MailMessage with which you can send emails.
I am working on a script that gets the oldest log file in a folder, mails it to me and then deletes the file.
Getting the file name and deleting it afterwards works but, when a log file contains [ ] brackets, it fails sending the mail, while the file still gets deleted...
I know that brackets are wildcards and that I need to rename the files before trying to attach them but, I am not an experienced Powershell scripter and could not get examples working with my code... Could someone help me on my way?
My code:
$Item = Get-ChildItem -Path "C:\backup log" -filter "*.log" | Sort CreationTime | select -First 1
Send-MailMessage -to "Jason <jason#company.com>" -from "Backupmaster <backupmaster#company.net>" -Subject "sync log: $($Item.Name)" -SmtpServer "172.24.1.x" -body "Attached is the sync log.`nFilename: $($Item.Name). `nNote that the oldest log is sent first, newer logs may arrive later.`nThis log will be deleted from the server after sending.`n`n-Backupmaster" -attachments "$($Item.FullName)"
Remove-Item $($Item.FullName)
-Jason
I haven't tested this, but I'd expect it to work if you escape the brackets with `:
$Attachment = $Item.FullName -replace "(\[|\])",'`$1'
And then
Send-MailMessage -Attachments $Attachment
So I posted for and got some help with this script:
#Command to get list of folders with logfiles where the logfile is at least 30 minutes old send results to variable.
$varlogfile = Get-ChildItem -Path "drive:\folder" -Recurse -Include "logfile" | Where-Object {$_.LastWriteTime -le ((Get-Date).AddMinutes(-30))}
#Add a carriage return to results contained in the variable so email is easier to read
$varlogfile = $varlogfile -join "`r`n"
#Email setup from this line down to next comment
$SMTPServer = "email.server"
$From = "Administrator <administrator#place.com>"
$To = "email","email2"
$Subject = "A Logfile older than 30 minutes has been detected"
$Body = "Logfile(s) older than 30 minutes have been detected in the following folder(s):
$varlogfile
Please login and attempt to process the files manually, if the manual process fails, open a ticket with someone.
From the Admin
"
#Email setup above this line
#If statement that looks for the text blah in the variable, if found email is sent.
if($varlogfile -match "blah")
{
#Command to send email
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer
}
exit 0;
And all that is working perfectly.
Here's the thing though. Over the weekend sometimes we may get a stuck logfile that can't be resolved until Monday morning and it would be nice to be able to turn off alerts when this happens.
Now I'm very new to powershell and this script has been my learning experience. The way I see it is I have 3 choices:
Keep the get-childitem from returning a result if it sees logfile and logfile.stop.
After get-childitem has produced $varlogfile, search $varlogfile for logfile.stop and delete the lines logfile and logfile.stop from it.
Rewrite the whole thing from scratch and produce $varlogfile in a better way that makes it easier to work with the results.
Thoughts and opinions? I'm leaning toward method 2, as I think I can figure that out, but I'm curious if that is a way of pain. I'd really like your input on this.
Thanks people!
I think you're on the right path with your current plan, so I'll help you with approach #2, creating a .sent file when we send an email, to keep the emails from sending multiple times.
Our first step: When an e-mail is sent , we create a new file titles $logfile.MessageSent or something like that. Doing this allows an e-mail to be sent, and for us to also create a flag that we can search for later in the filesystem to determine whether or not we send another e-mail.
#If statement that looks for the text blah in the variable, if found email is sent.
if($varlogfile -match "blah")
{
#Command to send email
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer
New-Item -path $varLogfile.Sent -itemType File
}
Our second step: Modify our Get-ChildItem query to search for the flag:
$varlogfile = Get-ChildItem -Path "drive:\folder" -Recurse -Include "logfile" |
Where-Object {$_.LastWriteTime -le ((Get-Date).AddMinutes(-30))} |
? "($_.BaseName).sent" -notin (Get-ChildItem -Recurse -Include "*.sent" -Path "drive:\folder" | Where-Object {$_.LastWriteTime -le ((Get-Date).AddMinutes(-30))})
This second modification to the $varlogfile step is hard to understand, admittedly. Here is how I've changed it:
Get a lit of files in the drive\folder path, recursively and include logfile
Where the LastWriteTime is older than 30 mins
Where filename.sent is not found in the same directory
The only other thing you'll need to do is add a cleanup task to regularly delete the .sent files, and you're good to go.
Please let me know if you have any questions about this approach, as I want to be sure you understand and to help you learn.
I am trying to create a PowerShell script that will send an email to a list of people, but the email call is already embedded within a ping script. This is for a system that only has PowerShell v2.0.
Computers.txt contains a list of computers to be pinged and on failure will send an email.
This is my existing script I am trying to modify:
Get-Content -path "E:\Computers.txt" | ForEach-Object {
if (-not (Test-Connection -ComputerName $_ -Delay 2 -Quiet)) {
Send-MailMessage -To "email address" -Subject "$_ is Unreachable" -Body "$_ is unreachable by ping. Next check is in 5 minutes" -SmtpServer "server address" -From "another email address"
}
}
I know that I can use the Get-Content -path "E:\From_Email.txt" and Get-Content -path "E:\To_Email.txt" to call the list of email addresses, but I am not sure how to do this within the existing command. I have looked online, but I have not found how to nest calling additional text files within PowerShell for a script.
Do I need to call these files earlier and set them equal to a variable which gets called? Any help would be greatly appreciated. Thank you.
Assuming you have an email address on each line of "E:\To_Email.txt", the code below should work
$emails = (Get-Content "E:\To_Email.txt") -join ";"
Get-Content -path "E:\Computers.txt" | ForEach-Object {
if (-not (Test-Connection -ComputerName $_ -Delay 2 -Quiet)) {
Send-MailMessage -To $emails -Subject "$_ is Unreachable" -Body "$_ is unreachable by ping. Next check is in 5 minutes" -SmtpServer "server address" -From "another email address"
}
}
The extra first line reads in all lines of the email list file as an array, then joins it with semi-colons, which I think is how your email addresses should be separated. Worth checking though.
Example content of "E:\To_Email.txt"
person.one#yourdomain.whatever
person.two#yourdomain.whatever
person.three#yourdomain.whatever
person.four#yourdomain.whatever