Outlook COM Mark email as read

Ask your PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
User avatar
localpct
Posts: 353
Last visit: Tue Oct 19, 2021 8:39 am

Outlook COM Mark email as read

Post by localpct »

Hello, I'm having issues marking emails as read when ran as a PS1 file. Everything works expect marking them as read.
  1. #FindOldReports and Archive Them
  2. $today = get-date -format dMMyy
  3. Get-ChildItem '\\servername\TaskSchedulerScripts' *.csv -Recurse -Exclude "this.csv", "that.CSV" |
  4. ForEach-Object {Move-Item $_.FullName -Destination "\\servername\TaskSchedulerScripts\Archive\$($Today)_$($_.Name)"}
  5.  
  6. #Open Outlook and find emails from today
  7. $ol = New-Object -ComObject Outlook.Application
  8. $ns = $ol.GetNamespace('mapi')
  9. $mb = $ns.Stores['some@email.com'].GetRootFolder()
  10. $inbox = $mb.Folders['Reports']
  11. $DailyReports = $inbox.Items | Where-Object {$_.ReceivedTime -match (get-date -Format d)}
  12.  
  13. #Define Attachments Path
  14. $filepath = '\\servername\TaskSchedulerScripts'
  15.  
  16. #Save Attachments
  17. $DailyReports.attachments | ForEach-Object {$_.saveasfile((Join-Path $filepath $_.FileName))}
  18.  
  19. #Mark items as read
  20. $inbox.items | ForEach {$_.UnRead = $false}
  21. sleep -Seconds 15
  22. #Quit Outlook and Release COM object
  23. $ol.Quit()
  24. [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Ol)
  25. Get-Process -Name OUTLOOK | Stop-Process -Force

jvierra
Posts: 14951
Last visit: Sun Oct 17, 2021 11:52 am
Answers: 14
Has voted: 3 times
Been upvoted: 11 times

Re: Outlook COM Mark email as read

Post by jvierra »

You should probably ask specific questions about external subsystems in teh developers forum for the subsystem.

Specifically, I see that you are not setting the mail item as beinf "Read". You must set that directly through the COM proxy.

Here is a link to the MailItem Unread property: https://docs.microsoft.com/en-us/office ... tem.unread

User avatar
localpct
Posts: 353
Last visit: Tue Oct 19, 2021 8:39 am

Re: Outlook COM Mark email as read

Post by localpct »

Hey Jim, I forgot to include that it does work if I run it one line at a time

It’s only when it’s all executed at the same time, in a PS1 or in ISE
Last edited by localpct on Fri Aug 20, 2021 5:55 am, edited 1 time in total.

jvierra
Posts: 14951
Last visit: Sun Oct 17, 2021 11:52 am
Answers: 14
Has voted: 3 times
Been upvoted: 11 times

Re: Outlook COM Mark email as read

Post by jvierra »

Ok I see you mistake. I couldn't see the code because it was colorized incorrectly.

When you filter and then iterate a collection and change the filter component then the filter skips items in the collection because you are changing a dynamic collection.

Get an array of Mail IDs and then enumerate that and you won't be fighting a changing dynamic collection.

User avatar
localpct
Posts: 353
Last visit: Tue Oct 19, 2021 8:39 am

Re: Outlook COM Mark email as read

Post by localpct »

Hey I edited my second post after you posted but if I run it one line at a time, it works

If I run in PS1 or select all then run in ISE, it fails to mark emails as read

User avatar
localpct
Posts: 353
Last visit: Tue Oct 19, 2021 8:39 am

Re: Outlook COM Mark email as read

Post by localpct »

$inbox.Items | ForEach-Object {$_.UnRead = $false}

User avatar
localpct
Posts: 353
Last visit: Tue Oct 19, 2021 8:39 am

Re: Outlook COM Mark email as read

Post by localpct »

Discovered I needed to add in a start-sleep for some reason our exchange couldn't handle it lol

jvierra
Posts: 14951
Last visit: Sun Oct 17, 2021 11:52 am
Answers: 14
Has voted: 3 times
Been upvoted: 11 times

Re: Outlook COM Mark email as read

Post by jvierra »

Unfortunately that is not possible as the updates occur differntly than you think. IN enumerted "Finds" the set of objects is changed betwen each iteration which causes the index to constantly be off. Enumerating bottom to top works if the search is not sorted. If sorted then retrive the mail ids and alter the emails using the index array which will not change due to alterations. What happens on Exchenge has nothing to do with this. If Exchange can't process the incremental changes an exception will be thrown.

User avatar
localpct
Posts: 353
Last visit: Tue Oct 19, 2021 8:39 am

Re: Outlook COM Mark email as read

Post by localpct »

I dont understand all of what you're saying. Sorry.

User avatar
localpct
Posts: 353
Last visit: Tue Oct 19, 2021 8:39 am

Re: Outlook COM Mark email as read

Post by localpct »

AFter re reading and thinking about this. I do understand what you're saying so I moved the script to something like this
  1. $Ol = New-Object -comobject Outlook.Application
  2. $namespace = $Ol.GetNameSpace("MAPI")
  3. $Folder = $namespace.Folders.Item('some@email.com').Folders.Item('REPORTS')
  4. $Folder.Items | ForEach-Object {
  5.     $files =  $_.attachments
  6.     foreach($f in $files)
  7.     {
  8.         $f.saveasfile((Join-Path 'C:\Data' $f.filename ))
  9.     }
  10. }
  11.  
  12. #Quit Outlook and Release COM object
  13. $ol.Quit()
  14. [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Ol)
  15. Get-Process -Name OUTLOOK | Stop-Process -ErrorAction SilentlyContinue -Force
I do honestly feel something is wrong with the object for a few reasons, there aren't many success stories on the web and If I attempt to delete/read the file within the loop or as a whole ($Folder.Items | ForEach-Object { $_.Delete()} )it wont process the files and I'll see an item removed from the folder

Locked