Writing a powershell script to monitor a log file - powershell

I am trying to write a script that will monitor a log file for time modified. If the file has been monitored on the last minute send me an email saying it is all good. IF the log file is older then a minute and the time is between 6am and 9pm send me an email. IF between 9pm and 6am reboot the server. except it is rebooting the server no matter what
# Set perameters here
$uncPath = 'Unc path to log file'
$Server = 'ServerName'
$min = Get-Date 06:00
$max = Get-Date 21:00
$now = Get-Date -Format hh:mm:ss
# Look at the Printstream Log Files and check last modified time
$files = (Get-ChildItem -Path $uncPath -Filter '*PrintstreamBroker*' -File |
Where-Object { $_.LastWriteTime -Gt (Get-Date).AddMinutes(-1) }).FullName
#If there file is good do nothing, and send email
if ($files) {
$Subject = 'Printstream Broker Is Running'
$message = 'The Printstream Broker Is Running There Is Nothing To Do'
$emailTo = '1#1.com'
}
Else ($min.TimeOfDay -lt $now -and $max.TimeOfDay -gt $now){
{
$Subject = 'Printstream Broker Is Not Running'
$message = 'Printstream Broker Is Not Running Please Log Into $servername and start the Printstream Monarch Broker'
$emailTo = '1#1.com'
}
}
Else {
Restart-Computer –ComputerName $server -Force
$Subject = 'Monarch Server Rebooted'
$message = 'The Monarch Server Has Been Rebooted'
$emailTo = '1#1.com'
}
}
# create a email
$mailParams = #{
From = 'PrintstreamBrokerDEV#visionps.com'
To = $emailTo
Subject = $Subject
Body = $message
SmtpServer = 'smtpserver'
# any other parameters you might want to use
}
# send the email
Send-MailMessage #mailParams

You have if else else.
It should be if elseif else.

Related

Sending email with CSV from a Running Process check

I'm trying to check if a process is running on a remote computer (Eventually will be about 100 computers). If the process is not running, I'd like it to put the computername/IP into a CSV and then email that out. If the process is running on all machines, I'd like the script to not send an email out at all. To do this, I'd like to test the machines first to check they're online (If they're offline, we've either got bigger problems or it's off for a reason, but that's not what this process is checking for.
I'm going to be testing this script on a few machines with just the notepad process at the moment as it's something I can do on a test machines reletively quickly.
I'm a little stuck at the moment, because I don't know how to get the results from the process check to be put into a CSV and then emailed. In the code snippet below, it's not generating the outfile, but have left the variable I was testing with and the path to where the attachment would be in the send-mailmessage. Any advice will be appreciated, I'm still learning powershell at the moment so don't know all the tricks and tips yet.
Cheers
# Mail server Configuration
$MailServer = "mail.server.co.uk"
$MailFrom = MailFrom#server.co.uk"
# Mail Content Configuration
$MailTo = "Recipient#Server.co.uk"
$MailSubjectFail = "INS Process not running on $DAU"
$MailBodyFail = "The INS Process on the DAU $DAU is not running. Please manually start process on DAU $DAU"
# Process Info
$Process = "Notepad"
$ProcessIsRunning = { Get-Process $Process -ErrorAction SilentlyContinue }
#Results Info
$Exportto = "C:\Scripts\Content\INSChecker\Results.csv"
# Get DAU Information
foreach($line in (Get-Content C:\Scripts\Content\INSChecker\INSList.cfg)){
$line = $line.split(",")
$DAU = $line[0]
$DAUIP = $line[1]
# Test Connection to INS DAU
write-host "Testing: $DAU / $DAUIP"
$TestDAU = Test-Connection $DAU -quiet
$TestDAUIP = Test-Connection $DAUIP -quiet
write-host "Tests: $TestDAU / $TestDAUIP"
If($TestDAU -ne 'True'){
If($TestDAUIP -ne 'True'){
write-host "DNS Not resolved for $DAU"
Write-Output "INS $DAU/$DAUIP is OFFLINE" | Out-File C:\Scripts\Content\INSChecker\INSProcessCheck.log -append
}
}
Else{
# Get Process Running State and Send Email
if(!$ProcessIsRunning.Invoke()) {
Send-MailMessage -To $MailTo -From $MailFrom -SmtpServer $MailServer -Subject $MailSubjectFail -Body $MailBodyFail -Attachments C:\Scripts\Content\INSChecker\Results.csv
} else {
"Running"
}
}
}
Hopefully this gives a you a hint on where to begin and how to approach the problem, I have removed the irrelevant parts of the script and only left the logic I would personally follow.
The result of $report should be an object[] (object array) which should be very easy to manipulate and very easy to export to CSV:
#($report).where({ $_.SendMail }) | Export-Csv $exportTo -NoTypeInformation
I'll leave you the remaining tasks (attach the CSV, send the emails, etc) for your own research and design.
$ErrorActionPreference = 'Stop'
# Process Info
$Process = "Notepad"
$ProcessIsRunning = {
param($computer, $process)
# On Windows PowerShell -ComputerName is an option,
# this was removed on PS Core
try
{
$null = Get-Process $process -ComputerName $computer
# If process is running return 'Running'
'Running'
}
catch
{
# else return 'Not Running'
'Not Running'
# send a Warning to the console to understand why did this
# fail ( couldn't connect or the process is not running? )
Write-Warning $_.Exception.Message
}
}
#Results Info
$ExportTo = "C:\Scripts\Content\INSChecker\Results.csv"
$exportProps = 'Server', 'IP', 'Ping', 'DNSResolution', 'Process', 'SendMail'
# Get DAU Information
$report = foreach($line in Get-Content path/to/file.txt)
{
$status = [ordered]#{} | Select-Object $exportProps
$DAU, $DAUIP = $line = $line.split(",")
$status.SendMail = $false
$status.Server = $DAU
$status.IP = $DAUIP
# Test ICMP Echo Request and DNS Resolution
$ping = Test-Connection $DAUIP -Quiet
$dns = Test-Connection $DAU -Quiet
$status.Ping = ('Failed', 'Success')[$ping]
$status.DNSResolution = ('Failed', 'Success')[$dns]
$status.Process = & $ProcessIsRunning -computer $DAUIP -process $Process
if(-not $ping -or -not $dns -or $status.Process -eq 'Not Running')
{
$status.SendMail = $true
}
[pscustomobject]$status
}
#($report).where({ $_.SendMail }) # => This is what should be mailed

