I have a exe file that is executed every day by the Task Scheduler on my Windows 2008. If that script should fail to start, or if the script fails during execution, I would like to get an email notification.
There are many examples of getting Task Schedular to send an email based on an event log entry. However, I only want to be notified if MY particular scheduled task fails, not get a notification for all tasks that fails with an EventID 203/103/201. How can I do that without any custom software?
Create a new Task that runs this PowerShell Script.
$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
}
I just wanted to add to this post just in case someone has a similar challenge on later server o/s. There is now a PowerShell cmdlet to get Scheduled Task information.
$ScheduledTaskName = 'Taskname'
(Get-ScheduledTaskInfo -TaskName $ScheduledTaskName).LastTaskResult
Related
So here is the deal. I have a script that kicks in once the AC adapter gets disconnected, and when that happens I also want the script to send me an text message via messages.google.com.
I am pretty new to PS, and im completely lost when it comes to HTML, so im not sure what I am supposed to look for at the website.
$url = "https://messages.google.com/web/conversations"
try {
$chrome = (Get-ItemProperty "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe").'(Default)'
Start-Process "$chrome" $url
}
catch {
Start-Process $url
Start-sleep -Seconds 5
($chrome.document.getElementsByClassName("fab-link mat-button mat-button-base") | select -first 1).click()
Start-Sleep -Seconds 5
($chrome.document.getElementsByClassName("input") | select -first 1).value = "95******"
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
Start-Sleep -Seconds 5
($chrome.document.getElementByClassName("input-row") | select -first 1).value = "HS3 har mistet strøm"
Start-Sleep -Seconds 5
($chrome.document.getElementByClassName("send-info ng-star-inserted") | select -first 1).click()
Start-Sleep -Seconds 5
Stop-Process -Name chrome
}
No idea how to make this work, hope anyone out there can help, thanks in advance :)
The try & catch does not make alot of sense if you use them like that. You can use that to handle ("catch") error messages -> see About Try Catch Finally.
If I were you I would go the easy way and send myself e-mails instead.
[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$username = "sender#gmail.com"
$password = ConvertTo-SecureString "yourPasswordHere" -AsPlainText -Force
$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$From = "sender#gmail.com"
$To = "recipient#gmail.com"
#$Cc = "YourBoss#YourDomain.com"
$Attachment = "C:\test\test.txt"
$Subject = "Test"
$Body = "To Whom It May Concern,`n`nthe bike is on fire,`nyou're on fire,`neverything is on fire,`nand you're in hell.`n`nRegards, YourSysAdmin"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $creds -Attachments $Attachment
See: PowerShell: Sending Email With Send-MailMessage (Gmail example)
But you will have to disable Less secure app blocked in Gmail.
If however you really really really want to send text messages instead, I'd suggest you either
get a commercial application that sends sms for you
or
you can find out how to send messages to i.e. Google Hangouts with XMPP
or
use Pidgin and write some code to send the messages remotely. There is a plug-in called purple-remote that you might be able to utilize.
If you still want to go for the method whereby you interact with Chrome, you can use Selenium as shown here: PowerShell & Selenium: Automate Web Browser Interactions – Part I
Basically I want to switch user in powershell in the same window (dont want to open a new one).
$username = "xxxxx"
$password = ConvertTo-SecureString "xxxxx" -AsPlainText -Force
$creds = New-Objet System.Management.Automation.PSCredential $username,$password
Start-Process powershell.exe -NoNewWindow -Credential $creds
But instead of launching powershell in same window it launches it in a new window which doesnt even work I cant type anything into its just a blinking cursor.
First things first, try to describe what you need to do in detail since the approach you're using might be misguided. Are you just trying to run commands as a different user within a script? If so, use the methods described here : https://www.itdroplets.com/run-a-command-as-a-different-user-in-powershell/
I particularly like the start-job method which I use sometimes, example:
#Shows who is the current user
whoami
""
$username = "DOMAIN\USER"
$password = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential $username,$password
$GetProcessJob = Start-Job -ScriptBlock {
#Shows who is the current user, in this case it's the user you provided credentials for. Everything in this scriptblock will run in his context.
whoami
} -Credential $Credential
#Wait until the job is completed
Wait-Job $GetProcessJob | Out-Null
#Get the Job results
$GetProcessResult = Receive-Job -Job $GetProcessJob
#Print the Job results
$GetProcessResult
If you truly just want to just launch another powershell.exe process as another user,
the only way I know of would be to simply start the new process and exit the first one after that command, this way you have only the new window running as the user provided.
$username = "DOMAIN\USER"
$password = ConvertTo-SecureString "PASSWORD" -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential $username,$password
Start-Process powershell.exe -Credential $creds ;Exit
A task job is running by task scheduler every 30 mins everyday.
I just want one more task to monitor whether the task is completed or not.
Would you please give me the powershell script as necessary below.
Sorted by Event id : 101 and 102, specified task job name, action time, the job result in the last 24 hours,
I want to have log txt file into C drive. I guess it should be used "Get-WinEvent"...
Otherwise if you know it's simple way to export the result log automatically(Task completed or not)
on daily base, please let me know.
Thank you
See these examples to inspire you to what you are after. Once you've tried some things, well, you know.
Powershell Script to Monitor Scheduled Tasks
https://social.technet.microsoft.com/Forums/windows/en-US/dc607f76-02c1-489f-b519-340b0faf8fcd/powershell-script-to-monitor-scheduled-tasks
$servername = "tome-mac"
$schedule = new-object -com("Schedule.Service")
$schedule.connect($servername)
$tasks = $schedule.getfolder("\").gettasks(0)
$tasks |select name, lasttaskresult, lastruntime
Make Windows Task Scheduler alert me on fail
https://superuser.com/questions/249103/make-windows-task-scheduler-alert-me-on-fail
$ScheduledTaskName = "Hans\Backup"
$Result = (schtasks /query /FO LIST /V /TN $ScheduledTaskName | findstr "Result")
$Result = $Result.substring(12)
$Code = $Result.trim()
If ($Code -gt 0) {
$User = "mymail#gmail.com"
$Pass = ConvertTo-SecureString -String "myPassword" -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential $User, $Pass
################################################################################
$From = "Alert Scheduled Task <mymail#gmail.com>"
$To = "Me Gmail <mymail#gmail.com>"
$Subject = "Scheduled task 'Backup' failed"
$Body = "Error code: $Code"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Subject $Subject `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential $Cred
}
Or just use these module(s) to determine if they can assist you in your use case.
https://www.powershellgallery.com/packages/TaskScheduler/1.0
https://gallery.technet.microsoft.com/scriptcenter/Schedule-Task-Monitor-a7c74403
I am trying to run a perl script whenever there is a service crash. The perl script intends to restart the service and send a mail to all the developers.
I have used windows recovery options for that, where it has an option to run a program . I have filled the required details in the command line option but the script doesn't seem to get executed. Can you please help me by sharing your knowledge on this?
Recovery tab configuration
I have tried with Restart service option and that is working fine but the run a program isn't executing the script. Am I missing something?
Any comment on this will be helpful.
I recently implemented a recovery option to run a powershell script that attempts to restart the service a defined number of times and sends an email notification at the conclusion, it also attaches a txt file with recent relevant logs.
After several attempts (and despite all the other things I have seen) The configuration of fields on the recovery tab in services is as follows:
Program: Powershell.exe
**Not C:\Windows\System32\WindowsPowerShell\v1.0\Powershell.exe
Command line parameters: -command "& {SomePath\YourScript.ps1 '$args[0]' '$args[1]' '$args[n]'}"
eg: -command "& {C:\PowershellScripts\ServicesRecovery.ps1 'Service Name'}"
**The $args are parameters that will be passed to your script. These are not required.
here is the powershell script:
cd $PSScriptRoot
$n = $args[0]
function CreateLogFile {
$events = Get-EventLog -LogName Application -Source SomeSource -Newest 40
if (!(Test-Path "c:\temp")) {
New-Item -Path "c:\temp" -Type directory}
if (!(Test-Path "c:\temp\ServicesLogs.txt")) {
New-Item -Path "c:\temp" -Type File -Name "ServicesLogs.txt"}
$events | Out-File -width 600 c:\temp\ServicesLogs.txt
}
function SendEmail {
$EmailServer = "SMTP Server"
$ToAddress = "Name#domain.com"
$FromAddress = "Name#domain.com"
CreateLogFile
$Retrycount = $Retrycount + 1
send-mailmessage -SmtpServer $EmailServer -Priority High -To $ToAddress -From $FromAddress -Subject "$n Service failure" `
-Body "The $n service on server $env:COMPUTERNAME has stopped and was unable to be restarted after $Retrycount attempts." -Attachments c:\temp\ServicesLogs.txt
Remove-Item "c:\temp\ServicesLogs.txt"
}
function SendEmailFail {
$EmailServer = "SMTP Server"
$ToAddress = "Name#domain.com"
$FromAddress = "Name#domain.com"
CreateLogFile
$Retrycount = $Retrycount + 1
send-mailmessage -SmtpServer $EmailServer -Priority High -To $ToAddress -From $FromAddress -Subject "$n Service Restarted" `
-Body "The $n service on server $env:COMPUTERNAME stopped and was successfully restarted after $Retrycount attempts. The relevant system logs are attached." -Attachments c:\temp\ServicesLogs.txt
Remove-Item "c:\temp\ServicesLogs.txt"
}
function StartService {
$Stoploop = $false
do {
if ($Retrycount -gt 3){
$Stoploop = $true
SendEmail
Break
}
$i = Get-WmiObject win32_service | ?{$_.Name -imatch $n} | select Name, State, StartMode
if ($i.State -ne "Running" -and $i.StartMode -ne "Disabled") {
sc.exe start $n
Start-Sleep -Seconds 35
$i = Get-WmiObject win32_service | ?{$_.Name -imatch $n} | select State
if ($i.state -eq "Running"){
$Stoploop = $true
SendEmailFail}
else {$Retrycount = $Retrycount + 1}
}
}
While ($Stoploop -eq $false)
}
[int]$Retrycount = "0"
StartService
I know very little about scripting, but I think what I want is possible. I would simply like to get an email notification when a file is added to a particular folder. I don't have any specific software, so I guess it would have to be a batch file or maybe VBS?
You can do this, in a batch-file with powershell enabled:
#echo off
setlocal EnableDelayedExpansion
set "emailUserName=dummyEmail#gmail.com"
set "emailPassword=dummyPassword"
set "target=yourEmail#email.com"
set "subject=File Changed"
FOR %%G IN (*) DO attrib -A "%%G"
:loop
set "body="
FOR %%G IN (*) DO (
attrib "%%G" | findstr /B /L A 1>nul
if !errorlevel! equ 0 (
echo "%%G"
set "body=!body!^<br ^/^>%%G"
attrib -A "%%G"
)
) 2>nul
if not "%body%"=="" echo sending email
if not "%body%"=="" set "body=The following files have been changed:!body!"
if not "%body%"=="" powershell.exe -command "Send-MailMessage -From '!emailUserName!' -to '!target!' -Subject '!subject!' -Body '!body!' -BodyAsHtml -SmtpServer 'smtp.gmail.com' -port '587' -UseSsl -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ('!emailUserName!', (ConvertTo-SecureString -String '!emailPassword!' -AsPlainText -Force)))"
goto :loop
For this to work, you need to create a dummy gmail acount that will send the email. This supports HTML tags in the body, as shown in the example.
Note that this doesn't work on deletion of files, only changes and new files.
Do you have information about your email server? What version of Windows and Powershell do you have?
This short Powershell script works in my environment:
$folder = "D:\"
$mailserver = "your.mailserver.your.company"
$recipient = "your.email#your.company"
$fsw = New-Object System.IO.FileSystemWatcher $folder -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'FileName'
}
$created = Register-ObjectEvent $fsw -EventName Created -Action {
$item = Get-Item $eventArgs.FullPath
$s = New-Object System.Security.SecureString
$anon = New-Object System.Management.Automation.PSCredential ("NT AUTHORITY\ANONYMOUS LOGON", $s)
Send-MailMessage -To $recipient `
-From "alerts#your.company" `
-Subject “File Creation Event” `
-Body "A file was created: $($eventArgs.FullPath)" `
-SmtpServer $mailserver `
-Credential $anon
}
Stop the alerts with this:
Unregister-Event -SourceIdentifier Created -Force
I built my solution based on what #xXhRQ8sD2L7Z contributed. But I was getting multiple emails as I tested, a new one for every time I ran the register script. The Unregister line was not working:
Unregister-Event -SourceIdentifier Created -Force
So I found this: Unregister a registered filewatcher event does not work
Get-EventSubscriber -SourceIdentifier "filechanged" | Unregister-Event
but it still wasn't working, so I ran Get-EventSubscriber by itself and got a list of the Subscriptions for the Event and found that, in my case, the -SourceIdentifier was a GUID. With that understanding, I grabbed each individual GUID and proceeded to unregister them. (I could've looped through them, but I will only use this once, probably. Plus, I had only created the subscription 6 times before I realized what was happening)
This eliminated all of the extra emails i received every time I tested.
Get-EventSubscriber -SourceIdentifier "<very long GUID>" | Unregister-Event
Then I wanted to send to multiple recipients, so i found this: Powershell send-mailmessage - email to multiple recipients
$recipients = "<User1#domain.com>", "<User2#domain.com>"
You can also use email distribution groups.