Powershell: Move email to a different folder in Gmail - powershell

I need to use Powershell and move an email in my GMAIL INBOX to a different folder.
I am using the Powershell module Mailozaurr to connect to Gmail via IMAP (https://evotec.xyz/mailozaurr-new-mail-toolkit-smtp-imap-pop3-with-support-for-oauth-2-0-and-graphapi-for-powershell/). I am able to correctly login and read emails in my Inbox.
Here is my code:
$FromAddress = "A12345#gmail.com"
$Password = "MY_password"
$Client = Connect-IMAP -Server 'imap.gmail.com' -Password $Password -UserName $FromAddress -Port 993 -Options Auto
Get-IMAPFolder -Client $Client -Verbose
foreach ($Email in $client.Data.Inbox)
{
if ($Email.from -notlike "test") {continue}
$Email
Break
}
At this stage I want to move $email to a new folder named "NewFolder". How do i achieve this?

I finally figured out why it was not working. Looking at the backend code for the module (https://www.powershellgallery.com/packages/Mailozaurr/0.0.16/Content/Mailozaurr.psm1), the Inbox is open in ReadOnly mode. Hence the solution is closing the inbox and opening it in readwrite mode or Set the FolderAccess on the Get-ImapFolder command. Hence
$FromAddress = "A12345#gmail.com"
$Password = "MY_password"
$Client = Connect-IMAP -Server 'imap.gmail.com' -Password $Password -UserName $FromAddress -Port 993 -Options Auto
Get-IMAPFolder -Client $Client -FolderAccess ReadWrite -Verbose
foreach ($Email in $client.Data.Inbox)
{
$Email
$TestFolder = $Client.data.GetFolder("Test")
$client.Data.Inbox.MoveTo(0, $TestFolder)
Break
}
The ZERO in the Moveto Command represents the 1st email to be moved. Thanks to #PrzemyslawKlys for assistance at https://github.com/EvotecIT/Mailozaurr/issues/22

Related

Adding attachments to an email generated in powershell

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/

Sorting, automatically adding an attachment to an email, and forwarding an email

What I am hoping to do is once a new email hits a folder containing a specific subject. That email is then forwarded to another inbox and a specific file is automatically attached. The code I have been able to cobble together so far is this. Is a .Net method the appropriate method to achieve my goal or would using Send-MailMessge to a hastable be better method? I am new to PowerShell code I am able to get both methods to work. But was wondering A. which method is preferred. B. is there a better/more efficient way?
#####Define Variables########
$fromaddress = "donotreply#fromemail.com"
$toaddress = "blah#toemail.com"
$bccaddress = "blah#bcc.com"
$CCaddress = "blah#cc.com"
$Subject = "ACtion Required"
$body = get-content .\content.htm
$attachment = "C:\sendemail\test.txt"
$smtpserver = "smtp.labtest.com"
##############################
$message = new-object System.Net.Mail.MailMessage
$message.From = $fromaddress
$message.To.Add($toaddress)
$message.CC.Add($CCaddress)
$message.Bcc.Add($bccaddress)
$message.IsBodyHtml = $True
$message.Subject = $Subject
$attach = new-object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attach)
$message.body = $body
$smtp = new-object Net.Mail.SmtpClient($smtpserver)
$smtp.Send($message)
(Example of the hashtable method
$emailHashSplat = #{ To = $toAddress
From = $fromAddress
Subject = $emailSubject
Body = $emailBody SMTPServer = $smtpServer BodyAsHtml =
$true Attachments = "C:\sendemail\test.txt" # Attachments =)
Stick with Powershell commands whenever possible, .NET might be faster in some cases but it is a best practice to use only Powershell commands when possible.
Also make sure your code is easy to read and understand by others, using hastables with splatting wil help with this, see the following example: Github Gist Link (Click Me!)
Copy of the code, in case of link failure.
### Script Global Settings
#Declare SMTP Connection Settings
$SMTPConnection = #{
#Use Office365, Gmail, Other or OnPremise SMTP Relay FQDN
SmtpServer = 'outlook.office365.com'
#OnPrem SMTP Relay usually uses port 25 without SSL
#Other Public SMTP Relays usually use SSL with a specific port such as 587 or 443
Port = 587
UseSsl = $true
#Option A: Query for Credential at run time.
Credential = Get-Credential -Message 'Enter SMTP Login' -UserName "emailaddress#domain.tld"
<#
#Option B: Hardcoded Credential based on a SecureString
Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList #(
#The SMTP User Emailaddress
"emailaddress#domain.tld"
#The Password as SecureString encoded by the user that wil run this script!
#To create a SecureString Use the folowing Command: Read-Host "Enter Password" -AsSecureString | ConvertFrom-SecureString
"Enter the SecureString here as a single line" | ConvertTo-SecureString
)
#>
}
### Script Variables
#Declare Mailmessages.
$MailMessageA = #{
From = "emailaddress#domain.tld"
To = #(
"emailaddress#domain.tld"
)
#Cc = #(
# "emailaddress#domain.tld"
#)
#Bcc = #(
# "emailaddress#domain.tld"
#)
Subject = 'Mailmessage from script'
#Priority = 'Normal' #Normal by default, options: High, Low, Normal
#Attachments = #(
#'FilePath'
#)
#InlineAttachments = #{
#'CIDA'='FilePath'
#} #For more information about inline attachments in mailmessages see: https://gallery.technet.microsoft.com/scriptcenter/Send-MailMessage-3a920a6d
BodyAsHtml = $true
Body = "Something Unexpected Occured as no Content has been Provided for this Mail Message!" #Default Message
}
### Script Start
#Retrieve Powershell Version Information and store it as HTML with Special CSS Class
$PSVersionTable_HTLM = ($PSVersionTable.Values | ConvertTo-Html -Fragment) -replace '<table>', '<table class="table">'
#Retrieve CSS Stylesheet
$CSS = Invoke-WebRequest "https://raw.githubusercontent.com/advancedrei/BootstrapForEmail/master/Stylesheet/bootstrap-email.min.css" | Select-Object -ExpandProperty Content
#Build HTML Mail Message and Apply it to the MailMessage HashTable
$MailMessageA.Body = ConvertTo-Html -Title $MailMessageA.Subject -Head "<style>$($CSS)</style>" -Body "
<p>
Hello World,
</p>
<p>
If your recieved this message then this script works.</br>
</br>
<div class='alert alert-info' role='alert'>
Powershell version
</div>
$($PSVersionTable_HTLM)
</P>
" | Out-String
#Send MailMessage
#This example uses the HashTable's with a technique called Splatting to match/bind the Key's in the HashTable with the Parameters of the command.
#Use the # Symbol instead of $ to invoke Splatting, Splatting improves readability and allows for better management and reuse of variables
Send-MailMessage #SMTPConnection #MailMessageA

