Send email with Powershell from different mailbox - email

I have created a small PS script to create an email for my pipeline to send out whenever there is a deployment. the problem is i dont want the email to be sent from my personal email but from the company outlook email. i searched and saw different SMTP server names and using mail.from but i cant get it to work. can someone help me out?
param(
[Parameter(Mandatory=$true,Position=0)]
[string]$Address1,
[Parameter(Mandatory=$true,Position=1)]
[string]$Address2,
[switch]$Recurse,
[switch]$Force
)
$ol = New-Object -comObject Outlook.Application
$mail = $ol.CreateItem(0)
$Mail.Recipients.Add($Address1)
$Mail.Recipients.Add($Address2)
$Mail.Subject = "DSC Deployment in Progress"
$Mail.Body = "There is a DSC install beginning. . ."
$Mail.Send()

You need to assign a value to the SendUsingAccount property. The account can be found in the (outlook).Session.Accounts collection.
$sendSmtpAddress = "some.name#somedomain.com"
$account = $ol.session.acounts | ? { $_.smtpAddress -eq $sendSmtpAddress }
then, assign to the SendUsingAccount property before sending
$mail.SendUsingAccount = $account
$mail.Send()
Full example
$sendSmtpAddress = "some.name#somedomain.com"
$ol = new-object -comobject "outlook.application"
$account = $ol.session.accounts | ? { $_.smtpAddress -eq $sendSmtpAddress }
$mail = $ol.CreateItem(0)
$mail.recipients.add("target.user#somedomain.com") | out-null
$mail.subject = "test email"
$mail.body = "test email"
$mail.SendUsingAccount = $account
$mail.Send()
For what it's worth, I gave up trying to send email via Outlook a long time ago, it's much easier to use plain SMTP. Depending on the security policy on your local SMTP server (Exchange?), you may be able to 'send as' any user on your local domain. Ask your IT people for the name/IP of an internal SMTP server that you can use to send email, and then it's as easy as:
send-mailmessage -smtpServer (servername or IP) -from sender.name#domain.com -to #(recipient1#domain.com, recipient2#domain.com) -subject "Email Subject" -body "Email Body"
If using send-mailmessage, it's possible to set a Display Name for the sender by using the form "Display Name <sender.name#domain.com>" e.g.
-from "Deployment Alerts <sender.name#domain.com>"
Recipients will see the Display Name in their email client, rather than the SMTP address.
A couple of points that I consider to be good practice:
Depending on the config of the SMTP server, there may be little, or no verification of the 'sender' address. It is worth using a genuine account that you have access to, so that you have sight of any bounce / non-delivery reports.
Consider including something in the mail body (perhaps a footer) that mentions where the alert came from and what process generated it. This can help your successor or colleague track down the script in the future.

The assignment like
$mail.SendUsingAccount = $account
worked for me since Windows Server 2000 till Windows Server 2008 and from Outlook 2007 till Outlook 2016. Since Windows Server 2016 I've got an exception (The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))).
But there is an alternative way to assign this property.
[Void] $mail.GetType().InvokeMember("SendUsingAccount","SetProperty",$NULL,$mail,$account)

Related

PowerShell Script for Email Notification

I am using a FileZilla Server as an FTP. I want to create a PowerShell script that will send an email as soon as a file is uploaded.
I have been using the knowledge in this article: https://richjenks.com/filezilla-email-notifications/
and below is the code of my fn.ps1 file
$EmailFrom = "SENDER_EMAIL"
$EmailTo = "RECIPIENT_EMAIL"
$Subject = "New File Uploaded to FileZilla"
$Body = "A new file has been uploaded to the FTP server on FileZilla"
$SMTPServer = "127.0.0.1"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 21)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object
System.Net.NetworkCredential("GMAIL_ADDRESS", "GMAIL_PASSWORD");
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
The only problem is that no email is actually sent? I can see the PowerShell pop up briefly after a file is uploaded so it is being run upon file upload, however no email is actually sent anywhere.
Any help would be greatly appreciated.
EDIT: I am not entirely sure what is the relationship between "SENDER_EMAIL" and "GMAIL_ADDRESS", I found the above solution on another website and they are different, should these not be the same?
Make sure you understand that the script actually has nothing to do with your FTP server. It is just a plain PowerShell script that sends a fixed email. So everything in the script is related to your SMTP mail server, not to your FTP server. So...
What goes to SmtpClient constructor is the address of your SMTP mail server. You seem to be using an address of your FTP server.
$SMTPServer = "127.0.0.1"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 21)
Check the example you have based this on. They use smtp.gmail.com:587.
Similarly, what goes to SmtpClient.Credentials are credentials to your SMTP mail server. So some real values, not placeholders like these:
$SMTPClient.Credentials = New-Object
System.Net.NetworkCredential("GMAIL_ADDRESS", "GMAIL_PASSWORD");
For Gmail they would be your Gmail address and password.

