Having rules run on old mails noved to inbox

odoll

New Member
Outlook version
Outlook 2016 64 bit
Email Account
POP3
OL16 64b on W10 64b

Hello,

I have a little powershell script which moves items to a PST files standard inbox.
How can I achieve that those mails get picked up by the rule engine as if they would have had arrived as incoming (e.g. same as the ones which get downloaded from a pop3 mbx)?

Thanks a lot in advance.
 

odoll

New Member
Outlook version
Outlook 2016 64 bit
Email Account
POP3
Thx a lot Diane,

> The only way would be to use run rules now command.

I already came across hints like this, however I understood it the way as if you'd have to read all defined rules first and execute them on the item one after another?

> Otherwise rules only run on mail downloaded from the service, as the mail passes through the mapi subsystem

My script is passing the mails through the MAPI as well, so I thought there might be a hook to tell the engine "Hi, here's a new mail, please process your rules on it."

In a nutshell the script looks like this:
Code:
# generate Outlook objects
Add-Type -Assembly "Microsoft.Office.Interop.Outlook"
$OL = New-Object -ComObject Outlook.Application
$NS = $OL.GetNS("MAPI")

# get the correct mailboxes
$MbxS = $NS.Folders | Where { $_.FolderPath -match "\\<account name>" }
$SrcFldr = $MbxS.Folders | Where { $_.Folderpath -match "Posteingang" }
$DstFldr = $NS.GetDefaultFolder(6)

# move all items from Source to Destination folder
$EMails = $SrcFldr.Items
ForEach ($EMail in $EMails){
  $EMail.Move($DstFldr) | Out-Null
  <start_rule_engine_on_mail_here>
}
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
you'd have to read all defined rules first and execute them on the item one after another?
Yeah, more or less, but it should be fast... unless you have a ton of rules. I would move the messages then run the rules on the inbox. It would be faster than running them on each message. I have a VBA version here - Run Rules Now using a Macro

if the rules are simple and you don't have many, you might be able file the messages as you move. (I have not tried converting a move macro to powershell.) The big thing is if you have a lot of rules with a lot of different types of conditions... the script gets heavy and slow as it checks each condition. In this case, running rules would be better. Rules such as 'move mail from sender display name to folder named for sender' would be fairly simple to convert. Keywords in the subject to folders named for keywords would be easy too. Converting a mix of these kinds of rules is where it slows as the scripts checks for matches.

My script is passing the mails through the MAPI as well
Outlook scripts always use mapi - you aren't passing it through the part that downloads messages.
 

odoll

New Member
Outlook version
Outlook 2016 64 bit
Email Account
POP3
Diane, thanks a lot for your hints!

Though I'm currently stuck with the following odd behaviour of the above little script, which however is a bit off-topic here.
Nevertheless I'm gonna mention it:

While working on a bigger number of mail items I noticed, that the ForEach loop doesn't process all items in the source folder, but only ~ half of them (to be precise, if the number N of items it odd, it processes (N+1)/2 items in one go, but leaves the remaining item in the folder.)

So the loop has some "binary based logarithmic attitude! ;-)

As an example: lets assume, if $EMails.count is 7, the ForEach ($EMail in $EMails){...} only works on 4 of the 7 items, leaving 3 in the folder.
During the next round it only moves 2 of the 3, finally the last one.

E.g. starting with 16 items it's 16 -> 8 -> 4 -> 2 -> 1 -> 0.

Am I doing something wrong here?
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
During the next round it only moves 2 of the 3, finally the last one.
If you are moving or deleting, you need to count then step backwards through the messages - when you do this going forward, after moving an item, item #2 now becomes item #1, #3 is #2 and outlook moves on to #2.

For i = 1 to items.count step -1
' move or delete
next i
 

odoll

New Member
Outlook version
Outlook 2016 64 bit
Email Account
POP3
Thx Dianne, I was under the impression when defining

$EMails = $SrcFldr.Items

in Powershell $EMails would be a "static" list of all all objects in $SrcFldr.Items, but obviously it's dynamically changing while moving the items.

BTW: as using piping the objects into a ForEach-Object () loop as in

Code:
$SrcFldr.Items | ForEach-Object {
  $_.Move($DstFldr) | Out-Null
}
has the same "problem" I decided to do it in a while loop

Code:
while($SrcFldr.Items.Count -gt 0) {
   $SrcFldr.Items[1].Move($DstFldr) | Out-Null
}
 

Diane Poremsky

Senior Member
Outlook version
Outlook 2016 32 bit
Email Account
Office 365 Exchange
Since it doesn't create an actual list of message ids or other identifiable characteristics, it can't keep track of the messages and just goes by count (which remains static) - but the actual count keeps changing in outlook. Recounting after each move and is slower in VBA, that's why it's recommended to work backwards.
 

odoll

New Member
Outlook version
Outlook 2016 64 bit
Email Account
POP3
OK, thx for the recommendation. Replaced "1" by the count then, so it should always move off from the end, even a new item gets in.

Code:
while($SrcFldr.Items.Count -gt 0) {
   $SrcFldr.Items[$SrcFldr.Items.Count].Move($DstFldr) | Out-Null
}
 
Top