Send mail trough TELNET over OVH with .batch script

I would like to use TELNET to send an email with the content of log.txt using one of my OVH mail accounts (noreply#clement.business hosted on OVH) to a gmail address. Due to my society security politics I am not able to install anything on the servers but the OS itself.
So I tried with both batch and PowerShell but without success, I even tried manually, I can telnet OVH but then don't know how to login.
Here's a few things I tried :
$subject = $args[0]
# Create from/to addresses
$from = New-Object system.net.mail.MailAddress "noreply#clement.business"
$to = New-Object system.net.mail.MailAddress "random#gmail.com"
# Create Message
$message = new-object system.net.mail.MailMessage $from, $to
$message.Subject = $subject
$message.Body = #"
Am I even suppose to write here
"#
# Set SMTP Server and create SMTP Client
$server = "I have no idea how to OVH here"
$client = new-object system.net.mail.smtpclient $server... Server what, POP3 ?
# Do
"Sending an e-mail message to {0} by using SMTP host {1} port {2}." -f $to.ToString(), $client.Host, $client.Port
try {
$client.Send($message)
}
catch {
"Exception caught in CreateTestMessage: {0}" -f $Error.ToString()
}
I cannot figure that out, it is such a struggle to deal with...
PS : I did use the OVH guide about POP3/SMTP setup, but did not work, or I have no idea what I am doing. Useful link here as well.
Just so you know the difference: POP3 is used to receive email, SMTP is used to send email. You can't use them interchangeably.
A quick google for 'ovh smtp server' shows that the ovh help pages list the SMTP servers as:
Server name: ns0.ovh.net
Port of the outgoing server: 587
Username: identical to the email address
Password: your password for your account, as defined in the creation of the email address
I can't test these as I don't have an ovh account.
I would use Send-MailMessage to send the email as it's much easier to use than your solution:'
This will send an email with the file log.txt as an attachment:
$username = "noreply#clement.business"
$password = "passwordforemailaddress" | ConvertTo-SecureString
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
$parms = #{
From = "noreply#clement.business"
To = "email#gmail.com"
Attachment = "C:\folder\log.txt"
Subject = "Daily Logs"
Body = "Your body text here"
SMTPServer = "ns0.ovh.net"
SMTPPort = "587"
Credential = $credentials
}
Send-MailMessage #params
And these params this will use log.txt as the email body text:
$parms = #{
From = "noreply#clement.business"
To = "email#gmail.com"
Body = Get-Content "C:\folder\log.txt"
Subject = "Daily Logs"
SMTPServer = "ns0.ovh.net"
SMTPPort = "587"
Credential = $credentials
}

Use powershell to send email while saving your password securely in encrypted file

