Script for sending e-mail - powershell

I found one script online, which does quite simple work - sends e-mail to the specified address after the trigger is hit.
In the example below script should scan the path which I stated for the trigger which is: #task, then it expected that it should send e-mail with the text after #td.
It should be correct, but when I run it nothing happens - what I'm doing wrong?
I've got the following message in powershell:
enter image description here
# Unregister-Event FileCreated
Unregister-Event FileChanged
# Email-settings
$loginuser = 'xxx#gmail.com'
$loginpassword = 'password;'
$smtpserver = 'smtp.gmail.com'
$smtpport = 587
$sendfrom = 'xxx#gmail.com'
$sendto = 'add.task.9270372.1523940684#todoist.net'
# Folder-settings
$folder = 'D:\Google Drive\Other\Nirvana' # Enter the root path you want to monitor.
$filter = '*.*' # You can enter a wildcard filter here.
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{IncludeSubdirectories = $false; NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite' }
# Trigger-settings
$trigger = '#task'
$lookfor = '#td'
$replaceto = '#intasklist'
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$fileContent = (Get-Content $folder$name)
# Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
if ($fileContent -match $trigger) {
$fileContent | Select-String -Pattern ".*$($lookfor)" -AllMatches | ForEach-Object { $_.Matches } | ForEach-Object { $secpasswd = ConvertTo-SecureString $loginpassword -AsPlainText -Force; $cred = New-Object System.Management.Automation.PSCredential ($loginuser, $secpasswd); Send-MailMessage -To $sendto -From $sendfrom -Subject $_.Value -Body $name -SmtpServer $smtpserver -Port $smtpport -Credential $cred -UseSsl
$fileContent | ForEach-Object { $_ -replace $lookfor, $replaceto -replace " $($trigger)", '' -replace $trigger, '' } | Set-Content $folder$name }
}}
# To stop the monitoring, run the following commands:
# Unregister-Event FileChanged

Related

Email Notification Powershell Getting 2 Emails