Powershell - Check IP, loop to retry and send email

I've been trying to script so powershell checks our external ip - if its unchanged - do nothing just log its been checked.
If the script thinks its changed, retry, and if after 5 attempts it has changed then send an email.
I've included where I got to, but I can't (tiredness or stupidity) get this to work today so throwing this out to the hive mind for help!
attached is where ive got too! Cheers CM
#find old ip
$oldip = gc .\ip.txt
#get current ip address
$currentip = (New-Object net.webclient).downloadstring("http://api.ipify.org")
#current date and time
$currentTime = Get-Date -format "dd-MMM-yyyy HH:mm:ss"
#script location
$scriptpath = $MyInvocation.MyCommand.Definition
[string]$dir = Split-Path $scriptpath
set-location $dir
#set the smtp server URL here
$smtpServer = "smtp.my.com"
#Set the Sender Name or Email here
$sender = "sender#my.comm"
#Enter the email reciepients here - you can send to multiple using format: "user1#gmail.com", "user2#hotmail.com";
$users = "email#my.com";
#Enter the subject title the reciepient see's here
$subject = "IP Has Changed"
#Type out the email contents here
$body = "Dear Team Member,
Your IP address at has just changed from: $oldip
And is now set too: $currentip
Regards."
#*****************************************************************************************************************************************
do {
$Result = ($oldip -ne $currentip)
if ($Result.Status -eq "Success") {
Write-Output "IP Address Unchanged - Monitoring Continues."
Add-Content $PSScriptRoot\IP_Check_Log.txt "$currentTime - IP Unchanged. "
Start-Sleep -s 2
Exit 0
}
else {
Write-Output "Ping Failed!"
Add-Content $PSScriptRoot\IP_Check_Log.txt "$currentTime - IP Check Failed - Retrying"
$Failures += 5
}
} until ($Failures -ge $FailureThreshold)
Write-Output "IP Address Changed!"
Add-Content $PSScriptRoot\IP_Check_Log.txt "$currentTime - IP Adderss Changed. "
Add-Content $PSScriptRoot\IP_Check_Log.txt "*****************************************************************************"
#be sure to alter the SMTP server port here if needed.
$smtp = New-Object Net.Mail.SmtpClient($smtpServer, 587)
$smtp.EnableSsl = $true
#Enter the sending email address and password here
$smtp.Credentials = New-Object System.Net.NetworkCredential("email#my.com", "password");
$smtp.Send($sender, $user, $subject, $body)
Perhaps easier than a do{..} until(..) here is to loop using a for loop and I would use a try{..} catch{..} on this.
Inside the loop get the ip address fresh, don't get that once and keep looping over that instance.
Something like this perhaps (left out the emailing stuff)
$logFile = Join-Path -Path $PSScriptRoot -ChildPath 'IP_Check_Log.txt'
$FailureThreshold = 5
# find old ip
$oldip = [IPAddress](Get-Content .\ip.txt)
$ipchanged = $false
$currentip = $null
for ($i = 0; $i -lt $FailureThreshold; $i++) {
try {
# try to get the get current ip address
$currentip = [IPAddress](New-Object net.webclient).DownloadString("http://api.ipify.org")
if ($currentip -eq $oldip) {
Write-Output "IP Address Unchanged - Monitoring Continues."
Add-Content -Path $logFile -Value "$currentTime - IP Unchanged. "
exit 0
}
else {
$ipchanged = $true
}
}
catch {
$currentip = $null
$ipchanged = $false
Write-Output "Ping Failed!"
Add-Content -Path $logFile -Value "$currentTime - IP Check Failed - Retrying"
}
Start-Sleep -Seconds 2
}
# test if the above returned a $currentip not $null and if boolean $ipchanged is $true
if (($currentip) -and $ipchanged) {
Write-Output "IP Address Changed!"
Add-Content -Path $logFile -Value "$currentTime - IP Address Changed. "
Add-Content -Path $logFile -Value "*****************************************************************************"
# refresh the .\ip.txt file to store the new ip?
Set-Content -Path .\ip.txt -Value $currentip.IPAddressToString
# send the email
}
I use casts to [IPAddress] because if the .DownloadString() fails OR it returns something which is not an IP address, you will enter the catch block so you can deal with the error

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