I have found similar threads but none that solve my issue. I am trying to send an email using SMTP server, with attachment (via gmail). That's the easy bit done. The main error response I get is
The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required."
I think it has to do with getting the password from the password file into the Credentials
"Password123" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File "C:\Folder\Password.txt"
$EmailFrom = "emailaddress#gmail.com"
$EmailTo = "otheremailaddress#gmail.com"
$Subject = "Log file from server"
$Subject = "Subject"
$Body = "Here is the log file from the server"
$File = "C:\Folder\LogFile.txt"
$attachment = New-Object System.Net.Mail.Attachment($File,'text/plain')
$mailmessage = New-Object system.net.mail.mailmessage
$mailmessage.from = ($EmailFrom)
$mailmessage.To.add($emailto)
$mailmessage.Subject = $Subject
$mailmessage.Body = $Body
$mailmessage.Attachments.Add($attachment)
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$username = "emailaddress#gmail.com"
$pass = Get-Content "C:\Folder\Password.txt" | ConvertTo-SecureString -AsPlainText -Force
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($username, $pass);
$SMTPClient.Send($mailmessage)
I want to remove the first line of this code as it's never a good idea to have a password in the script.
If I change the password variable to the following I have no issue
$pass = "Password123"
All the other forum posts I found have suggested things haven't solved my problem.
Also changing gmails settings to allow access from less secure apps doesn't solve my problem.
Any help would greatly be appreciated
Thanks in advance.
EDIT:
I have gmail accessible for less secure apps
I have 2 step verification off for gmail
I believe the issue is reading the password file. It's a case of not being able to accept password from the file when it is encrypted. I tried it with an un-encrypted password but that isn't much better for scripting
I've ran into issues with this in the past - I think one of the common gotcha's was already mentioned by Mathias - watch out for running under different credentials (running as a schedule job) since decoding depends on using the user's session information. The one thing I'm not quite sure about in your example is why you're doing a subsequent convert to plain text- otherwise though, the below should take your username and password, export it to a file, then import it in as a credential you can use later.
$user = "UsernameGoesHere"
$passwordtostore = 'PasswordGoesHere'
$secureStringPWD = $passwordtostore | ConvertTo-SecureString -AsPlainText -Force
$secureStringText = $secureStringPWD | ConvertFrom-SecureString
Set-Content "C:\temp\authenticationfile.cfg" $secureStringText
# Retrieve password
$pwdin = Get-Content "C:\temp\authenticationfile.cfg"
$password = $pwdin | ConvertTo-SecureString
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $user,$password
Hope that helps?

Can't use send-mailmessage when using PSFTP Module

I've made a Powershell script which uploads data to a NAS.
After the Upload is completed the script should send an Email message.
When the script tries to send a mailmessage I get an error saying I used an incorrect security certificate.
This error only shows up when I use the PSFTP module. When i run the sendmail code on its own it works just fine.
The FTP session itself isn't alive anymore so this shouldn't be a problem.
Can someone point me in the right direction to sort this problem out?I've made a Powershell script which uploads data to a NAS.
After the Upload is completed the script should send an Email message.
When the script tries to send a mailmessage I get an error saying I used an incorrect security certificate.
This error only shows up when I use the PSFTP module. When i run the sendmail code on its own it works just fine.
The FTP session itself isn't alive anymore so this shouldn't be a problem.
Can someone point me in the right direction to sort this problem out?
$Execution = Get-ExecutionPolicy
If($Execution -eq "RemoteSigned")
{
Write-Host "HOI" -BackgroundColor Black -ForegroundColor Green
}
Else
{
Set-ExecutionPolicy Remotesigned
}
1.Module PSFTP importing
Import-Module PSFTP
$secpasswd = ConvertTo-SecureString “Wachtwoord” -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential (“Admin”, $secpasswd)
Variables
$Session = "Alive"
$ftp = "IP"
$Credentials = "Admin"
$FtpFile = "C:\Test\Back-up.ps1"
$ftpDestination = "FTPLOCATIE"
2.Connect to FTP with module PSFTP
Set-FTPConnection -Server $ftp -Credentials $mycreds -Session $Session
( Connect to ftp)
3.TPItem for uploading to NAS
Get-ChildItem $FtpFile | Add-FTPItem -Session $Session -Path $ftpDestination -Overwrite
4.Section for mailing,variables
$secpasswd = ConvertTo-SecureString “Wachtwoord” -AsPlainText -Force
$mycredsMail = New-Object System.Management.Automation.PSCredential (“Email-address”, $secpasswd)
5. Section for mailing
$Smtp = "smtp.office365.com"
$Port = "587"
$To = "Email"
$Subject = "Back-up"
$From = "Email
6. this is where i want send the mail i use ssl
Send-MailMessage -to $To -from $From -Subject $Subject -SmtpServer $Smtp -Credential $mycredsMail -Port $Port -UseSsl