1

I am trying to reply to emails using PowerShell, and the code below works successfully, but it doesn't show the original message I'm responding to:

Add-Type -assembly "Microsoft.Office.Interop.Outlook"
Add-type -assembly "System.Runtime.Interopservices"

try {
$outlook = [Runtime.Interopservices.Marshal]::GetActiveObject('Outlook.Application')
$outlookWasAlreadyRunning = $true
}
catch {
    try {
    $Outlook = New-Object -comobject Outlook.Application
    $outlookWasAlreadyRunning = $false
    }
    catch {
        write-host "You must exit Outlook first."
        exit
    }
}

$namespace = $Outlook.GetNameSpace("MAPI")

$inbox = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)

$Folder = $inbox.Folders | where-object { $_.name -eq "Folder name" }

$mails = $Folder.Items | Where-Object {$_.Subject -like "This is the subject"}

foreach($mail in $mails) {
    $reply = $mail.ReplyAll()
    $reply.body = "TEST BODY"
    $reply.save()
    
    $inspector = $reply.GetInspector
    $inspector.display()
}

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45

2 Answers2

2

First of all, there is no need to iterate over all items in the folder checking the subject property:

$mails = $Folder.Items | Where-Object {$_.Subject -like "This is the subject"}

Use the Find/FindNext or Restrict methods of the Items class to get only items that correspond to your conditions. Read more about these methods in the following articles:

As for the message body, in the code it is replaced with a plain text:

$reply.body = "TEST BODY"

To preserve the original message body you need to add your content right after the opening <body> tag and use the HTMLBody property instead. The Body property contains a plain text.

Also there is no need to get an inspector if you need to display the item after. Use the Display method of the MailItem class directly.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
1

The reason your reply is not showing is because you're creating your reply with $reply = $mail.ReplyAll() and then replacing the body of that email in this line $reply.body = "TEST BODY"

If you wish to retain the existing email, I'd use the Insert method on the body string like so:

foreach($mail in $mails) {
    $reply = $mail.ReplyAll()
    $text = "TEST BODY`r`n"

    # Insert our desired text at position 0 of the existing string content
    $reply.body = $reply.body.Insert(0, $text)
    $reply.save()
    
    $inspector = $reply.GetInspector
    $inspector.display()
}

If you're working with HTML-based emails, you'll probably want to update the HTMLBody field instead, so replace

$reply.body = $reply.body.Insert(0, $text)

with this

$reply.HTMLBody = $reply.HTMLBody.Insert(0, $text)
NiMux
  • 826
  • 7
  • 16