2

I am trying to send attachments in Send-MailMessage without saving to disk first by using the answer I found in this thread, which points to this URL.

It says to use:

$attachment = [System.Net.Mail.Attachment]::CreateAttachmentFromString($attachmenttext,"test.txt") 

But when I try to do that with Send-MailMessage instead of the complicated way it shows, I get this error:

Send-MailMessage -From "email@email.com" -To "email@email.com" -Subject "Subject" -Body $body -SmtpServer "smtp.server.local" -Port 25 -BodyAsHtml -Attachments $attachment

Send-MailMessage : Could not find file 'C:\Windows\system32\System.Net.Mail.Attachment'.
At line:3 char:1
+ Send-MailMessage -From "email@email.com" -To "email@e ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Send-MailMessage], FileNotFoundException
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.SendMailMessage

Is there anyway to continue using Send-MailMessage with this method? Or is there a different method that will allow me to attach files without first saving to disk while still using send-mailmessage?

alexander7567
  • 665
  • 13
  • 35

1 Answers1

2

Let me first go over whats wrong. [System.Net.Mail.Attachment]::CreateAttachmentFromString outputs type System.Net.Mail.Attachment while send-mailmessage -attachments is looking for an array of strings string[]. Thats why the example will fail.

I have written a simple function so you can use the attachment you have posted in the example which creates a MailMessage and looks for attachments of type [System.Net.Mail.Attachment].

Function Try-SendMail([string[]]$To, [string]$From, [string]$SmtpServer, [int]$Port = 25, [pscredential]$SmtpCredential, [string]$Subject, [string]$Body, [System.Net.Mail.Attachment[]]$attachment, [switch]$IsBodyHTML){
    [System.Net.Mail.MailMessage]$Mail = new-object System.Net.Mail.MailMessage
    $To | %{$Mail.To.Add($_)}
    $Mail.From = $From
    $Mail.IsBodyHtml = $IsBodyHTML
    $Mail.Body = $Body
    $Mail.Subject = $Subject
    $Attachment | %{$mail.Attachments.Add($_)}
    [System.Net.Mail.SmtpClient]$SMTP = new-object System.Net.Mail.SmtpClient
    $SMTP.Host = $SmtpServer
    $SMTP.Port = $Port
    If($SmtpCredential){
        $NetCredential = New-Object System.Net.NetworkCredential
        $NetCredential.UserName = $SmtpCredential.GetNetworkCredential().UserName
        $NetCredential.Password = $SmtpCredential.GetNetworkCredential().Password
        $SMTP.Credentials = $NetCredential
    }
    try{
        $SMTP.Send($Mail)
    }catch{
        $_ | select *
    }
}

you can use it like

$To = @("Person1@Test.com","Person2@Test.com")
$From = "MainGuy@PErson.com"
$Server = "SMTPSERVER.NET"
$Port = 587
$Attachments = @(
    $([System.Net.Mail.Attachment]::CreateAttachmentFromString("HELLO", "Test.txt")),
    $([System.Net.Mail.Attachment]::CreateAttachmentFromString("HELLO2", "Test2.txt"))
)
$SmtpCredential = Get-Credential

Try-SendMail -to $To -From $From -Subject "Hello" -Body "World" -Attachment $Attachments -SmtpServer $Server -port $Port -SmtpCredential $SmtpCredential

*Edited forgot to make [System.Net.Mail.Attachment] to [System.Net.Mail.Attachment[]] in the function parameters

ArcSet
  • 6,518
  • 1
  • 20
  • 34
  • Thank you - I was hoping for an one-liner I could remember, but I can live with that. I can copy and paste the function and use the rest like I normally would. Shame this is not built in to the send-mailmessage! – alexander7567 Oct 29 '18 at 22:03
  • Well its official - I used this method. I was torn between your method or [this](https://stackoverflow.com/questions/6955860/filename-of-downloaded-file-in-dataapplication-octet-stream). I loved the other method because it was more customization and easy to remember, but it doesn't work in Outlook 2016. If I could give you multiple upvotes I would :) Thanks for your time! – alexander7567 Oct 30 '18 at 15:45
  • 1
    @alexander7567 most email client will not allow that method you linked – ArcSet Oct 30 '18 at 15:52