Powershell script sends email for every file, only need one email - powershell

My script is set to check a directory for files older than 2 days and then an email is sent to the group to submit. If there are files in the directory that were submitted within 2 days, they are thanked. However, the foreach is killing me with multiple emails when multiple files are there. Is there a way to only send one email regardless of the number of files?
$path = "C:\testing\Claims"
Foreach($file in (Get-ChildItem $path *.txt -Recurse))
{
If($file.LastWriteTime -lt (Get-Date).adddays(-2).date)
{
Send-MailMessage `
-From emailer#email.com `
-To me#email.com`
-Subject "File Not Received" `
-Body "Your claims files for this week not available. Please submit them ASAP so that processing can begin." `
-SmtpServer smtp.smtp.com
}
Else
{
Send-MailMessage `
-From email#email.com `
-To me#email.com`
-Subject "File Received" `
-Body "We have received your file for this week. Thank you!" `
-SmtpServer smtp.smtp.com
}
}

Simply check the number of files that were submitted within the last 2 days and send your mails depending on that number:
$path = "C:\testing\Claims"
$twoDaysAgo = (Get-Date).AddDays(-2).Date
$submitted = Get-ChildItem $path *.txt -Recurse |
? { $_.LastWriteTime -ge $twoDaysAgo }
if (#($submitted).Count -eq 0) {
Send-MailMessage `
-From emailer#email.com `
-To me#email.com`
-Subject "File Not Received" `
-Body "Your claims files for this week not available. Please submit them ASAP so that processing can begin." `
-SmtpServer smtp.smtp.com
} else {
Send-MailMessage `
-From email#email.com `
-To me#email.com`
-Subject "File Received" `
-Body "We have received your file for this week. Thank you!" `
-SmtpServer smtp.smtp.com
}

Related

Powershell Script to send email after validation

I have a Powershell script that logs the result to a text file (this is working fine), now I need to update it to send email instead of a Log file (see actual script below). I'm kind of a new to powershell, hopefully you can help me out.
# details of the script
# if a file "FILE.400" is found and check the modified date, it will send a log file (txt file)
# need to update the script, to send email instead of a log file
$svr=$env:ComputerName
$date=[datetime]::Today.ToString('MM-dd-yyyy')
$filename = "FILE.400"
$DestLogs1 = "E:\sample\pfupdatedfin-$date.txt"
$DestLogs2 = "E:\sample\pfoutdatedfin-$date.txt"
$SrcPath = "E:\sample\$filename"
If ((Get-ChildItem $SrcPath).LastWriteTime -gt $date)
{
$date | Out-File $DestLogs1
Write-Output "Found latest FILE.400 file" | Out-File $DestLogs1 -Append
(Get-ChildItem -Recurse -Path $SrcPath).LastWriteTime | Out-File $DestLogs1 -Append
}
Else
{
Write-Output "FILE.400 - is not updated, please verify " | Out-File $DestLogs2
(Get-ChildItem -Recurse -Path $SrcPath).LastWriteTime | Out-File $DestLogs2 -Append
}
Send-MailMessageis pretty easy to use. The online documentation for cmdlets is very easy to find. Just enter the name of the cmdlet in your favorite search engine. Or use the Get-Help cmdlet. Here is an example how to use it just fille the Variables reasonably :
Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Port $SMTPPort -Credential $Credential # -UseSsl:$UseSsl
-useSsl is a switch so it is not necessary unless it's $true. If you want to provide a variable to a switch parameter, don't use a whitespace but a : in between.
Credentials in Powershell are stored in credential objects. You can't just use a plain text password. However don't think they are stored extremly save since the password can be easly extracted if you know how. Here is how you create the necessary credential object:
$SecPw = ConvertTo-SecureString -AsPlainText $Password -Force
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName,$SecPw
the script is working as expected, in my Home network
$svr=$env:ComputerName
$date=[datetime]::Today.ToString('MM-dd-yyyy')
$filename = "FILE.400"
$DestLogs1 = "E:\sample\pfupdatedfin-$date.txt"
$DestLogs2 = "E:\sample\pfoutdatedfin-$date.txt"
$SrcPath = "E:\sample\$filename"
# email settings
$MyEmail = "myemail#gmail.com"
$SMTP = "smtp.gmail.com"
$To = "samplereceiver#gmail.com"
$Subject1 = "JDA-Alert || Found FILE.400 file - Successful"
$Body1 = "JDA-Alert || Found FILE.400 file - Successful"
$Subject2 = "JDA-Alert || FILE.400 file - Outdated File"
$Body2 = "JDA-Alert || FILE.400 file - Outdated File"
$Creds = (Get-Credential -Credential "$MyEmail")
If ((Get-ChildItem $SrcPath).LastWriteTime -gt $date)
{
Start-Sleep 2
Send-MailMessage -To $To -From $MyEmail -Subject $Subject1 -Body $Body1 -SmtpServer $SMTP -Credential $Creds -UseSsl -Port 587 -DeliveryNotificationOption Never
}
Else
{
Start-Sleep 2
Send-MailMessage -To $To -From $MyEmail -Subject $Subject2 -Body $Body2 -SmtpServer $SMTP -Credential $Creds -UseSsl -Port 587 -DeliveryNotificationOption Never
}

Result of Powershell Script sent via email

