Send mail trough TELNET over OVH with .batch script - powershell

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
}

Related

Supported way to send office 365 smtp email which allow us to attach a file

I have this code to send email with attachment:-
$encpassword = convertto-securestring -String "*****" -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "***#***", $encpassword
Connect-PnPOnline -Url $sourceWebURL -Credentials $cred
Send-MailMessage -to "" -from "" -Credentials $cred -bcc "" -Port "587" -UseSSL "true" -Subject "subject" -Body "<b>1</b><br><b>2</b>" -BodyAsHtml -SmtpServer "smtp.office365.com" -Attachments "C:\s.csv"
but based on the documentation's warning that Send-MailMessage is obsolete # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-7.3
and at the same time using Send-PnPMail does not support sending attachments # https://pnp.github.io/powershell/cmdlets/Send-PnPMail.html .
so my question is how we can send an email using power shell using a supported/recommended approach which allow us to attach a file.
Thanks
What the Send-MailMessage documentation's warning that Send-MailMessage is obsolete fails to mention is the underlying reason as to why it is now obsolete. For example, Send-MailMessage still works just fine when you continue to connect to your on-premise Exchange Server so why the message?
The reason is as part of Microsoft’s "Secure by Default" policy, Microsoft is permanently disabling Basic Authentication in Exchange Online for everyone on October 1, 2022 (Basic Authentication and Exchange Online – September 2021 Update - Microsoft Tech Community).
This includes Exchange Web Services (EWS), Exchange ActiveSync (EAS), POP, IMAP, Remote PowerShell, MAPI, RPC, SMTP AUTH, and OAB. All client applications need to switch to Modern Authentication/OAuth or Microsoft Graph API to continue to function.
Send-MailMessage uses Basic Authentication (Username and password with an option to use SSL) but wasn't made to use Modern Authentication methods. It was primarily designed to work with on-premise Exchange Servers and didn't have to worry about those pesky things like MFA or options for using key/value/tokens for authentication. Therefore, it's use is now obsolete when trying to use it with Exchange Online/O365 servers.
The O365 supported method is to use Microsoft Graph to send the message with attachment. It's a little more complicated than a vanilla Send-MailMessage, because you need to use JSON to create the configuration. You also need to convert the file Attachment to a Base64 encoded string so that it can be added to the JSON message.
Import-Module Microsoft.Graph.Users.Actions
Connect-MgGraph
#Convert File to Base64
$filename = "C:\attachment.csv"
$filenameBase64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes($filename))
$params = #{
Message = #{
Subject = "Important Attachment"
Body = #{
ContentType = "html"
Content = "Please find <b>Important Document</b> attached"
}
ToRecipients = #(
#{
EmailAddress = #{
Address = "johnGu#contoso.com"
}
}
)
Attachments = #(
#{
"#odata.type" = "#microsoft.graph.fileAttachment"
Name = "attachment.csv"
ContentType = "text/plain"
ContentBytes = $filenameBase64string
}
)
}
}
Send-MgUserMail -UserId johnGu#contoso.com -BodyParameter $params
This is now done with Send-MgUserMail which is from the Microsoft Graph PowerShell module Microsoft.Graph.Users.Actions.
Example 3: Create a message with a file attachment and send the message
Import-Module Microsoft.Graph.Users.Actions
$params = #{
Message = #{
Subject = "Meet for lunch?"
Body = #{
ContentType = "Text"
Content = "The new cafeteria is open."
}
ToRecipients = #(
#{
EmailAddress = #{
Address = "meganb#contoso.onmicrosoft.com"
}
}
)
Attachments = #(
#{
"#odata.type" = "#microsoft.graph.fileAttachment"
Name = "attachment.txt"
ContentType = "text/plain"
ContentBytes = "SGVsbG8gV29ybGQh"
}
)
}
}
# A UPN can also be used as -UserId.
Send-MgUserMail -UserId $userId -BodyParameter $params

Send email via SMTP Mail server