Is it possible to use Send-MailMessage with default credentials?

I've been trying to write a powershell script that sends an automated email as part of it's process using the logged in user's credentials. There are two primary methods that I've found to do this: Send-MailMessage and using a Net.Mail.SmtpClient object.
I've been able to get it up and running using the Net.Mail.SmtpClient object without issue, however that API is marked obsolete and so I'd prefer to not use it if possible, however I haven't been able to get Send-MailMessage to work using default credentials.
Without UseDefaultCredentials both of the scripts below fail with the same general message.
$smtpServer = "server.com"
$smtpFrom = "user#server.com"
$smtpTo = "user#server.com"
$messageSubject = "THIS IS WHERE YOUR SUBJECT GOES"
$messageBody = "This is a test of automated email at $([datetime]::Now.ToString('dd.MM.yyyy - HH.MM.SS'))"
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.EnableSsl = $true
$smtp.Port = 587
#$smtp.UseDefaultCredentials = $true
$smtp.Send($smtpFrom,$smtpTo,$messagesubject,$messagebody)
and
$mailsplat = #{
SmtpServer = 'server.com'
From = 'user#server.com'
To = 'user#server.com'
Subject = 'THIS IS WHERE YOUR SUBJECT GOES'
Body = "This is a test of automated email at $([datetime]::Now.ToString('dd.MM.yyyy - HH.MM.SS'))"
Port = 587
UseSSL = $true
#UseDefaultCredentials = $true
}
Send-MailMessage #mailsplat
"The SMTP server requires a secure connection or the client was not authenticated. The server
response was: 5.7.1 Client was not authenticated"
Fixing the first script is easy. If I uncomment out the UseDefaultCredentials line it works perfectly as expected. There's no UseDefaultCredentials or similar parameter available to Send-MailMessage however. I'd prefer to use the Send-MailMessage as it's the recommended method and the other is marked as obsolete, but I can't actually find a way to make it work with my requirements (despite a plethora of posts saying Send-MailMessage will use default credentials if none are provided and the documentation indicating it should)

How to check whether the email has been sent with Powershell

I am currently writing a Powershell script, which pings a server and if a connection cannot be established, sends an email to the IT department to restart the server manually.
Right now, the script can successfully send the email when the ping is unsuccessful and the object has a property value, which is supposed to evaluate to "True", but I can't verify that, because upon sending the email, the variable deletes itself and therefore the property doesn't exist anymore.
$Outlook = New-Object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
$Mail.To = "<recipient>"
$Mail.Cc = "<some_cc>"
$Mail.Send()
# After this line, the variable is deleted!
if ($Mail.Sent())
# The line which is supposed to work, but evaluates to False everytime
How do I make sure that this variable survives until I can verify the exchange?
The variable won't survive after Send method, and won't return a value either.
You are delegating the actual sending action to Outlook so you'll need to check Outlook Application for errors (i.e. a bounce).
If sending via Outlook is not necessary, you can have more options with
try {
Send-MailMessage -From 'monitoring#example.com' -To 'ITdesk#example.com' -Subject 'test' -Body 'whatever' -Priority High -DeliveryNotificationOption OnSuccess, OnFailure -SmtpServer 'mail.example.com' -ErrorAction stop -Port 25
}
catch{
write-warning "error in sending. $_"
}
Note that if you need authenticated send you can specify saved credentials via the -credential parameter.
References here:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-6
You could put the mail.send() inside a try/catch block. That way it would output if there were any errors or if it succeeded. Plus, there's no need for another variable.
try{
mail.send()
write-host "success"
}catch{
write-host "fail"
}

