How to create a MSG file with CC with PowerShell? - powershell

I try to create a msg file with powershell. I could already add the subject, and the receiver. but I can not add a CC.
This is what I have so far:
$obj = New-Object -ComObject Outlook.Application
$mail = $obj.CreateItem(0)
$Mail.Recipients.Add("email#email.com")
$Mail.Recipients.Type = olCC
$Mail.Recipients.Add("email2#email.com")
$Mail.Recipients.Add("email3#email.com")
$Mail.Subject = "Some Subject"
$Mail.Body = "test mail with powershell"
$Mail.Attachments.Add("c:\Users\se\Desktop\Attachment.txt")
$mail.SaveAs("c:\Users\se\Desktop\test.msg")
c:\Users\se\Desktop\test.msg
I tried to change the Recipient object from the default ("To") to CC but this doesn't work.

Per the documentation you need to change the type on the recipient objects, not on the Recipients collection before adding the recipients.
$cc = $Mail.Recipients.Add("email2#email.com")
$cc.Type = 2
$cc = $Mail.Recipients.Add("email3#email.com")
$cc.Type = 2
Also, olCC is not a valid constant in PowerShell. You need to either assign the numeric value of the constant (see above), define the constant yourself
$olCC = 2
# alternatively, if you want $olCC to be an actual constant:
#New-Variable -Name olCC -Value 2 -Option Constant
...
$cc = $Mail.Recipients.Add("email2#email.com")
$cc.Type = $olCC
$cc = $Mail.Recipients.Add("email3#email.com")
$cc.Type = $olCC
or look up the value in the Interop assembly (untested):
Add-Type -AssemblyName Microsoft.Office.Interop.Outlook
...
$cc = $Mail.Recipients.Add("email2#email.com")
$cc.Type = [Microsoft.Office.Interop.Outlook.Constants]::olCC
$cc = $Mail.Recipients.Add("email3#email.com")
$cc.Type = [Microsoft.Office.Interop.Outlook.Constants]::olCC

Related

Cannot understand why this parameter is returning a null value

