If file exists, send Email and run batch script - powershell

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.

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
}

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
}

Powershell search for longfile path names and send the owner of a file a mail to do something about it

I am trying to set up a PowerShell script which reads out a UNC path on Windows and searches for longfiles/paths. After it has found the file it needs to send a mail to the owner of the file.
I have found already a script and tweaked it a bit but it doesn't seems to work yet. The following script can find the long file path now but the mail is not working properly.
$limit = 90
$testpath = "C:\test"
$resultpath = "c:\test"
$admins = "moh#test.com"
$from = "moh#test.com"
$smtpserver = "smtp.office365.com"
Get-ChildItem -Path $testpath -Recurse | ?{$_.fullname.length -gt $limit} |
Select-Object fullname,
#{n="owner";e={
$_.GetAccessControl().GetOwner('System.Security.Principal.NTAccount')}},
#{n="namelength"; e={$_.fullname.length}} |
%{
Out-File -FilePath "$resultpath\Longfiles of $($_.owner -replace "\\","-").txt" -Append -InputObject "$($_.namelength) - $($_.fullname)"
}
Get-ChildItem $resultpath -Filter "longfiles of *" | % {
if($_.name -match "Longfiles\sof\s(.+)\.txt"){
$user = $matches[1] -replace "-","\"
$ntacc = New-Object System.Security.Principal.NTAccount($user)
$sid = $ntacc.Translate([System.Security.Principal.SecurityIdentifier])
$aduser = [ADSI]"LDAP://<SID=$sid>"
$email = $aduser.Properties.mail
if($email) {Send-MailMessage -Attachments $_.fullname -Body "Please change the filenames of the files listed in the attached file to shorter!"
-From $from -SmtpServer $smtpserver -Subject "System notice" -To
$email -cc $admins
}
else {
Send-MailMessage -Attachments $_.fullname -Body "email coudn't be sent to owner" `
-From $from -SmtpServer $smtpserver -Subject "System notice" -To $admins
}
}
else {Write-Host "Some error with file $_"}
}
EDIT: This is what i see, after running the script... it is asking me to fill in the fields, while the fields are already filled in in the script such as (From: moh#test.com to moh#test.com)
[]
You issue was because of line breaks in the middle of a command. In some lines, you had a backtick character which escapes the end of the line. But as you found these are really easy to break and that's why it's best practice to use splatting on commands with many parameters.
I also changed your Select-Object calculated properties into a more readable [pscustomobject] since they are hard to format in a readable way, but this does require PS3+.
$limit = 90
$testpath = "C:\test"
$resultpath = "c:\test"
$admins = "moh#test.com"
$from = "moh#test.com"
$smtpserver = "smtp.office365.com"
Get-ChildItem -Path $testpath -Recurse |
Where-Object {$_.fullname.length -gt $limit} |
ForEach-Object {
[PSCustomObject]#{
'fullname' = $_.fullname
'owner' = $_.GetAccessControl().GetOwner('System.Security.Principal.NTAccount')
'namelength' = $_.fullname.length
}
} |
ForEach-Object {
Out-File -FilePath "$resultpath\Longfiles of $($_.owner -replace "\\","-").txt" -Append -InputObject "$($_.namelength) - $($_.fullname)"
}
Get-ChildItem $resultpath -Filter "longfiles of *" | ForEach-Object {
if ($_.name -match "Longfiles\sof\s(.+)\.txt") {
$user = $matches[1] -replace "-", "\"
$ntacc = New-Object System.Security.Principal.NTAccount($user)
$sid = $ntacc.Translate([System.Security.Principal.SecurityIdentifier])
$aduser = [ADSI]"LDAP://<SID=$sid>"
$email = $aduser.Properties.mail
if ($email) {
$mailparams = #{
'Attachments' = $_.fullname
'Body' = "Please change the filenames of the files listed in the attached file to shorter!"
'From' = $from
'SmtpServer' = $smtpserver
'Subject' = "System notice"
'To' = $email
'cc' = $admins
}
Send-MailMessage #mailparams
} else {
$mailparams = #{
'Attachments' = $_.fullname
'Body' = "email coudn't be sent to owner"
'From' = $from
'SmtpServer' = $smtpserver
'Subject' = "System notice"
'To' = $admins
}
Send-MailMessage #mailparams
}
} else {
Write-Host "Some error with file $_"
}
}
Remove the line breaks or escape them with a backtick: `. Your script must actually look like this:
if ($email) {
Send-MailMessage -Attachments $_.fullname -Body "Please change the filenames of the files listed in the attached file to shorter!"
-From $from -SmtpServer $smtpserver -Subject "System notice" -To
$email -cc $admins
}
else {
Send-MailMessage -Attachments $_.fullname -Body "email coudn't be sent to owner" `
-From $from -SmtpServer $smtpserver -Subject "System notice" -To $admins
}
And Powershell doesn't know that the line beginning with -From is part of Send-MailMessage.

robocopy unable to find specified path

#Variables
$logfile = "\\hermamora\Public\Plex Backup\Logs\Plex_Backup_Log_$(get-date -format "yyyyMMdd").txt"
function log($string, $color)
{
if ($Color -eq $null) {$color = "white"}
Write-Host $string -ForegroundColor $color
$string | Out-File -Filepath $logfile -Append
}
function Main {
robocopy Q:\ L:\ /v /mir /z /r:1 /w:5
}
$main = Main
#Arguments for Email
$From = "FROMADDRESS"
$To = "TOADDRESS"
#$Attachment = $logfile
$Subject = "Plex Backup Success"
$Body = "Here is the log of the Plex DB Backup, It was able to complete successfully"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
$login = "USERNAME"
$password = "PASSWORD" | ConvertTo-SecureString -AsPlainText -Force
$credentials = New-Object System.Management.Automation.Pscredential -Argumentlist $login,$password
#Main Script
#Sets up Drives for Easy copy
subst L: "\\hermamora\Public\Plex Backup\Backup"
subst Q: "C:\Users\ztownes\AppData\Local\Plex Media Server"
#Stops Plex and Copies DB
taskkill /IM "Plex Media Server.exe"
Start-Sleep -Seconds 15
log $main
Start-Sleep -Seconds 15
Start-process "C:\Program Files (x86)\Plex\Plex Media Server\Plex Media Server.exe"
#Removes Drives for unclutering
subst /d L:
subst /d Q:
Start-Sleep -Seconds 5
#Sends Email
Send-MailMessage -From $From -To $To -Cc $Cc -Subject $Subject -Body $Body -SmtpServer $SMTPServer -Port $SMTPPort -UseSsl -Credential $credentials -Attachments $logfile
Start-Sleep -Seconds 5
Whenever I try to run this code it is unable to find the drives L: and Q: for robocopy. I am able to see the drives in Windows Explorer. I have an almost identical script for PowerShell that runs this with no problem. For obvious security reasons I have removed the email addresses and passwords from the email arguments.

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

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
}