Sending mail with Powershell Windows 7

I cant get this to work on a windows 7 client with powershell 2
$smtpServer = "smtp.example.com"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = "fromID#example.com"
$msg.ReplyTo = "replyto#example.com"
$msg.To.Add("toID#example.com")
$msg.subject = "My Subject"
$msg.body = "This is the email Body."
$smtp.Send($msg)
I am getting an exception that says "Exception calling "Send with "1" arguments" Failure Sending mail"
Anyone have any idea?
I have tried Send-MailMessage but it also fails, if I run the command on a server based windows it executes fine.
I use the same account for the procedures.
This could be due to many reasons, but one issue that I had seen this exact same error was because an anti-virus program was blocking Powershell from sending the email. Check if this is the case by looking at your anti virus logs.
Beyond that, you might want to check if firewall is fine, you can connect to the SMTP server etc.
This might work:
$ol = New-Object -comObject Outlook.Application
$mail = $ol.CreateItem(0)
$Mail.Recipients.Add("XXX#YYY.ZZZ")
$Mail.Subject = "PS1 Script TestMail"
$Mail.Body = "Test Mail"
$Mail.Send()
# you can use this for HTML-Mails
# $Mail.HTMLBody = "<HTML><HEAD>Text<B>BOLD</B> <span style='color:#E36C0A'>Color Text</span></HEAD></HTML>"
# you can use this for attache a file
# $Mail.Attachments.Add("D:\scripte\ol.txt")
For further reference.
Changing port to 25 works, but why ?

Send email via Powershell and Outlook

I have a .msg file on my filesystem. With powershell I can open a Outlook window with the message simply like this:
Invoke-Item "MY MAIL.msg"
How to change the subject and forward it to a given address via Powershell?
Thanks in advance
We had a problem that required the email to be forwarded from Outlook, there was 3000~ emails to do.
The answer Iain had given led me down the path to success, so thank you.
However it did not work for me as given, it failed. I noticed that you need to save the method of the forward to a variable and then execute the code from that, below is my complete script for looping through each msg file in a folder and forwarding it to a person.
I also left the subject as it was and gave no body as this was not needed.
#Open Outlook and get a list of emails to forward
$Outlook = New-Object -comObject Outlook.Application
$Emails = Get-ChildItem -Path C:\Users\APerson\Documents -Filter *.msg
#Loop through each email and open it up
Foreach($Email IN $Emails){
$Message = $Outlook.Session.OpenSharedItem($($Email.FullName))
$Forward = $Message.Forward()
$Forward.Recipients.Add('a.person#gmail.com')
$Forward.Send()
#Sleep is optional :D
Start-Sleep -Seconds 1
}
#Close Outlook
$Outlook.Quit()
Also noticed if you have a security policy applied to Outlook that is stopping you from running this script, for example it will remove the Add() on recipients, just import these registry settings (can be saved as a reg file):
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Policies\Microsoft\office\14.0\outlook\security]
"PromptOOMSend"=dword:00000002
"PromptOOMAddressBookAccess"=dword:00000002
"PromptOOMAddressInformationAccess"=dword:00000002
"PromptOOMMeetingTaskRequestResponse"=dword:00000002
"PromptOOMSaveAs"=dword:00000002
"PromptOOMFormulaAccess"=dword:00000002
"PromptSimpleMAPISend"=dword:00000002
"PromptSimpleMAPINameResolve"=dword:00000002
"PromptSimpleMAPIOpenMessage"=dword:00000002
You could try something like this, works with outlook 2010
$ol = New-Object -comObject Outlook.Application
gm -InputObject $ol
$mail = $ol.Session.OpenSharedItem("C:\Users\fred\Desktop\Test Email Subject.msg")
$mail.Forward()
$Mail.Recipients.Add("fred#bloggs.com")
$Mail.Subject = "Test Mail"
$Mail.Body = " Test Mail 22222 "
$Mail.Send()
In PowerShell 2.0 there is a Send-MailMessage cmdlet that allows you to attach files, specify a subject and a recipient e.g.:
Send-MailMessage -smtpServer smtp.doe.com -from 'joe#doe.com' `
-to 'jane#doe.com' -subject 'Testing' -attachment foo.txt
Not sure how that plays with .msg files but you might give it a try.