Powershell Scripting regarding decrementing dates by one - powershell

Here is my script so far. My intention is to take the event log from the previous day and send it an email to myself every morning. This is my script so far.
(Get-EventLog -LogName Application -After "10/26/16" | ConvertTo-Html | set-content 'C:\Users\myusername\Documents\Powershell Outputs\1day event log.html')
$date= get-date
if ($date=get-date).AddDays(-1)
Else {"File Not Found"}`
Send-MailMessage -To "my email" -From "my email" -subject "Eventlog for Yesterday" -body "This is a daily sent automated email for the event log of the previous day." -Attachments "`
Now what am I doing wrong, Im brand new to powershell so go easy.

So the first thing you are going to want to do is get Yesterday in a DateTime, which is what I assume you were trying to do with $date and if ($date = (get-date).AddDays(-1))
Then let's put you log location in a variable, so that we can use it both in saving the log and then sending the attachment
The -After parameter uses the DateTime that we saved in $Yesterday. The path for Set-Content is then $logPath
#Get DateTime for Yesterday
$Yesterday = (Get-Date).AddDays(-1)
#Set the location of the log attachment
$logPath = 'C:\Users\myusername\Documents\Powershell Outputs\1day event log.html'
#Get the Event Log After Yesterday, Convert it to HTML, Save it to the logPath
Get-EventLog -LogName Application -After $Yesterday | ConvertTo-Html | Set-Content $logPath
#Send Mail Message with the logPath as an attachment
Send-MailMessage -To "my email" -From "my email" -subject "Eventlog for Yesterday" -body "This is a daily sent automated email for the event log of the previous day." -Attachments $logpath

Related

Check logs for errors regularly but prevent sending repetitive notifications

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

Sending output via Email from Powershell

See attached photo (link) of Output in PowerShell and Outlook.
I am trying to send output via email but having troubles getting the script to put the output in the body of the email. Instead of grabbing the Services Names and Expiration Dates that fall in-between the desired threshold (70 days), it is grabbing everything in the CSV (ex. see a Service that expires in 2022) and putting that into the body of the email.
My question is how do I have it email just the information that I pulled in PowerShell (the ones that fall between the specified threshold date)?
Somewhat newer to scripting, thanks! :)
$now=get-date
$cert = Import-Csv C:\Users\userID\Desktop\Certificate_CSV2.csv
$threshold = 70
$deadline = (Get-Date).AddDays($threshold)
$cert | Select-Object "Service Name", "Certificate Expiration Date" | Where-Object {$_."Certificate Expiration Date" -as [datetime] -le $deadline}
Send-mailMessage -to "SentTo#email.com" -subject "test message 8" -from "SentTo#email.com" -body ($cert | Out-String) -SmtpServer pobox.email.com
You're just printing out cert with the filter, not applying it back to cert. To fix, just set $cert equal to the filtered version of itself.
$cert = $cert | Select-Object "Service Name", "Certificate Expiration Date" | Where-Object {$_."Certificate Expiration Date" -as [datetime] -le $deadline}

Brackets cause error in Send-MailMessage -Attachment

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

Looking for advice on how to proceed with working powershell script

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.

PowerShell send email to list of addresses within another script

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