I have written a powershell script, to get an email notification when a file is saved in a certain folder. It works really well the first time anyone saves, but after that you get 2 emails anytime someone saves. Can you look at the code posted below and see what I did wrong exactly or why this might be happening?
$folder = "Folder Path"
$mailserver = "mail server"
$recipient = "Alerts#Email.com"
$fsw = New-Object System.IO.FileSystemWatcher $folder -Property #{
IncludeSubdirectories = $true
EnableRaisingEvents=$true
}
$created = Register-ObjectEvent -InputObject $fsw -EventName Created -SourceIdentifier CreatedEvent -Action {
$item = Get-Item $eventArgs.FullPath
$s = New-Object System.Security.SecureString
$anon = New-Object System.Management.Automation.PSCredential ("NT AUTHORITY\ANONYMOUS LOGON", $s)
If (($item -notlike '~') -And ([IO.Path]::GetExtension($item) -ne '.tmp')) {
Send-MailMessage -To $recipient `
-From "Email#Email.com" `
-Subject “File Creation Event” `
-Body "A file was created: $($eventArgs.FullPath)" `
-SmtpServer $mailserver `
-Credential $anon
}
}

Send Email of PowerShell Output

I'm new to PowerShell, I'm running Windows Server 2012 R2. The following Script gives me Output what I want but in the message the output is not appearing and it saying the Body cannot be "null" or "empty".
$fileToLocate = "*"
$Directories = #(
"C:\CtvFTPSite\AE1\ASN\Undelivered\",
"C:\CtvFTPSite\AE1\Invoices\Undelivered\",
"C:\CtvFTPSite\AE1\SO\Undelivered\",
"C:\CtvFTPSite\AE2\ASN\Undelivered\",
"C:\CtvFTPSite\AE2\Invoices\Undelivered\",
"C:\CtvFTPSite\AE2\SO\Undelivered\",
"C:\CtvFTPSite\BH1\ASN\Undelivered\",
"C:\CtvFTPSite\BH1\Invoices\Undelivered\",
"C:\CtvFTPSite\BH1\SO\Undelivered\",
"C:\CtvFTPSite\KW1\ASN\Undelivered\",
"C:\CtvFTPSite\KW1\Invoices\Undelivered\",
"C:\CtvFTPSite\KW1\SO\Undelivered\",
"C:\CtvFTPSite\OM1\ASN\Undelivered\",
"C:\CtvFTPSite\OM1\Invoices\Undelivered\",
"C:\CtvFTPSite\OM1\SO\Undelivered\",
"C:\CtvFTPSite\SA1\ASN\Undelivered\",
"C:\CtvFTPSite\SA1\Invoices\Undelivered\",
"C:\CtvFTPSite\SA1\SO\Undelivered\"
)
$filesUndelivered = Join-Path -Path $Directories -ChildPath $fileToLocate | Where-Object{Test-Path $_} | ForEach-Object{
Get-ChildItem $Directories -Recurse | % { Write-Host $_.FullName }
}
$Max_mins = "-5"
$Curr_date = get-date
$username = "myusername#myemail.com"
$password = Get-Content C:\security\string.txt | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
$localIpAddress = $(ipconfig | where {$_ -match 'IPv4.+\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' } | out-null; $Matches[1])
[string]$messagebody ="$filesUndelivered"
[string]$titlefailed ="Urgent You Have Files in Undelivered Folder in $localIpAddress in $env:computername"
$portno = "25"
$smtpsrv = "mail.server.com"
$smtpto = "myusername#myemail.com"
$smtpfrom ="myusername#myemail.com"
if ($filesfailed.Count)
{
foreach ($file in $filesUndelivered) {[string]$messagebody += $file.FullName + "`r`n"}
Send-MailMessage -To $smtpto -From $smtpfrom -port $portno -SmtpServer $smtpsrv -Credential $cred -Subject $titlefailed -Body $messagebody
}
Fixed
$fileToLocate = "*"
$failedpath = #(
"C:\CtvFTPSite\AE1\ASN\Undelivered\",
"C:\CtvFTPSite\AE1\Invoices\Undelivered\",
"C:\CtvFTPSite\AE1\SO\Undelivered\",
"C:\CtvFTPSite\AE2\ASN\Undelivered\",
"C:\CtvFTPSite\AE2\Invoices\Undelivered\",
"C:\CtvFTPSite\AE2\SO\Undelivered\",
"C:\CtvFTPSite\BH1\ASN\Undelivered\",
"C:\CtvFTPSite\BH1\Invoices\Undelivered\",
"C:\CtvFTPSite\BH1\SO\Undelivered\",
"C:\CtvFTPSite\KW1\ASN\Undelivered\",
"C:\CtvFTPSite\KW1\Invoices\Undelivered\",
"C:\CtvFTPSite\KW1\SO\Undelivered\",
"C:\CtvFTPSite\OM1\ASN\Undelivered\",
"C:\CtvFTPSite\OM1\Invoices\Undelivered\",
"C:\CtvFTPSite\OM1\SO\Undelivered\",
"C:\CtvFTPSite\SA1\ASN\Undelivered\",
"C:\CtvFTPSite\SA1\Invoices\Undelivered\",
"C:\CtvFTPSite\SA1\SO\Undelivered\"
)
$Max_mins = "-5"
$Curr_date = get-date
$username = "username#email.com"
$password = Get-Content C:\security\string.txt | ConvertTo-SecureString
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
$filesfailed = Get-ChildItem -Path $failedpath | Where{$_.CreationTime -lt ($Curr_date).addminutes($Max_mins)}
$localIpAddress = $(ipconfig | where {$_ -match 'IPv4.+\s(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' } | out-null; $Matches[1])
[string]$messagebody =""
[string]$titlefailed ="Urgent You Have Files in Undelivered Folder in $localIpAddress in $env:computername"
$portno = "25"
$smtpsrv = "mail.server.net"
$smtpto = "username#email.com"
$smtpfrom ="username#email.com"
if ($filesfailed.Count)
{
foreach ($file in $filesfailed) {[string]$messagebody += $file.FullName + "`r`n"}
Send-MailMessage -To $smtpto -From $smtpfrom -port $portno -SmtpServer $smtpsrv -Credential $cred -Subject $titlefailed -Body $messagebody
}

Powershell Scipt Runs in ISE only

I have researched this question quite a bit and have found others with similar issues, but no fix that works for us.
We have built a power shell script to monitor a folder for new images, check their color profile with exiftool and convert when needed with image magick. All of this functionality works well enough when the script is run in ISE, but will not work if the script is executed from a .exe or ran manually.
I have read that FileSystemWatcher requires the script be ran in STA which I have attempted to do a few times by including -STA in the target for the .exe shortcut. Doing so proves unsuccessful.
#----------------------------------------------------------------------------
Unregister-Event -SourceIdentifier FileCreated
Clear
#----------------------------------------------------------------------------
$description = Get-WmiObject -Class Win32_OperatingSystem |Select Description
$description = $description -Replace "#{Description=",""
$description = $description -Replace "}",""
$assetsFolder = "E:\" + $description + "\Capture One Session\Output"
$conversionStage = "C:\Profile_Pro\conversionStage"
#----------------------------------------------------------------------------
New-Item -ItemType directory -Force -Path "$assetsFolder" | Out-Null
New-Item -ItemType directory -Force -Path "$assetsFolder" | Out-Null
#----------------------------------------------------------------------------
$filter = "*.*"
$srgb = "sRGB IEC61966-2.1"
$isTif = "tif"
#----------------------------------------------------------------------------
$monitor = New-Object IO.FileSystemWatcher $assetsFolder, $filter -Property #{
IncludeSubdirectories = $true
NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
#----------------------------------------------------------------------------
$onCreated = Register-ObjectEvent $monitor Created -SourceIdentifier FileCreated -Action {
#----------------------------------------------------------------------------
Add-Type -AssemblyName System.Windows.Forms
#----------------------------------------------------------------------------
$path = $event.SourceEventArgs.FullPath
$name = $event.SourceEventArgs.Name
Write-Host $path
Write-Host $name
If ($name -Match $isTif)
{
$BOX = [System.Windows.Forms.MessageBox]::Show('TIFF FILE DETECTED. PLEASE CHECK RECIPE.', 'Warning', 'ok', 'Warning')
$path = $path -Replace ".tif.tmp",".tif"
Start-Sleep -s 2
Remove-Item "$path" -Force
}
Else
{
$colorSpace = C:\Profile_Pro\tools\exiftool.exe -T -ProfileDescription $path
$profileConvert = 'C:\Profile_Pro\tools\sRGB_Color_Space_Profile.icm'
If ($colorSpace -Match $srgb)
{
}
Else
{
Start-Sleep -s 3
$name = $name -Replace ".jpg.tmp",".jpg"
$path = $path -Replace ".jpg.tmp",".jpg"
Move-Item -Path $path -Destination $conversionStage -Force
convert $conversionStage\$name -profile $profileConvert $path
Start-Sleep -s 1
Remove-Item "$conversionStage\$name" -Force
#----------------------------------------------------------------------------
$BOX = [System.Windows.Forms.MessageBox]::Show('COLOR PROFILE ERROR. PLEASE CHECK RECIPE.', 'Warning', 'ok', 'Warning')
#----------------------------------------------------------------------------
$TO = $env:USERNAME + "#biz.com"
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
$Mail.To = $TO
$Mail.Subject = "COLOR PROFILE DEFECT: " + $name
$Mail.importance = 2
$Mail.Body = "A COLOR PROFILE DEFECT HAS BEEN DETECTED WITH FILE:`r`n`r`n$name`r`n`r`nTHIS FILE IS FIXED.`r`n`r`nPLEASE CHECK YOUR PROCESS RECIPE."
$Mail.Send()
}
}
}
#----------------------------------------------------------------------------
#Unregister-Event -SourceIdentifier FileCreated
#----------------------------------------------------------------------------
Any ideas to keep this script running as a .exe or outside of ISE would be greatly appreciated.

$Event.SourceEventArgs.<attribute> is returning a null or empty object

I have a FileSystemWatcher program that whenever an event is raised it sends an email notifying me of where the change happened.
However, $Event.SourceEventArgs.FullPath returns empty, and the other attributes returns $null.
Relevant code:
Function Watch{
$global:FileChanged = $false
$folder = "\\foo\boo\here\is\folder"
$filter = "*this is the filter*"
$watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true
EnableRaisingEvents = $true
}
# Start-Sleep -Seconds 1
Register-ObjectEvent $watcher "Changed" -Action {$global:FileChanged = $true} > $null
# Register-ObjectEvent $watcher "Created" -Action {$global:FileChanged = $true} > $null
# Register-ObjectEvent $watcher "Deleted" -Action {$global:FileChanged = $true} > $null
# $watcher.EnableRaisingEvents = $true
while($true){
while($global:FileChanged -eq $false){
Start-Sleep -Milliseconds 250
}
$global:FileChanged = $false
$paths = $Event.SourceEventArgs.FullPath
$name = $Event.SourceEventArgs.FileName
$changetype = $Event.SourceEventArgs.ChangeType
$TimeChanged = $Event.TimeGenerated
RunScript $paths, $name, $changetype, $TimeChanged
}
}
Function RunScript
{
param($paths, $name, $changetype, $TimeChanged)
Write-Host "This should work $paths $name $changetype $TimeChanged"
$From = "email"
$ToAddress = "email"
$MessageSubject = "Form Submitted by $paths"
$MessageBody = "File Path: $Event.SourceEventArgs.FullPath
Name: $name
Change Type?: $changetype
Time Changed: $timechanged"
$SendingServer = "999.999.999.9.9"
$SMTPMessage = New-Object System.Net.Mail.MailMessage $From, $ToAddress,
$MessageSubject, $MessageBody
$SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer
$SMTPClient.Send($SMTPMessage)
}
Watcher
Updated example. Note: I haven't tested this at all so be aware there are likely bugs. I've added some comments and a couple of different approaches for other sections of the code.
Function Watch {
$folder = "\\foo\boo\here\is\folder"
$filter = "*this is the filter*"
$watcher = New-Object IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubdirectories = $true
EnableRaisingEvents = $true
}
# Start-Sleep -Seconds 1
Register-ObjectEvent $watcher "Changed" > $null
# Register-ObjectEvent $watcher "Created" > $null
# Register-ObjectEvent $watcher "Deleted" > $null
# $watcher.EnableRaisingEvents = $true
while($true){
Wait-Event | Get-Event | ForEach-Object {
# $paths = $_.SourceEventArgs.FullPath
# $name = $_.SourceEventArgs.FileName
# $changetype = $_.SourceEventArgs.ChangeType
# $TimeChanged = $_.TimeGenerated
# If you comma-delimit this list you pass all of the arguments into "RunScript".
# Either name the parameters or make them positional.
# Positional:
# RunScript $paths $name $changetype $TimeChanged
# Named:
# RunScript -Paths $paths -Name $name -ChangeType $changetype -TimeChanged $TimeChanged
# Or use Splatting:
$params = #{
Paths = $_.SourceEventArgs.FullPath
Name = $_.SourceEventArgs.FileName
ChangeType = $_.SourceEventArgs.ChangeType
TimeChanged = $_.TimeGenerated
}
RunScript #params
}
}
}
Function RunScript {
param($paths, $name, $changetype, $TimeChanged)
Write-Host "This should work $paths $name $changetype $TimeChanged"
# $From = "email"
# $ToAddress = "email"
# $MessageSubject = "Form Submitted by $paths"
# $MessageBody = "File Path: $Event.SourceEventArgs.FullPath
# Name: $name
# Change Type?: $changetype
# Time Changed: $timechanged"
# $SendingServer = "999.999.999.9.9"
# $SMTPMessage = New-Object System.Net.Mail.MailMessage $From, $ToAddress,
# $MessageSubject, $MessageBody
# $SMTPClient = New-Object System.Net.Mail.SMTPClient $SendingServer
# $SMTPClient.Send($SMTPMessage)
# Is there a reason you're not using Send-MailMessage?
# Splatting again :)
# The body of the email isn't going to be very pretty, but it's a start.
$params = #{
From = "email"
To = "email"
Subject = "Form Submitted by $paths"
Body = "File Path: $paths
Name: $name
Change Type?: $changetype
Time Changed: $timechanged"
"
SmtpServer = "999.999.999.9.9"
}
Send-MailMessage #params
}
Now you get a caveat. The FileSystemWatcher is useful, but because of how Windows works you may well receive two event notifications for a single change (that's a deep Windows problem as opposed to a code problem). Try it and see.
Chris
Edit: Forgot to remove the action parameter. It's gone now.

Powershell + Robocopy Auto backup executing multiple times

I've put together this script to detect file changes in a directory, so that whenever the changes take effect the file(s) changed will get backed up right away.
I have also set up an email notification.
The backup works. I can see whenever a file changes it gets copied over to the desired destination, however I am receiving three emails and the robocopy log shows no changes, which leads me to think it's being written three times each time a file changes. So the last time it gets written there will of course be no changes.
Below you can see the code, hope you can help me figure out what's going on.
#The Script
$folder = 'C:\_Using Last Template Approach\' # Enter the root path you want to monitor.
$filter = '' # You can enter a wildcard filter here.
# In the following line, you can change 'IncludeSubdirectories to $false if required.
$fsw = New-Object IO.FileSystemWatcher $folder -Property #{IncludeSubdirectories = $true;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Changed -SourceIdentifier AutoBackUp -Action {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
$datestamp = get-date -uformat "%Y-%m-%d#%H-%M-%S"
$Computer = get-content env:computername
$Body = "Documents Folders have been backed up"
robocopy "C:\_Using Last Template Approach" G:\BackUp\ /v /mir /xo /log:"c:\RobocopyLog.txt"
Send-MailMessage -To "me#me.com" -From "jdoe#me.com" -Subject $Body -SmtpServer "smtp-mm.me.com" -Body " "
# To stop the monitoring, run the following commands (e.g using PowerShell ISE:
# Unregister-Event AutoBackUp
}
i do not change your monitor script just change send mail and copy with copy-item powershell command
$folder = 'c:\sites' # Enter the root path you want to monitor.
$filter = '*.*' # You can enter a wildcard filter here.
# In the following line, you can change 'IncludeSubdirectories to $true if required.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore white
Out-File -FilePath c:\sites\filechange\outlog.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"
$username=”gmailaccount”
$password=”password”
$smtpServer = “smtp.gmail.com”
$msg = new-object Net.Mail.MailMessage
$smtp = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$smtp.EnableSsl = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential( $username, $password )
$msg.From = "gmail"
$msg.To.Add(“mail should check notify”)
$msg.Body=”Please See archive for notification”
$msg.Subject = “backup information”
$files=Get-ChildItem “c:\sites\filechange\”
Foreach($file in $files)
{
Write-Host “Attaching File :- ” $file
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList S:\sites\filechange\$file
$msg.Attachments.Add($attachment)
}
$smtp.Send($msg)
$attachment.Dispose();
$msg.Dispose();
Copy-Item c:\sites\$name C:\a\$name }
i check this script work for me if change file content of file first email log file then copy them to destination c:\a\ also you and that file changed to attachment of mail