I have installed SMTP Virtual Server in windows server 2012 r2. Later I have used following PowerShell script to send the email. Which was successful
$email = "xxxxxxxxxx#xxxxxx.com"
$pass = "xxxxxxx"
$smtpServer = "smtp.office365.com"
$smtpPort = "25"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.EnableSsl = $true
$msg.From = "$email"
$attachment = New-Object Net.Mail.Attachment("C:abcd/123.txt");
$msg.Attachments.Add($attachment);
$msg.To.Add("xxxx#xxxxx.com")
$msg.BodyEncoding = [system.Text.Encoding]::Unicode
$msg.SubjectEncoding = [system.Text.Encoding]::Unicode
$msg.IsBodyHTML = $true
$msg.Subject ="List of users"
$msg.Body=$msg.Body = "<h2> hi everyone </h2>
$SMTP.Credentials = New-Object System.Net.NetworkCredential("$email", "$pass");
$smtp.Send($msg)
here my question is can I send email without using from address in the above script(Is there any chance to save from email address and credentials somewhere in SMTP virtual server settings so that script can take credentials directly). I don't want to use from email address and credentials in above script
I'd suggest using Send-MailMessage instead of manual .NET manipulation:
$Creds = Import-CliXml -Path 'C:\mycreds.xml'
$MailArgs = #{ 'SmtpServer' = 'smtp.office365.com'
'Port' = 25
'To' = 'xxxx#xxxxx.com'
'From' = $Creds.UserName
'Subject' = 'List of users'
'Attachments' = 'C:\abcd\123.txt'
'Body' = '<h2> hi everyone </h2>'
'Encoding' = [Text.Encoding]::Unicode
'BodyAsHtml' = $true
'UseSsl' = $true
'Credential' = $Creds
}
Send-MailMessage #MailArgs
And you would create your $Creds object as follows:
Get-Credential -Credential 'xxxxxxxxxx#xxxxxx.com' | Export-CliXml -Path 'C:\mycreds.xml'
There are a couple extra options you might be interested in (such as notification of delivery) you can read about in the doc linked above.
Additionally, your password is encrypted when exported using Export-CliXml specific to that device and account utilizing DPAPI.

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 via powershell without authentication

I was using nant to send mail and it is working fine - something like
<mail
from="Test#b.c"
tolist="A#b.c"
subject="Test"
mailhost="myhost.mydomain.com"
isbodyhtml="true"
message= "${Test}">
</mail>
I didn't have to use any kind of authentication.
Now when using powershell it seems I am forced to use authentication - something like this would fail:
Send-MailMessage -To $to -From $from -Subject "Test" –Body “Test (body) -SmtpServer "myhost.mydomain.com"
I would get the following message:
Send-MailMessage : No credentials are available in the security package
Am I missing some way to send mails without specifying credentials if the server supports that?
Edit:
I've also tried the answer here to send anonymous mails but it just times out:
send anonymous mails using powershell
Sending mails using Powershell v1 method works fine without authentication as shown here
My Powershell version is 5 yet this is apparently the way to go, unless someone has another idea.
$smtpServer = "ho-ex2010-caht1.exchangeserverpro.net"
$smtpFrom = "reports#exchangeserverpro.net"
$smtpTo = $to
$messageSubject = $subject
$messageBody = $body
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
I was looking for another issue and found this question here...
As #AngelicCore already explained one approach,
Here is another one if someone using Outlook dektop app...
The mail sent will appear in your outbox.
using outlook object
Try
{
#Email structure
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
#Email Recipients
$Mail.To = "abc#domain.com;xyz#domain.com"
$Mail.Cc = "tuv#domain.com; pqr#domain.com"
#Email Subject
$date = Get-Date -Format g
$Mail.Subject = "Subject here $date"
#Email Body
$Mail.Body = "Body Here"
#Html Body
$Mail.HTMLBody == "<html> HTML Body Here </html>"
#Email Attachment
$file = "C:\path\xyz.txt"
$Mail.Attachments.Add($file)
$Mail.Send()
Write-Host -foreground green "Mail Sent Successfully"
}
Catch
{
write-host -foreground red $error[0].Exception.Message
}
pause
exit

powershell email smtp with startls

Need to send email via private smtp server with credential and starttls. I read many tutorials and still cannot establish starttls communication.
My code:
$smtpServer = "smtp.xserver.cz"
#Creating a Mail object
$msg = new-object Net.Mail.MailMessage
#Creating SMTP server object
$smtp = new-object Net.Mail.SmtpClient($smtpServer, 25)#587 works
$smtp.EnableSsl = $false
$smtp.Credentials = New-Object System.Net.NetworkCredential("myuser#xserver.cz","mypassword"); #yes, correct login, tried via Thunderbird
#Email structure
$msg.From = "info#xserver.cz"
$msg.To.Add("testtest#gmail.com")
$msg.subject = "subject"
$msg.IsBodyHTML = $true
$msg.body = "AAA"+"<br /><br />"
$ok=$true
try{
$smtp.Send($msg)
Write-Host "SENT"
}
catch {
Write-Host "`tNOT WORK !!!!!"
$error[0]
$_.Exception.Response
$ok=$false
}
finally{
$msg.Dispose()
}
if($ok){
Write-Host "`tEVERYTHING OK"
}
Need to use .Net objects and class, not third party library, or Send-MailMessage in Powershell, because Send-MailMessage doesn't have atachment sending options.
You're not getting your TLS connect because you've set EnableSsl to $false.
Not sure where you got the idea that Send-MailMessage doesn't have attachment sending options. Sending attachments with Send-MailMailMessage is ridiculously easy. It accepts one or more file names to use as attachments from the pipeline, or through the -Attachments parameter.