title: Powershell Send-MailMessage does not dispose attachment after failing to send
body: <p>I'm having a bit of trouble with my automated Powershell Hyper-V Backup script. The script functions perfectly, but my issue is that when I try to send an email with the log file as attachment, it does not unlock the file after it FAILS to send it. (It's not possible for me to check how it acts, when it send the mail successfully, but to be honest, it should also dispose it, even when it fails to send.)</p>
  
  <p>I have searched throughout the web and all I could find, is that either:</p>
  
  <ol>
  <li>Send-MailMessage automatically dispose attachments, after sending
  the mail.</li>
  <li>Use the method from Powershell v1 with new-object
  system.net.mail.mailmessage and new-object
  system.net.mail.attachment.</li>
  </ol>
  
  <p>Heres the part of my code (I have shortened it down to only the essentials of the code needed):</p>
  
  <pre><code>[String]$ComputerName = Get-Content Env:ComputerName
  [String]$LogFile = "Hyper-V Backup Logs\$ComputerName.Hyper-V Backup." + (Get-Date).Day + "-" +(Get-Date).Month + "-" +(Get-Date).Year + "-" +(Get-Date).Hour + "." +(Get-Date).Minute + "." +(Get-Date).Second + ".log"
  
  "# $(Get-Date) :: Attempting to send log file to 'Support@example.dk'..." | Out-File $LogFile -Append
  Try
  {
      $EmailTo = "Support@example.dk"
      $EmailFrom = "Service@example.dk"
      $EmailServer = "server.example.dk"
      $EmailSubject = "An error occurred during Hyper-V Backup on $ComputerName!"
      $EmailBody = "Hello,
  
      An error occured during Hyper-V Backup on $ComputerName.
  
      I have attached the log file, $LogFile, to this mail.
  
      Kind Regards,&lt;br&gt;&lt;/p&gt;
      Hyper-V Backup.
      "
  
      Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $EmailSubject -Body $EmailBody -Attachments $LogFile -SmtpServer $EmailServer
      "# $(Get-Date) :: Successfully send log file to 'Support@example.dk" | Out-File $LogFile -Append
  
  }
  Catch
  {
      "# $(Get-Date) :: Failed to send log file to 'Support@example.dk" | Out-File $LogFile -Append
      "                      :: Error Command: Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $EmailSubject -Body $EmailBody -Attachments $LogFile -SmtpServer $EmailServer" | Out-File $LogFile -Append
      "                      :: Error Message: $($_.Exception.Message)" | Out-File $LogFile -Append
  }
  </code></pre>
  
  <p>Which throws the following error:</p>
  
  <pre><code>Out-File : The process cannot access the file 'C:\Hyper-V Backup\Hyper-V Backup
  Logs\example.Hyper-V Backup.22-8-2013-13.48.16.log' because it is being used by
  another process.
  At C:\Hyper-V Backup\Hyper-V Backup.ps1:310 char:163
  + ... port@example.dk" | Out-File $LogFile -Append
  +                    ~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo          : OpenError: (:) [Out-File], IOException
      + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
  </code></pre>
  
  <p>So my question is, how can I make Send-MailMessage dispose the attachment, after failing to send the email, so my script can continue to write to the log file?</p>
  
  <p>PS. the script above works, without throwing any errors and without locking the file, when the mail is send <em>successfully</em>.</p>
  
  <p>Kind regards,</p>
  
  <p>Thomas Schmidt</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I went with the old Powershell v1 way instead:</p>
  
  <pre><code>Try
  {
      $SMTPServer = "exchange.example.dk"
      $SMTP = new-object Net.Mail.SmtpClient($SMTPServer)
  
      $EmailAttachment = new-object Net.Mail.Attachment($Logfile)
      $EmailMessage = new-object Net.Mail.MailMessage
  
      $EmailMessage.Attachments.Add($EmailAttachment)
      $EmailMessage.From = "service@example.dk"
      $EmailMessage.To.Add("spport@example.dk")
      $EmailMessage.Subject = "Notification from email server"
      $EmailMessage.Body = "Hello,
  An error occurred during A/S Hyper-V Backup on $ComputerName.
  
  I have attached the log file, $LogFile, to this mail.
  
  Kind Regards,
  Hyper-V Backup.
  "
      $SMTP.Send($EmailMessage)
      $EmailAttachment.Dispose()
      Write-Host "# $(Get-Date) :: Successfully send log file to 'Support@example.dk" -foregroundcolor green; "# $(Get-Date) :: Successfully send log file to 'Support@example.dk" | Out-File $LogFile -Append
  }
  Catch
  {
      $EmailAttachment.Dispose()
      Write-Host "# $(Get-Date) :: Failed to send log file to 'Support@example.dk" -foregroundcolor red; "# $(Get-Date) :: Failed to send log file to 'Support@example.dk" | Out-File $LogFile -Append
      "                      :: Error Command: SMTP.Send(EmailMessage)" | Out-File $LogFile -Append
      "                      :: Error Message: $($_.Exception.Message)" | Out-File $LogFile -Append
  }
  </code></pre>
  
  <p>But if anyone can provide an answer to the above, I would love to use that solution instead!</p>
  
  <p>Kind regards,</p>
  
  <p>Thomas Schmidt</p>