This PowerShell script runs a SQL query and populates an Excel spreadsheet, then emails that spreadsheet:
$FileName = "C:\Users\user\Documents\Report.xlsx";
$ConnectionString = "OurConnectionString"
$secpasswd = "emailpassword"
$cred = New-Object System.Management.Automation.PSCredential ("emailaddress", $secpasswd)
$SmtpCred = $cred
$ToAddress = 'to#contoso.com'
$FromAddress = 'from#contoso.com'
$SmtpServer = 'smtp.server.com'
$SmtpPort = '587'
$Subject = 'Report'
$Body = "Here is your report"
$SqlQuery = #"
SELECT TOP 10 * FROM dbo.table
"#;
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection;
$SqlConnection.ConnectionString = $ConnectionString;
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand;
$SqlCmd.CommandText = $SqlQuery;
$SqlCmd.Connection = $SqlConnection;
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter;
$SqlAdapter.SelectCommand = $SqlCmd;
$DataSet = New-Object System.Data.DataSet;
$SqlAdapter.Fill($DataSet);
$DataSetTable = $DataSet.Tables["Table"];
$xlsFile = #($DataSetTable | Export-Excel $FileName -AutoSize)
$SqlConnection.Close()
$Attachment = $xlsFile
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $Attachment
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}
Send-MailMessage #mailparam -UseSsl
The error I get when I run this is:
Send-MailMessage : Cannot validate argument on parameter 'Attachments'. The
argument is null, empty, or an element of the argument collection contains a
null value. Supply a collection that does not contain any null values and then
try the command again.
At C:\Users\Desktop\Untitled1.ps1:58 char:18
+ Send-MailMessage #mailparam -UseSsl
+ ~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage
I can't figure out how $Attachment is ending up as null or empty? I know I've written scripts similar to this in the past and they worked fine. Am I missing something in my script that someone else can see? Further, I don't technically need to save the Excel file to the file system first, I just need to email it as an attachment. So it's ok if the answer eliminates the saving to the file system part, if that's even do-able.
The -Attachments parameter expects a string or list of strings.
see Send-MailMessage
This should be the full path(s) to the file(s) you need to attach, thus requires you to store them first. Generally, if I don't need the files afterwards you can just delete them. Also note that it is required you pass the FullName.
As I cannot see the Output of the Export-Excel function I will assume it returns a File Object then this should work
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $xlsFile.FullName
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}
If you are not returned a File object you will need to get the item first and pass the `FullName'
$MyExcelFile = Get-Item -Path 'C:\MyExcelFile.xlsx'
$mailparam = #{
To = $ToAddress
From = $FromAddress
Subject = $Subject
Body = $Body
Attachments = $MyExcelFile.FullName
SmtpServer = $SmtpServer
Port = $SmtpPort
Credential = $SmtpCred
}

Parsing a file of email adresses to set email recipients

I'm trying to write a PowerShell script which parses a list of email addresses and send a mail to them.
The file is formatted this way:
a.a#domain.com
b.b#domain.com
c.c#domain.com
...
I figured something like:
$recipients = Get-Content -Path MY_FILE.txt
$outlook = New-Object -ComObject Outlook.Application
$mail = $Outlook.CreateItem(0)
$mail.To = $recipients # here's the problem
$mail.Subject = "MY_SUBJECT"
$mail.HTMLBody = "MY_HTML_BODY"
$mail.Send()
My problem, as you can see is: how can I assign the addresses in $recipients to $mail.To?
When in doubt, read the documentation:
MailItem.To Property (Outlook)
Returns or sets a semicolon-delimited String list of display names for the To recipients for the Outlook item.
Read/write.
[...]
Remarks
This property contains the display names only. The To property corresponds to the MAPI property PidTagDisplayTo. The Recipients collection should be used to modify this property.
Emphasis mine.
To send one mail to all recipients change this line:
$mail.To = $recipients
into this:
foreach ($addr in $recipients) {
$mail.Recipients.Add($addr)
}
and the code should do what you want.
If you want to send every address in your file a separate email do it this way:
$recipients = Get-Content -Path MY_FILE.txt
$outlook = New-Object -ComObject Outlook.Application
ForEach ($recipient in $recipients) {
$mail = $Outlook.CreateItem(0)
$mail.To = $recipient
$mail.Subject = "MY_SUBJECT"
$mail.HTMLBody = "MY_HTML_BODY"
$mail.Send()
}
Also make sure you close the COM Object by adding the following to the end of your file:
$outlook.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null
You could try something like this:
$file = "$PSScriptRoot\MY_FILE.txt"
# Add a List of recipients
$to = #()
foreach ($email in (Get-Content $file)) {
$to += "$email;"
}
Write-Host "Complete recipient-list: $to"
$outlook = New-Object -ComObject Outlook.Application
$mail = $Outlook.CreateItem(0)
$mail.To = "$to"
$mail.Subject = "MY_SUBJECT"
$mail.HTMLBody = "MY_HTML_BODY"
$mail.Send()

Send mail with "Send As" or change sender

I'm making a script to automate Outlook 2016. I have one account with two different inboxes from clients.
At the end of the script, I need to send an email from the name of the inbox the script is run from. I'm authorized to send email in the name of both inboxes, but I can't get the script to do it. I post my actual code:
The code:
Function Send-Email {
param ([String]$desde,[String]$subject,[String]$buzon,[String]$inc)
$mail = $Outlook.CreateItem(0)
$firma ="
Textplan
"
$mail.subject = "Closed Ticket "+$subject
[String]$cuerpo =#"
Dear colleague,
bla bla bla
Thank you.
"#
$mail.sender = $buzon
$mail.body = $cuerpo+" "+$firma
$mail.To = $desde
$mail.Send()
Start-Sleep 3
}
$Outlook = New-Object -ComObject Outlook.Application
$desde = client2#mail.com
$buzon = inbox1#mail.com
$inc = 000000001
$subject = "Automat request"
Send-Email -desde $desde -subject $asunto -buzon $Buzon1 -inc $inc
Your issues look to be:
Object defined outside the function it's being used in:
$Outlook = New-Object -ComObject Outlook.Application
Unquoted strings in variables:
$desde = client2#mail.com
$buzon = inbox1#mail.com
$inc = 000000001
Mix and match of single and double quotes
I'd recommend reading about_quoting_rules to understand the difference as this is quite crucial when using variables within strings.
the function param $inc is defined has data but is not used for anything?
Recommend to remove this if it's not used.
Not specifically an issue, but I've changed the here string (#" "#) to a normal string with line breaks (`r`n`)
After resolving the issues and tidying the code:
Function Send-Email {
param (
[String]$desde,
[String]$subject,
[String]$buzon,
[String]$inc
)
$firma = 'Textplan'
$cuerpo = "Dear colleague,`r`nbla bla bla`r`nThank you."
$Outlook = New-Object -ComObject Outlook.Application
$mail = $Outlook.CreateItem(0)
$mail.subject = 'Closed Ticket ' + $subject
$mail.sender = $buzon
$mail.body = "$cuerpo $firma"
$mail.To = $desde
$mail.Send()
Start-Sleep 3
}
$desde = 'client2#mail.com'
$subject = 'Automat request'
$buzon = 'inbox1#mail.com'
$inc = '000000001'
Send-Email -desde $desde -subject $subject -buzon $buzon -inc $inc
I don't have Outlook to test the code, but from checking it over with the Outlook.Application documentation it now seems to be valid.
I finally used this lines and work well:
$mail.SentOnBehalfOfName = "inbox1d#mail.com"
$mail.SendUsingAccount = $Outlook.Session.Accounts | where {$_.DisplayName -eq $FromMail}
Function Send-Email {
param (
[String]$desde,
[String]$subject,
[String]$buzon,
[String]$inc
)
$firma = 'Textplan'
$cuerpo = "Dear colleague,`r`nbla bla bla`r`nThank you."
$Outlook = New-Object -ComObject Outlook.Application
$mail = $Outlook.CreateItem(0)
$mail.subject = 'Closed Ticket ' + $subject
$mail.sender = $buzon
$mail.body = "$cuerpo $firma"
$mail.SentOnBehalfOfName = "inbox1d#mail.com"
$mail.SendUsingAccount = $Outlook.Session.Accounts | where {$_.DisplayName -eq $FromMail}
$mail.Send()
Start-Sleep 3
}
$desde = 'client2#mail.com'
$subject = 'Automat request'
$buzon = 'inbox1#mail.com'
$inc = '000000001'
Send-Email -desde $desde -subject $subject -buzon $buzon -inc $inc