On the result of running the below script, it returns the following:
How could I get this result sent via email? I'm not sure how to get the result into a parameter that I can pass into the Body of an email script:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-6
$azPath = "C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy\"
Set-Location $azPath
$StorageAccountName = "#"
$StorageAccountKey = "#"
$ContainerName = "#"
$SourceFolder = "#"
$DestURL = "https://$StorageAccountName.blob.core.windows.net/$ContainerName"
$Result = .\AzCopy.exe /source:$SourceFolder /dest:$DestURL /BlobType:block /destkey:$StorageAccountKey /Y /S /XO
$Result
You can either store your result in a file and send it as an attachment:
$Result | Out-File Result.txt
Send-MailMessage -From 'User01 <user01#fabrikam.com>' -To 'User02 <user02#fabrikam.com>' -Subject 'Sending the Attachment' -Body "Forgot to send the attachment. Sending now." -Attachments .\Result.txt -SmtpServer 'smtp.fabrikam.com'
Or send the content of $Result (=string[]) as a string in the -Body:
$body = $Result -join '`n' # Join result to a single string with line breaks
Send-MailMessage -From 'User01 <user01#fabrikam.com>' -To 'User02 <user02#fabrikam.com>' -Subject 'Sending the Attachment' -Body $body -SmtpServer 'smtp.fabrikam.com'
Or (as stated in #Olfa's comment) convert it to HTML and add the -BodyAsHtml switch:
$body = $Result | ConvertTo-Html
Send-MailMessage -From 'User01 <user01#fabrikam.com>' -To 'User02 <user02#fabrikam.com>' -Subject 'Sending the Attachment' -Body $body -SmtpServer 'smtp.fabrikam.com' -BodyAsHtml

Powershell Email Notification File Created

I have written a code for PowerShell to notify me when a new file has been added to a designated folder, but every time the file is opened it creates a temp file and I keep getting those emails each time I open it. I have tried to create an if-else statement so that the temp file emails go to a different email address. Ideally, I would like to not receive those emails at all. If any of you know of a way that this is possible please help me. I have copied my code below.
$folder = "File Folder Path"
$mailserver = "mailserver"
$recipient = "Recipient#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 ($fsw -ccontains '~') {
Send-MailMessage -To "MyEmail#Email.com" `
-From "Email#Email.com" `
-Subject “File Creation Event” `
-Body "A file was created: $($eventArgs.FullPath)" `
-SmtpServer $mailserver `
-Credential $anon
}
Else {
Send-MailMessage -To $recipient `
-From "Email#Email.com" `
-Subject “File Creation Event” `
-Body "A file was created: $($eventArgs.FullPath)" `
-SmtpServer $mailserver `
-Credential $anon
}
}
Contains works on an array, not a string. Use -like or -match.
If you don't want an e-mail, don't write the code to send one.
For example, this only send an e-mail if your temp file does not contain ~. As there is no else, no action is taken if the file name does contain ~.
If ($fsw -notlike '*~*') {
Send-MailMessage -To $recipient `
-From "Email#Email.com" `
-Subject “File Creation Event” `
-Body "A file was created: $($eventArgs.FullPath)" `
-SmtpServer $mailserver `
-Credential $anon
}

If file exists, send Email and run batch script

I have a script that runs every two hours to see if a file has been dropped. If it is there, I get an alert. I would like to take it a step further and run a job the move the file. So far here is what I have:
$path = "\\0.0.0.0\files\test\state\WAITING\*"
$fileexists = Test-Path $path
if ($fileexists) {
Send-MailMessage `
-From noreply#email.com `
-To tester#foo.com `
-Subject "Files Have Arrived" `
-Body "The files have arrived and are being moved to the processing folder." `
-SmtpServer 0.0.0.1
} else {
#donothing
}
I want to fit this in the ifexists:
Start-Process "cmd.exe" "/c \\0.0.0.0\files\test\MOVE.bat"
Would it be like this:
$path = "\\0.0.0.0\files\test\state\WAITING\*"
$fileexists = Test-Path $path
if ($fileexists) {
Send-MailMessage `
-From noreply#email.com `
-To tester#foo.com `
-Subject "Files Have Arrived" `
-Body "The files have arrived and are being moved to the processing folder." `
-SmtpServer 0.0.0.1
Start-Process "cmd.exe" "/c \\0.0.0.0\files\test\MOVE.bat
} else {
#donothing
}
I got it figured out
$path = "\\0.0.0.0\files\test\state\WAITING\*"
$fileexists = Test-Path $path
if ($fileexists) {
Start-Process "cmd.exe" "/c \\0.0.0.1\files\test\MOVE.bat"` | Send-MailMessage -From noreply#test.com -To tester#foo.com -Subject "Files Have Arrived" -Body "The files have arrived and are being moved to the processing folder." -SmtpServer 0.0.0.2`
} else {
#donothing
}
You can use semicolon ";" to separate commands.

PowerShell to send email

I am running a Task Scheduler to execute my PowerShell every 30 minutes.
So
$users = Search-ADAccount -LockedOut -SearchBase
"OU=People,DC=Example,DC=com" -SearchScope Subtree | Select
SamAccountName
This returns a list of users. Now I want to create an emailbody with the users
$EmailBody = ForEach($user in $users) {"`r`n",$user}
Send-MailMessage -To $to -Subject "Locked Accounts" -BodyAsHtml $EmailBody -From $from -Credential $cred -SmtpServer $server -Debug
However my current code will send the email even if NO ONE is locked. Is there anyway I can check to see if the $users has at least 1 person?
(I haven't tested the $EmailBody but would like to know if this is acceptable for BodyAsHtml)
================
Updated Code
if ($users) {
if ($users.count -gt 0) {#even if there are users, this line always is false.
# send the email here
foreach($user in $users)
{
$message = $message + " " + $user + " is locked out" + "`r`n"
Write-Host $user
}
Send-MailMessage -To $to -Subject "Locked Accounts" -BodyAsHtml $message -From $from -Credential $cred -SmtpServer $server -Debug
} }
if ($users -ne $null) # lists can be empty as well, in which case the count fails
{
if ($users.count -gt 0) {
# send the email here
}
}