Send mail from result (should be easy)

I have built a script to check for local machine certificates from a certain issuer expiring within 400.000 days (to get a hit when testing it) on remote server, but i cant just figure out how to get the result to send the actual email as experimenting with pipes after (and in) the IF statements doesnt seem to work.
I have been googling quiet alot (ofcourse) but as I'm new to Powershell and some code is difficult at times to interpret.
I am looking for something like; if $OutputFromtheIFStatement | Measure-Object -gt 0 { Send email using $SendReportNow.}
My code:
$Servers = 'testserver1,'testserver2'
$Threshold = 400000
$Deadline = (Get-Date).AddDays($Threshold)
$MailSMTP = '-SmtpServer smtpserver.domain.com -Port 25'
$MailTo = "receiversmailaddress#company.com"
$MailFrom = "sendersmailaddress#company.com"
$MailSubject = '-Subject Certifikat expiring within 90 days'
$MailBody = '-Body ?'
$SendReportNow = 'Send-MailMessage $MailSMTP $MailFrom $MailTo $MailSubject'
Invoke-Command -ComputerName $Servers { Get-ChildItem Cert:\LocalMachine\My } | ForEach {
If ($_.NotAfter -le $Deadline -and $_.Issuer -like '*CertainCompanyName*') { $_ | Select #{Label="Servername";Expression={($_.PSComputerName)}}, Issuer, Subject, #{Label="Expiry Date & Time";Expression={($_.NotAfter)}}, #{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}}
}
}
I cleaned your code up, hopefully this is easier to digest.
$Servers = 'testserver1','testserver2'
$Threshold = 400000
$Deadline = (Get-Date).AddDays($Threshold)
$certs = Invoke-Command -ComputerName $Servers { Get-ChildItem Cert:\LocalMachine\My }
ForEach ($cert in $certs){
If ($cert.NotAfter -le $Deadline -and $cert.Issuer -like '*CertainCompanyName*') {
$body = $cert | Select #{Label="Servername";Expression={($cert.PSComputerName)}}, Issuer, Subject, #{Label="Expiry Date & Time";Expression={($cert.NotAfter)}}, #{Label="Expires In (Days)";Expression={($cert.NotAfter - (Get-Date)).Days}}
$MailSubject = "[$($cert.PsComputerName)] Certifikat expiring within 90 days"
Send-MailMessage -SmtpServer smtpserver.domain.com -Port 25 -From sendersmailaddress#company.com -To receiversmailaddress#company.com -Subject $MailSubject -Body $body
}
}
This will result in e-mails being sent like this:
Title: [ServerA] Certifikat expiring within 90 days
----- Body-------
Servername : ServerA
Issuer : CN=localhost
Subject : CN=localhost
Expiry Date & Time : 4/5/2020 8:00:00 PM
Expires In (Days) : 1627