Add Attachment and Cc Parameter to smtp Email function

My powershell script currently handles sending an email from the command line to a list of users. I would like to add an attachment to the email and also a list of Cc so all emails don't come through the "To" email parameter. Here is my current function.
function SendEmail
{
$smtpServer = "smtp.server"
$smtpFrom = "PROD <email#gmail.com>"
$smtpTo = "me#gmail.com"
$messageSubject = "Weekly List "+$day
$messagebody = "Hi User, Please find attached document. Thank you."
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($smtpFrom,$smtpTo,$messageSubject,$messagebody)
}
My attempt was to add a variable called $attachment = "\PathtoFile"
and add $attachment into the Send function, but that didn't work...
Use Send-MailMessage with the Attachments and Cc parameter:
Send-MailMessage -Attachments "C:\path\to\attachment.ext" -Cc "myboss#gmail.com"
You can also specify an encoding (you mentioned special characters):
Send-MailMessage -Encoding UTF8
In general, I would recommend splatting the parameters, so it ends up looking like this:
$MyAttachments = ".\a\relative\path.ext","C:\another\file.ext"
$MailParams = #{
SmtpServer = "smtp.server"
From = "PROD <email#gmail.com>"
To = "me#gmail.com"
Subject = "Weekly List "+$day
Body = "Hi User, Please find attached document. Thank you."
Attachments = $MyAttachments
Encoding = [System.Text.Encoding]::UTF8
}
Send-MailMessage #MailParams

How to encode the subject of the mail in Powershell?

I am trying to send mail using Powershell with Japanese character on the subject and body of the mail. The mail is successfully sent and the Japanese character in the body is fine. But it is not working in subject. I got =?iso-2022-jp?Q?=1B=24B=25F=259=25H=1B=28B?= instead of テスト.
Can someone help me on this?
code:
$eSubject = "テスト This is subject"
$eBody = "テスト テスト テスト This is body"
$Encode = [Text.Encoding]::GetEncoding("csISO2022JP");
$s64 = [Convert]::ToBase64String($Encode.GetBytes($eSubject), [Base64FormattingOptions]::None)
$Mail = New-Object Net.Mail.MailMessage("From#mail.com","To#mail.com")
$Mail.Subject = [String]::Format("=?{0}?B?{1}?=", $Encode.HeaderName, $s64)
$View = [Net.Mail.AlternateView]::CreateAlternateViewFromString($eBody, $Encode, [Net.Mime.MediaTypeNames]::Text.Plain)
$View.TransferEncoding = [Net.Mime.TransferEncoding]::SevenBit
$Mail.AlternateViews.Add($View)
$SmtpClient = NEW-OBJECT Net.Mail.SmtpClient("localhost","25")
$SmtpClient.Send($Mail)
When using the default CmdLet Send-MailMessage it works fine for me:
$EmailParams = #{
To = 'Destination#domain.com'
From = 'From#domain.com'
Subject = 'テスト This is the subject'
Body = 'テスト This is the body'
SMTPServer = 'YourSMTPServer'
Encoding = 'UTF8'
}
Send-MailMessage #EmailParams
I don't know how. But it is working now, I just remove the encoding for subject.
code:
$eSubject = "テスト This is subject"
$eBody = "テスト テスト テスト This is body"
$Encode = [Text.Encoding]::GetEncoding("csISO2022JP");
$Mail = New-Object Net.Mail.MailMessage("From#mail.com","To#mail.com")
$Mail.Subject = $eSubject
$View = [Net.Mail.AlternateView]::CreateAlternateViewFromString($eBody, $Encode, [Net.Mime.MediaTypeNames]::Text.Plain)
$View.TransferEncoding = [Net.Mime.TransferEncoding]::SevenBit
$Mail.AlternateViews.Add($View)
$SmtpClient = NEW-OBJECT Net.Mail.SmtpClient("localhost","25")
$SmtpClient.Send($Mail)