I tried several Scripts to email the status of HDD or RAM but its not working,
1st Time using PowerShell.
Windows Server 2012 R2
Script would get triggered by the event (when the Memory is low) and send the email with the details.
to get the Disk Stats i used
Get-EventLog -LogName System | Where-Object {$_.EventID -eq 2013}
How can i add this event to the email and make it appear in the message, i tried giving it a name like
$event Get-EventLog -LogName System | Where-Object {$_.EventID -eq 2013}
but i don't know how to add it to the message body its not like java or
$message.body = $body + $event
to send email this script works,
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$Username = "username#gmail.com"
$Password = "zxc"
$to = "help#x.com"
$cc = "help#x.ae"
$subject = "Low Disk Space"
$body = "The Server Disk is Low on memory"
$message = New-Object System.Net.Mail.MailMessage
$message.Subject = $subject
$message.Body = $body
$message.To.add($to)
$message.Cc.add($cc)
$message.From = $username
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.Send($message)
Write-Host "Mail Sent"
I read that the email alerts were discontinued by MS but people still have ways of doing it, unfortunately I didn't get it to work.
Something to help you get started on this:
# We first need to know which command to use
Get-Command '*mail*'
# We use the splatting technique to provide the parameters
$Params = #{
SmtpServer = 'smtp.gmail.com'
Port = '587'
From = $username
To = 'help#x.com'
Cc = 'help#x.ae'
Subject = 'Low Disk Space'
Body = 'The Server Disk is Low on memory.'
}
# Get-Help explains what this CmdLet does
Get-Help Send-MailMessage
# Get-Help can also give you examples on how to use the CmdLet
Get-Help Send-MailMessage -Examples
# Retrieve only events of the last 24 hours and select the first one
$Today = Get-Date
$Past = $Today.AddDays(-1)
$Event = Get-EventLog -LogName System -After $Past | Where-Object {$_.EventID -eq 6013} | Select-Object -First 1
# Add the event to the mail body
$Params.Body += ' ' + $Event.Message
# Send the mail
Send-MailMessage #Params
This script can then be added to the Task-Scheduler to run once a day.
SCHTASKS /Create /RU "SYSTEM" /SC DAILY /ST 17:30 /TN DailyHDDMemReport /TR "powershell -NoProfile -NoLogo -ExecutionPolicy Unrestricted -File 'C:\Temp\file.ps1'" /F
This will create a daily task that runs a powershell script specified at 5:30 as SYSTEM in conjunction with DarkLite1's answer.
After many writing may scripts and working on it, due to increased requirements script after script, the feature requirement made me in the end use the free option of the following tool.
Has more than needed
https://www.manageengine.com/network-monitoring/
Regards
Related
I'm attempting to create a PS script that does the following:
Run 2 programs located on the server
Check for error files
Attach the error files to the email
Wait for 5 minutes, rinse and repeat
I've got the below so far, I can get it working without the attachments, it just sends a link in the email. However I'd rather they be attachments.
Currently the error I'm getting is "Powershell.exe : A positional parameter cannot be found that accepts argument '$null'.".
But I've no idea why this is being generated?
Any advice would be appreciated.
#Hide powershell
Powershell.exe -windowstyle hidden {
#Make sure the program isn't running before starting the script
stop-process -Name WorksOrderCompletionImport
stop-process -Name WorksOrderIssuesImport
#Loop condition
While ($true)
{
$i++
#Bind location to string
$files=Get-ChildItem "E:\Production Siemens Interface Files\error"
#Binding the path to the string
$filechecker = 'E:\Production Siemens Interface Files\error\*.csv'
# Sender and Recipient Info for email
$MailFrom = "myemail#domain.com"
$MailTo = "myemail#domain.com"
# Sender Credentials
$Username = "myemail#domain.com"
$Password = "BadBoiPassword"
# Server Info
$SmtpServer = "smtp.office365.com"
$SmtpPort = "587"
# Message content
$Link = "\\SERVER1\E Drive\Production Siemens Interface Files\error"
$MessageSubject = "Errors have been generated in the Production Siemens Interface Files Folder"
$Message = New-Object System.Net.Mail.MailMessage $MailFrom,$MailTo
$Message.IsBodyHTML = $true
$Message.Subject = $MessageSubject
$Message.Body = #'
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Hello,</p>
<p>Please be advised that errors have been generated in the Siemens Integration Production Folder.</p>
<p>Please follow this link to check : Link to error files</p>
</body>
</html>
'#
#Start the programs
start-process -filepath "C:\Program Files\Datel Computing\Siemens Integration PRODUCTION\WorksOrderIssuesImport.exe"
start-process -filepath "C:\Program Files\Datel Computing\Siemens Integration PRODUCTION\WorksOrderCompletionImport.exe"
Start-Sleep -s 10
#If statement to control email
if (Test-Path $filechecker)
# Construct the SMTP client object, credentials, and send
{$Smtp = New-Object Net.Mail.SmtpClient($SmtpServer,$SmtpPort)
$Smtp.EnableSsl = $true
$Smtp.Credentials = New-Object System.Net.NetworkCredential($Username,$Password)
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList 'E:\Production Siemens Interface Files\error\'$file
$smtp.Attachments.Add($attachment)
$Smtp.Send($Message)}
else { Start-Sleep -s 10
}
#Stop the program
stop-process -Name WorksOrderCompletionImport
stop-process -Name WorksOrderIssuesImport
# Sleep for 300 seconds then loop back
Start-Sleep -s 300
}
}
You're using a lot .net references. I think you can simplify this by using the existing cmdlet Send-MailMessage. For example:
$PSEmailServer = "smtp.office365.com"
$smtpPort = "587"
$mailFrom = "myemail#domain.com"
$mailTo = "myemail#domain.com"
$messageSubject = "Errors have been generated in the Production Siemens Interface Files Folder"
$attachment = "E:\Production Siemens Interface Files\error\$file"
$body = #'
<p>Hello,</p>
<p>Please be advised that errors have been generated in the Siemens Integration Production Folder.</p>
<p>Please follow this link to check : Link to error files</p>
'#
Send-MailMessage -From $mailFrom -To $mailTo -Subject $messageSubject -Body $body -BodyAsHtml -Attachments $attachment -Port $smtpPort -UseSsl
See also: MS Reference Send-MailMessage
Ofcourse you need to supply your credentials for authentication. If you look at the documentation you'll see -Credential is one of the parameters. What you can do is:
# Define your Credentials
$username = 'your username'
$password= 'your password'
# Crete a credential Object
[SecureString]$secureString = $password | ConvertTo-SecureString -AsPlainText -Force
[PSCredential]$credentialObject = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $password
Add the -Credential parameter to the Send-Mailmessage command like -Credential $credentialObject
This is just to show you a way to accomplish what you want, but be careful with this method, because this way you store your password directly in the Script. There are solutions to encrypt your password in external files. You can find a good explanation on: https://pscustomobject.github.io/powershell/howto/Store-Credentials-in-PowerShell-Script/
I would like to create a batch file that gives me the memory of a needed file. For example, Chrome.exe. And send me an e-mail if the required memory is more than 1GB.
The application to be checked is on the terminal server and requires more and more memory. It should go to an e-mail to me, which tells me if the application requires more than 1GB of memory.
As info, the batch file will run on a terminal server. And is started by the task planning every 10 minutes.
I have tried so far.
powershell.exe -command send-mailmessage -to test#example.de -cc test.e#example.de
-from test#example.de -subject '"Batch-Testmail"'
-smtpserver smtp.testserver.de -body '"Testmail"'
That is just a sample.
And to check how much Workspace my programm needs. Chrome for example
dir C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
If you are asking for the amount of memory used by a running process, you could start experiencing on this by using the following command:
wmic process where name='chrome.exe' get WorkingSetSize
It will dump to the screen the amount of memory used by each of the Chrome tabs you have opened.
Hope it helps. :)
I took the sample from here:
https://superuser.com/questions/1128692/extract-used-ram-of-program-by-batch
Using, then, the details you provided about the email, you could do something like this:
$app_loaded=wmic process where "workingsetsize>=1000000000" get name
$EmailFrom = “yourgmailadress#gmail.com”
$EmailTo = “destination#somedomain.com”
$Subject = “The subject of your email”
$Body = “The application”.$app_loaded." is using more memory than expected."
$SMTPServer = “smtp.gmail.com”
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“usr”, “pass”);
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
Kind regards.
I also think a PowerShell solution is better. WMI is nice, we could also do it with Get-Process and Group-Object, e.g.
$mem = get-process | Group-Object -Property Chrome.exe |
Format-Table #{n='Mem';e={'{0:N0}' -f (($_.Group|Measure-Object WorkingSet -Sum).Sum / 1MB)};a='right'} -HideTableHeaders -AutoSize | Out-String
if($mem.Trim()/1 -gt 1024) {
$EmailFrom = "noreply#do.too"
$EmailTo = "you#do.too"
$Subject = "Memory Warning: $($mem.Trim()) MB accumulated"
$Body = "this is a notification from server x"
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($username, $credentials);
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
}
Try this?
#echo off
setlocal ENABLEDELAYEDEXPANSION
set CHROME_MEM=0
for /F "tokens=5" %%a in ('tasklist ^| find "chrome"') do (set MEM=%%a
set /A CHROME_MEM=!CHROME_MEM! + !MEM:,=!
)
echo Total Memory is %CHROME_MEM% K
The Solution is:
$mem = get-process | Group-Object -Property chrome.exe |
Format-Table #{n='Mem';e={'{0:N0}' -f (($_.Group|Measure-Object WorkingSet -Sum).Sum / 1MB)};a='right'} -HideTableHeaders -AutoSize | Out-String
if($mem.Trim()/1 -gt 1024) {
command send-mailmessage -to example#mail.com -cc examplecc#mail.com -from noreply#mail.com -subject '"Memory Warning: 1 GB accumulated"' -smtpserver smtp.server.com -body '"this is a notification from server x"' -priority High
}
We (our company) are runnning several scheduled tasks on a server. Recently some of the tasks started to fail on running. We'd like to query all the scheduled jobs reporting anyone whose last run result isn't 0x0 using powershell.
I've tried a lot of research for finding an easy way to do so, but only found scripts, that can query scheduled task by name (only to check one single task) but not by last run result. It wouldn't be helpful to add a new codeline for every newly intstalled scheduled task.
There is a quite similar entry on that topic, but as described above with the task name as parameter. (How to send email when SPECIFIC scheduled task fails to run)
$ScheduledTaskName = "Taskname"
$Result = (schtasks /query /FO LIST /V /TN $ScheduledTaskName | findstr "Result")
$Result = $Result.substring(12)
$Code = $Result.trim()
If ($Code -gt 0) {
$User = "admin#company.com"
$Pass = ConvertTo-SecureString -String "myPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential $User, $Pass
$From = "Alert Scheduled Task <task#servername>"
$To = "Admin <admin#company.com>"
$Subject = "Scheduled task 'Taskname' failed on SRV-001"
$Body = "Error code: $Code"
$SMTPServer = "smtp.company.com"
$SMTPPort = "25"
Send-MailMessage -From $From -to $To -Subject $Subject `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential $Cred
}
The code should be something like that, I guess
Get-ScheduledTask | where LastTaskResult -NE "0x0"
Use Get-ScheduledTaskInfo.
Get-ScheduledTask -TaskPath "\" | Where State -ne "Disabled" | Get-ScheduledTaskInfo | Where LastTaskResult -ne 0
In my example, I've just assumed you want tasks in the Task root, not any in the MS subfolders. If you store or care about tasks in the subfolders, then obviously modify the taskpath or identify the tasks you want some other way.
Get-ScheduledTaskInfo returns a bunch of properties that you can search/select. Excluding the Cim (WMI) properties, they are:
TaskName,TaskPath,LastRunTime,LastTaskResult,NextRunTime,NumberofMissedRuns
I am new to powershell and I am trying to write a script that will email me whenever someone moves or deletes a file or folder from a shared drive. I already set up the task scheduler to execute the script when one of those events happen. The problem that I have is that I execute script from the shell it provides me with all the information regarding the last entry in the event logs. However, when it runs from the task scheduler it does not execute. I believe that it has to do with the body line. Any suggestions or insights will be greatly appreciated.
This is my code:
$events = Get-EventLog -Logname Security -Newest 1
$From = $env:COMPUTERNAME + "#company.com"
$To = "me#company.com"
$Subject = $env:COMPUTERNAME + " " + $env:UserName + " " + $_.eventID
$Body = $events | format-list -property * | out-string
$SMTPServer = "exch"
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SMTPServer $SMTPServer
I have a script that gets all the information from the security log and has the event ID 4740. It then creates an html report from that and emails it. What I want to do is to exit the script if there is no data returned from $event.
# Created by Brad Tostenson 1/13/17
# This script will gather all the events with event ID 4740 (Account Locked Out)
# creates a report in HTML and emails it to the System Admins as the body
# of the email.
# Varaible the sets the reports temporary location
$LockedOut= "c:\temp\LockedOut.html"
# Setup date
$Date = Get-Date
# Sets up the report
$HTML=#"
<title>Account locked out Report</title>
<!--mce:0-->
"#
# Setup variables for the information to go under the headers in the report
$Account_Name = #{n='Account Name';e={$_.ReplacementStrings[-1]}}
$Account_domain = #{n='Account Domain';e={$_.ReplacementStrings[-2]}}
$Caller_Computer_Name = #{n='Caller Computer Name';e={$_.ReplacementStrings[-1]}}
# Pulls the information from the log
$event = Get-EventLog -LogName Security -InstanceId 4740 -after $date.AddHours(-24) |
Select TimeGenerated,ReplacementStrings,"Account Name","Account Domain","Caller Computer Name" |
% {
New-Object PSObject -Property #{
"Account Name" = $_.ReplacementStrings[-7]
"Account Domain" = $_.ReplacementStrings[5]
"Caller Computer Name" = $_.ReplacementStrings[1]
Date = $_.TimeGenerated
}
}
$event | ConvertTo-Html -Property "Account Name","Account Domain","Caller Computer Name",Date -head $HTML -body "<H2> The Following User Accounts Were Locked In Active Directory</H2>"|
Out-File $LockedOut -Append
# Takes the report and adds the information to the body of the email and sends it to the System Admins
$MailBody= Get-Content $LockedOut
$MailSubject= "Account Lock Report"
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "smtp.ourdomain.com"
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "LockedOut#ourdomain.com"
$MailMessage.To.add("email#ourdomain.com")
$MailMessage.Subject = $MailSubject
$MailMessage.IsBodyHtml = 1
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)
del c:\temp\LockedOut.html
I don't see why $event wouldn't be null if Get-EventLog returns no data, and null has a Boolean value of false. That means you can just do this:
if (!$event) { exit }
Or, if it makes more sense, you can do this:
if ($event) {
$event | ConvertTo-Html -Property "Account Name","Account Domain","Caller Computer Name",Date -head $HTML -body "<H2> The Following User Accounts Were Locked In Active Directory</H2>"|
Out-File $LockedOut -Append
# Takes the report and adds the information to the body of the email and sends it to the System Admins
$MailBody= Get-Content $LockedOut
$MailSubject= "Account Lock Report"
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "smtp.ourdomain.com"
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "LockedOut#ourdomain.com"
$MailMessage.To.add("email#ourdomain.com")
$MailMessage.Subject = $MailSubject
$MailMessage.IsBodyHtml = 1
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)
del c:\temp\LockedOut.html
}
Also, you might want to look at using the Send-MailMessage cmdlet. It's much simpler that what you're doing.
You also don't technically need the $LockedOut file at all, but I'm guessing you're using that in case the network is down or the email fails for some reason.