Its been a while but here is a quick tip for embedding inline images in SMTP emails with powershell. Outlook will see these the attachments and embed them inline with the message.
create your message:
$smtpServer = "SMTP.YourServer.com" $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpServer)
Add your contact and subject to your message:
$msg.From = "<a href="mailto:From@YourServer.com">From@YourServer.com</a>" $msg.ReplyTo = "<a href="mailto:From@YourServer.com">From@YourServer.com</a>" $msg.To.Add("<a href="mailto:To@YourServer.com">To@YourServer.com</a>") $msg.subject = "This is an email with inline images"
Makre sure the email is HTML enabled:
$msg.IsBodyHtml = $True
Add your Content to the body (note this can also be read in from an html file via get-content):
$body = @" <html> <body> <img src="cid:image1.jpg"> </body> </html> "@
Attach the image to your email: (note setting the images as inline and media type will make sure that outlook attaches the images as embedded and the email will not show as having attachments)
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList "C:\image1.jpg" $attachment.ContentDisposition.Inline = $True $attachment.ContentDisposition.DispositionType = "Inline" $attachment.ContentType.MediaType = "image/jpg" $attachment.ContentId = 'image1.jpg' $msg.Attachments.Add($attachment)
Or for multiple images or attachments:
$path = C:\images $files= Get-ChildItem $path Foreach($file in $files) { $attachment = New-Object System.Net.Mail.Attachment –ArgumentList $Path\$file.ToString() #convert file-system object type to string $attachment.ContentDisposition.Inline = $True $attachment.ContentDisposition.DispositionType = "Inline" $attachment.ContentType.MediaType = "image/jpg" $attachment.ContentId = $file.ToString() $msg.Attachments.Add($attachment) }
Just make sure that in your html email to referece each file with <image src=”cid:filename.extension”>
<html> <body> <img src="cid:image1.jpg"> <img src="cid:image2.jpg"> <img src="cid:image3.jpg"> </body> </html>
When done adding attachments send your message adn clean up:
$smtp.Send($msg) $attachment.Dispose(); $msg.Dispose();
If you have inline image attachments of varying file formats you can also set the inline media type dynamically. In your attachment lool take the file type as a string and pipe it into the media type:
$fileType = $file.Substring(($file.IndexOf('.'))+1) #get image file extension ... $attachment.MediaType = "image/$fileType" #set mediaType based on $file extension
Great break down of the script. I have been using it to tweak my own attempts at this. I’m only new to scripting and was hoping for a little help with a glitch or oversight on my part in using your script.
When running at this point of code i get error:
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList $Path\$file.ToString()
Error message:
New-Object : A positional parameter cannot be found that accepts argument ”.
At C:\Users\Owner\Desktop\SendEmail.ps1:53 char:15
+ $attachment = New-Object System.Net.Mail.Attachment –ArgumentList $Path\$file(“” …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-Object], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
Can you help me understand what the positional parameter it is expecting I presume it’s meant to take input from the image name but doesn’t seem to be grabbing it?
what version of powershell are you running?
This looks promising, but with PowerShell v3 I get so many errors. Here are the major ones:
(I’ll try switching to PowerShell v2 if I can’t figure out how to adjust this for PS3/4.)
Thanks for sharing!
Exception setting “From”: “Cannot convert value “mailto:helpdesk@somecompany.com” to
type “System.Net.Mail.MailAddress”. Error: “The specified string is not in the form required for an e-mail address.”"
At D:\ad\PasswordReminder\email_embedded_files.ps1:12 char:1
+ $msg.From = “mailto:helpdesk@somecompany.com …
Method invocation failed because [System.IO.FileInfo] does not contain a method named ‘IndexOf’.
At D:\ad\PasswordReminder\email_embedded_files.ps1:50 char:2
+ $fileType = $file.Substring(($file.IndexOf(‘.’))+1) # <– Get the file extensio …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
New-Object : Exception calling ".ctor" with "1" argument(s): "Could not find file
'D:\AD\PasswordReminder\images\footer.gif.ToString'."
At D:\ad\PasswordReminder\email_embedded_files.ps1:51 char:16
+ $attachment = New-Object System.Net.Mail.Attachment –ArgumentList $Path\$file.T …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [New-Object], MethodInvocationException
+ FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
The property 'Inline' cannot be found on this object. Verify that the property exists and can be set.
At D:\ad\PasswordReminder\email_embedded_files.ps1:52 char:2
+ $attachment.ContentDisposition.Inline = $True
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
The property 'DispositionType' cannot be found on this object. Verify that the property exists and can be set.
At D:\ad\PasswordReminder\email_embedded_files.ps1:53 char:2
+ $attachment.ContentDisposition.DispositionType = "Inline"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
The property 'MediaType' cannot be found on this object. Verify that the property exists and can be set.
At D:\ad\PasswordReminder\email_embedded_files.ps1:54 char:2
+ $attachment.ContentType.MediaType = "image/$fileType"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
The property 'ContentId' cannot be found on this object. Verify that the property exists and can be set.
At D:\ad\PasswordReminder\email_embedded_files.ps1:55 char:2
+ $attachment.ContentId = $file.ToString()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
Exception calling "Add" with "1" argument(s): "Value cannot be null.
Parameter name: item"
At D:\ad\PasswordReminder\email_embedded_files.ps1:56 char:2
+ $msg.Attachments.Add($attachment)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentNullException
looks like you have issues with the code. should be an email address not mailto:user@domain.comm but just user@domain.com also looks like you have some other issues as well.
can you maybe post the code you are using? I can take a look I’m running this in powershell 3 no problem.
I got the same error as Brem. Additionally, on the line that says “$attachment = New-Object System.Net.Mail.Attachment –ArgumentList $Path\$file.ToString() #convert file-system object type to string” there is an error after ToString() that says “An expression was expected after ‘(‘.”
What is the code you are using in the $msg.from and $msg.to? Also are you attaching multiple images or just one?
Hi,
I modified your script a bit to work on PS v4. My Problem is that the Picture is not Embedded it just shows up like a document icon, i have to double click the icon to see the picture.
Can you help me ?
$smtpServer = “172.0.0.1″
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = “2@2.com”
$msg.To.Add(“2@2.com”)
$msg.subject = “This is an email with inline images”
$msg.IsBodyHtml = $True
$body = @”
“@
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList “C:\1.jpg”
$attachment.ContentDisposition.Inline = $True
$attachment.ContentDisposition.DispositionType = “Inline”
$attachment.ContentType.MediaType = “image/jpg”
$attachment.ContentId = ’1.jpg’
$msg.Attachments.Add($attachment)
$smtp.Send($msg)
$attachment.Dispose();
$msg.Dispose();
Hi Dane,
Great script and very well explained.
I just tried to use it but the image does not go inline, it comes as an attachment. I would like you to help to see what am I doing wrong.
#create your message:
$smtpServer = "webmail.telecom.pt"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.Credentials = New-Object System.Net.NetworkCredential("user", "pwd");
# Add your contact and subject to your message:
$msg.From = "user1@server.com"
$msg.To.Add("user2@server.com")
$msg.subject = "This is an email with inline images"
# Makre sure the email is HTML enabled:
$msg.IsBodyHtml = $True
# Attach the image to your email:
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList "C:\Logo.jpg"
$attachment.ContentDisposition.Inline = $True
$attachment.ContentDisposition.DispositionType = "Inline"
$attachment.ContentType.MediaType = "image/jpg"
$attachment.ContentId = 'Logo.jpg'
$msg.Attachments.Add($attachment)
# Add your Content to the body (note this can also be read in from an html file via get-content):
$body = @"
"@
# When done adding attachments send your message adn clean up:
$smtp.Send($msg)
$attachment.Dispose();
$msg.Dispose();
Regards,
Elio Fernandes
in your html file are you referrencing the image as:
image src=”cid:Logo.jpg”
I am using this
$body = @"
"@
Yes I am
are you using exchange/outlook or some other email? and can you post a snippit of the the html with the images? you strip out the actual html tags and wordpress wont strip your code that way
Dane, I am using Outlook. About the snippit, I am not understanding what you are trying to say. Can you send me an e-mail with the code I sent and put inside the changes you are refering to.
Regards,
Elio Fernandes
the real culprit is my lack of typing. HTML should be img src=… not image src=
I corrected the typo in the original post above for future reference
Thank you very much for very well explained code.
I would like to point out that there is a typo, where you define $Body, it should be $msg.Body, cause as it is now, it will just send a blank email.
Again, thanks!
Regards,
Mateja
Problem Solved.
I added the picture with division Tag
div id=’BottomRight’
img src=’cid:Attachment’/
/div
Regards,
Dan.